diff options
Diffstat (limited to 'src/sexpr')
-rw-r--r-- | src/sexpr/bind.cpp | 29 | ||||
-rw-r--r-- | src/sexpr/fwd.hpp | 4 | ||||
-rw-r--r-- | src/sexpr/lexer.hpp | 10 | ||||
-rw-r--r-- | src/sexpr/lexer_test.cpp | 32 | ||||
-rw-r--r-- | src/sexpr/parser.hpp | 2 | ||||
-rw-r--r-- | src/sexpr/parser_test.cpp | 25 | ||||
-rw-r--r-- | src/sexpr/union_test.cpp (renamed from src/sexpr/union.cpp) | 2 | ||||
-rw-r--r-- | src/sexpr/variant.cpp | 40 | ||||
-rw-r--r-- | src/sexpr/variant.hpp | 49 | ||||
-rw-r--r-- | src/sexpr/variant.tcc | 3 | ||||
-rw-r--r-- | src/sexpr/variant_test.cpp | 32 | ||||
-rw-r--r-- | src/sexpr/void.cpp | 29 |
12 files changed, 82 insertions, 175 deletions
diff --git a/src/sexpr/bind.cpp b/src/sexpr/bind.cpp deleted file mode 100644 index d8d0caa..0000000 --- a/src/sexpr/bind.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "bind.hpp" -// bind.cpp - Just include the header file. -// -// Copyright © 2012 Ben Longbons <b.r.longbons@gmail.com> -// -// This file is part of The Mana World (Athena server) -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. - -#include "../poison.hpp" - - -namespace tmwa -{ -namespace sexpr -{ -} // namespace sexpr -} // namespace tmwa diff --git a/src/sexpr/fwd.hpp b/src/sexpr/fwd.hpp index 580b322..b86d9fb 100644 --- a/src/sexpr/fwd.hpp +++ b/src/sexpr/fwd.hpp @@ -20,6 +20,10 @@ #include "../sanity.hpp" +#include "../strings/fwd.hpp" // rank 1 +#include "../io/fwd.hpp" // rank 4 +// sexpr/fwd.hpp is rank 5 + namespace tmwa { diff --git a/src/sexpr/lexer.hpp b/src/sexpr/lexer.hpp index 63be72d..9b198a0 100644 --- a/src/sexpr/lexer.hpp +++ b/src/sexpr/lexer.hpp @@ -22,7 +22,6 @@ #include <vector> -#include "../strings/fwd.hpp" #include "../strings/astring.hpp" #include "../strings/zstring.hpp" @@ -59,10 +58,13 @@ namespace sexpr Lexer(ZString filename) : _in(filename), _current(TOK_EOF), _span(), _depth() { adv(); } - // for unit tests - Lexer(ZString fake, io::FD fd) - : _in(fake, fd), _current(TOK_EOF), _span(), _depth() + Lexer(io::read_file_from_string, ZString name, XString str) + : _in(io::from_string, name, str), _current(TOK_EOF), _span(), _depth() { adv(); } + Lexer(io::read_file_from_string, ZString name, LString str) + : _in(io::from_string, name, str), _current(TOK_EOF), _span(), _depth() + { adv(); } + Lexeme peek() { return _current; } void adv() { _current = _adv(); } ZString val_string() { return _string; } diff --git a/src/sexpr/lexer_test.cpp b/src/sexpr/lexer_test.cpp index fdb47f2..d84312e 100644 --- a/src/sexpr/lexer_test.cpp +++ b/src/sexpr/lexer_test.cpp @@ -29,22 +29,6 @@ namespace tmwa { -static -io::FD string_pipe(ZString sz) -{ - io::FD rfd, wfd; - if (-1 == io::FD::pipe(rfd, wfd)) - return io::FD(); - if (sz.size() != wfd.write(sz.c_str(), sz.size())) - { - rfd.close(); - wfd.close(); - return io::FD(); - } - wfd.close(); - return rfd; -} - TEST(sexpr, escape) { EXPECT_EQ(sexpr::escape('\0'), "\\x00"_s); @@ -73,24 +57,24 @@ TEST(sexpr, escape) TEST(sexpr, lexer) { io::LineSpan span; - sexpr::Lexer lexer("<lexer-test1>"_s, string_pipe(" foo( ) 123\"\" \n"_s)); + sexpr::Lexer lexer(io::from_string, "<lexer-test1>"_s, " foo( ) 123\"\" \n"_s); EXPECT_EQ(lexer.peek(), sexpr::TOK_TOKEN); EXPECT_EQ(lexer.val_string(), "foo"_s); - EXPECT_EQ(lexer.span().message_str("error"_s, "test"_s), + EXPECT_EQ(lexer.span().error_str("test"_s), "<lexer-test1>:1:2: error: test\n" " foo( ) 123\"\" \n" " ^~~\n"_s ); lexer.adv(); EXPECT_EQ(lexer.peek(), sexpr::TOK_OPEN); - EXPECT_EQ(lexer.span().message_str("error"_s, "test"_s), + EXPECT_EQ(lexer.span().error_str("test"_s), "<lexer-test1>:1:5: error: test\n" " foo( ) 123\"\" \n" " ^\n"_s ); lexer.adv(); EXPECT_EQ(lexer.peek(), sexpr::TOK_CLOSE); - EXPECT_EQ(lexer.span().message_str("error"_s, "test"_s), + EXPECT_EQ(lexer.span().error_str("test"_s), "<lexer-test1>:1:7: error: test\n" " foo( ) 123\"\" \n" " ^\n"_s @@ -98,7 +82,7 @@ TEST(sexpr, lexer) lexer.adv(); EXPECT_EQ(lexer.peek(), sexpr::TOK_TOKEN); EXPECT_EQ(lexer.val_string(), "123"_s); - EXPECT_EQ(lexer.span().message_str("error"_s, "test"_s), + EXPECT_EQ(lexer.span().error_str("test"_s), "<lexer-test1>:1:9: error: test\n" " foo( ) 123\"\" \n" " ^~~\n"_s @@ -106,7 +90,7 @@ TEST(sexpr, lexer) lexer.adv(); EXPECT_EQ(lexer.peek(), sexpr::TOK_STRING); EXPECT_EQ(lexer.val_string(), ""_s); - EXPECT_EQ(lexer.span().message_str("error"_s, "test"_s), + EXPECT_EQ(lexer.span().error_str("test"_s), "<lexer-test1>:1:12: error: test\n" " foo( ) 123\"\" \n" " ^~\n"_s @@ -120,7 +104,7 @@ TEST(sexpr, lexbad) QuietFd q; { io::LineSpan span; - sexpr::Lexer lexer("<lexer-bad>"_s, string_pipe("(\n"_s)); + sexpr::Lexer lexer(io::from_string, "<lexer-bad>"_s, "(\n"_s); EXPECT_EQ(lexer.peek(), sexpr::TOK_OPEN); lexer.adv(); EXPECT_EQ(lexer.peek(), sexpr::TOK_ERROR); @@ -135,7 +119,7 @@ TEST(sexpr, lexbad) }) { io::LineSpan span; - sexpr::Lexer lexer("<lexer-bad>"_s, string_pipe(bad)); + sexpr::Lexer lexer(io::from_string, "<lexer-bad>"_s, bad); EXPECT_EQ(lexer.peek(), sexpr::TOK_ERROR); } } diff --git a/src/sexpr/parser.hpp b/src/sexpr/parser.hpp index feed636..cfe8212 100644 --- a/src/sexpr/parser.hpp +++ b/src/sexpr/parser.hpp @@ -22,8 +22,6 @@ #include <cstdlib> -#include "../strings/fwd.hpp" - #include "../io/line.hpp" #include "lexer.hpp" diff --git a/src/sexpr/parser_test.cpp b/src/sexpr/parser_test.cpp index 846d425..bbaf5eb 100644 --- a/src/sexpr/parser_test.cpp +++ b/src/sexpr/parser_test.cpp @@ -20,32 +20,18 @@ #include <gtest/gtest.h> +#include "../tests/fdhack.hpp" + #include "../poison.hpp" namespace tmwa { -static -io::FD string_pipe(ZString sz) -{ - io::FD rfd, wfd; - if (-1 == io::FD::pipe(rfd, wfd)) - return io::FD(); - if (sz.size() != wfd.write(sz.c_str(), sz.size())) - { - rfd.close(); - wfd.close(); - return io::FD(); - } - wfd.close(); - return rfd; -} - TEST(sexpr, parser) { sexpr::SExpr s; io::LineSpan span; - sexpr::Lexer lexer("<parser-test1>"_s, string_pipe(" foo( ) 123\"\" \n"_s)); + sexpr::Lexer lexer(io::from_string, "<parser-test1>"_s, " foo( ) 123\"\" \n"_s); EXPECT_TRUE(sexpr::parse(lexer, s)); EXPECT_EQ(s._type, sexpr::TOKEN); @@ -70,7 +56,7 @@ TEST(sexpr, parser) TEST(sexpr, parselist) { sexpr::SExpr s; - sexpr::Lexer lexer("<parser-test1>"_s, string_pipe("(foo)(bar)\n"_s)); + sexpr::Lexer lexer(io::from_string, "<parser-test1>"_s, "(foo)(bar)\n"_s); EXPECT_TRUE(sexpr::parse(lexer, s)); EXPECT_EQ(s._type, sexpr::LIST); @@ -90,6 +76,7 @@ TEST(sexpr, parselist) TEST(sexpr, parsebad) { + QuietFd q; for (LString bad : { "(\n"_s, ")\n"_s, @@ -105,7 +92,7 @@ TEST(sexpr, parsebad) { sexpr::SExpr s; io::LineSpan span; - sexpr::Lexer lexer("<parse-bad>"_s, string_pipe(bad)); + sexpr::Lexer lexer(io::from_string, "<parse-bad>"_s, bad); EXPECT_FALSE(sexpr::parse(lexer, s)); EXPECT_EQ(lexer.peek(), sexpr::TOK_ERROR); } diff --git a/src/sexpr/union.cpp b/src/sexpr/union_test.cpp index 6f65012..ca60b49 100644 --- a/src/sexpr/union.cpp +++ b/src/sexpr/union_test.cpp @@ -1,5 +1,5 @@ #include "union.hpp" -// union.cpp - Just include the header file and try to instantiate. +// union_test.cpp - Just include the header file and try to instantiate. // // Copyright © 2012 Ben Longbons <b.r.longbons@gmail.com> // diff --git a/src/sexpr/variant.cpp b/src/sexpr/variant.cpp deleted file mode 100644 index b1f500a..0000000 --- a/src/sexpr/variant.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include "variant.hpp" -// variant.cpp - Just include the header file. -// -// Copyright © 2012 Ben Longbons <b.r.longbons@gmail.com> -// -// This file is part of The Mana World (Athena server) -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. - -#include "../poison.hpp" - - -namespace tmwa -{ -namespace sexpr -{ -namespace -{ - struct Foo - { - Foo() {} - ~Foo() {} - Foo(Foo&&) {} - Foo& operator = (Foo&&) { return *this; } - }; -} // anonymous namespace - static Variant<int, Foo> v; -} // namespace sexpr -} // namespace tmwa diff --git a/src/sexpr/variant.hpp b/src/sexpr/variant.hpp index fbf9345..0eccc5a 100644 --- a/src/sexpr/variant.hpp +++ b/src/sexpr/variant.hpp @@ -33,19 +33,42 @@ namespace tmwa { namespace sexpr { -#define JOIN(a, b) a##b - -#define WITH_VAR(ty, var, expr) \ - for (bool JOIN(var, _guard) = true; JOIN(var, _guard); ) \ - for (ty var = expr; JOIN(var, _guard); JOIN(var, _guard) = false) -#define MATCH(expr) \ - WITH_VAR(auto&&, _match_var, expr) \ - switch (tmwa::sexpr::VariantFriend::get_state(_match_var)) -#define TYPED_CASE(ty, var, look) \ - break; \ - case tmwa::sexpr::VariantFriend::get_state_for<look, decltype(_match_var)>(): \ - WITH_VAR(ty, var, tmwa::sexpr::VariantFriend::unchecked_get<look>(_match_var)) -#define CASE(ty, var) TYPED_CASE(ty, var, std::remove_const<std::remove_reference<ty>::type>::type) +#define MATCH_BEGIN(expr) \ + { \ + auto&& _match_var = (expr); \ + switch (tmwa::sexpr::VariantFriend::get_state(_match_var)) \ + { \ + { \ + { \ + /* }}}} */ +#define MATCH_END() \ + /* {{{{ */ \ + } \ + } \ + } \ + (void) _match_var; \ + } + +#define MATCH_CASE(ty, v) \ + /* {{{{ */ \ + } \ + break; \ + } \ + { \ + using _match_case_type = std::remove_const<std::remove_reference<ty>::type>::type; \ + case tmwa::sexpr::VariantFriend::get_state_for<_match_case_type, decltype(_match_var)>(): \ + { \ + ty v = tmwa::sexpr::VariantFriend::unchecked_get<_match_case_type>(_match_var); + /* }}}} */ +#define MATCH_DEFAULT() \ + /* {{{{ */ \ + } \ + break; \ + } \ + { \ + default: \ + { \ + /* }}}} */ template<class... T> class Variant diff --git a/src/sexpr/variant.tcc b/src/sexpr/variant.tcc index 1f7df03..c370fa4 100644 --- a/src/sexpr/variant.tcc +++ b/src/sexpr/variant.tcc @@ -120,6 +120,9 @@ namespace sexpr } catch (...) { + // TODO switch from requiring nothrow default construct, to + // instead require nothrow moves, and offer the strong exception + // guarantee (which is actually easier that the basic one) #if GCC != 407 // apparent compiler bug, not reduced // 4.7.2 from wheezy is bad // 4.7.3 from jessie is good diff --git a/src/sexpr/variant_test.cpp b/src/sexpr/variant_test.cpp index bc378aa..c671264 100644 --- a/src/sexpr/variant_test.cpp +++ b/src/sexpr/variant_test.cpp @@ -77,42 +77,46 @@ TEST(variant, match) : sexpr::Variant<Foo, Bar>(Foo(1)) {} }; + Sub v1; - MATCH (v1) + MATCH_BEGIN (v1) { - // This is not a public API, it's just for testing. - default: - FAIL(); - - CASE(Foo, f) + MATCH_DEFAULT () + { + FAIL(); + } + MATCH_CASE (Foo, f) { (void)f; SUCCEED(); } - CASE(Bar, b) + MATCH_CASE (Bar, b) { (void)b; FAIL(); } } + MATCH_END (); + v1.emplace<Bar>(2); - MATCH (v1) + MATCH_BEGIN (v1) { - // This is not a public API, it's just for testing. - default: - FAIL(); - - CASE(Foo, f) + MATCH_DEFAULT () + { + FAIL(); + } + MATCH_CASE (Foo, f) { (void)f; FAIL(); } - CASE(Bar, b) + MATCH_CASE (Bar, b) { (void)b; SUCCEED(); } } + MATCH_END (); } TEST(variant, copymove1) diff --git a/src/sexpr/void.cpp b/src/sexpr/void.cpp deleted file mode 100644 index 9f0eeb5..0000000 --- a/src/sexpr/void.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "void.hpp" -// void.cpp - Just include the header file. -// -// Copyright © 2012 Ben Longbons <b.r.longbons@gmail.com> -// -// This file is part of The Mana World (Athena server) -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. - -#include "../poison.hpp" - - -namespace tmwa -{ -namespace sexpr -{ -} // namespace sexpr -} // namespace tmwa |