diff --git a/doc/grammar.bnf b/doc/grammar.bnf index 7c9ee9c..acbdd86 100644 --- a/doc/grammar.bnf +++ b/doc/grammar.bnf @@ -24,6 +24,9 @@ LITERAL ::= | ident | int | CALL +| NS CALL ::= ident opar ARGS cpar ARGS ::= (EXPR (comma EXPR)*)? + +NS ::= ident (dot ident)+ diff --git a/lib/Compiler.cpp b/lib/Compiler.cpp index d279818..b051982 100644 --- a/lib/Compiler.cpp +++ b/lib/Compiler.cpp @@ -105,7 +105,7 @@ namespace wg if (node->child(0)->repr() == "import") { std::string pkg_name = node->child(1)->repr(); - std::cout << "-> " << pkg_name << std::endl; + std::cout << "import pkg " << pkg_name << std::endl; } return nullptr; diff --git a/lib/Lexer.cpp b/lib/Lexer.cpp index 1860876..f68832c 100644 --- a/lib/Lexer.cpp +++ b/lib/Lexer.cpp @@ -10,6 +10,7 @@ namespace wg add_keyword("return", NODE_RETURN); add_keyword("extern", NODE_EXTERN); + add_text(".", NODE_DOT); add_text("{", NODE_OBRACE); add_text("}", NODE_CBRACE); add_text(",", NODE_COMMA); diff --git a/lib/Node.hpp b/lib/Node.hpp index f0d33bf..ed55dc4 100644 --- a/lib/Node.hpp +++ b/lib/Node.hpp @@ -17,7 +17,7 @@ G(NODE_ARGS), G(NODE_TYPE), G(NODE_RETURN), \ G(NODE_FUN), G(NODE_PARAMS), G(NODE_BLOCK), \ G(NODE_OBRACE), G(NODE_CBRACE), G(NODE_FUNDECL), \ - G(NODE_EXTERN), G(NODE_RET) + G(NODE_EXTERN), G(NODE_RET), G(NODE_DOT), G(NODE_NS) namespace wg { diff --git a/lib/Parser.cpp b/lib/Parser.cpp index 77b9d0e..c782e19 100644 --- a/lib/Parser.cpp +++ b/lib/Parser.cpp @@ -280,6 +280,12 @@ namespace wg return parse_call(); } + if (type_is(NODE_IDENT) + && type_is(NODE_DOT, 1)) + { + return parse_ns(); + } + if (type_is(NODE_INT) || type_is(NODE_IDENT)) { @@ -337,4 +343,18 @@ namespace wg return node; } + + std::shared_ptr Parser::parse_ns() + { + auto node = make_node(NODE_NS); + node->add_child(consume(NODE_IDENT)); + + while (type_is(NODE_DOT)) + { + consume(); + node->add_child(consume(NODE_IDENT)); + } + + return node; + } } diff --git a/lib/Parser.hpp b/lib/Parser.hpp index f7c8da2..b286826 100644 --- a/lib/Parser.hpp +++ b/lib/Parser.hpp @@ -45,6 +45,8 @@ namespace wg std::shared_ptr parse_call(); std::shared_ptr parse_args(); + std::shared_ptr parse_ns(); + }; } diff --git a/tests/Lexer.cpp b/tests/Lexer.cpp index 8ec4ef5..8c80d60 100644 --- a/tests/Lexer.cpp +++ b/tests/Lexer.cpp @@ -68,3 +68,11 @@ TEST_CASE_METHOD(LexerTest, "Lexer_fun_call") test_next(lex, "EXTERN"); test_end(lex); } + +TEST_CASE_METHOD(LexerTest, "Lexer_pkg_namespace") +{ + wg::Lexer lex; + lex.scan(" . "); + test_next(lex, "DOT"); + test_end(lex); +} diff --git a/tests/Parser.cpp b/tests/Parser.cpp index 6a29d64..b3deea4 100644 --- a/tests/Parser.cpp +++ b/tests/Parser.cpp @@ -90,3 +90,9 @@ TEST_CASE_METHOD(ParserTest, "Parser_fundecl") test_parse("PROG(RETURN(ADD(CALL(IDENT[a],ARGS),INT[1])))", " return a() + 1; "); } + +TEST_CASE_METHOD(ParserTest, "Parser_namespace") +{ + test_parse("PROG(NS(IDENT[a],IDENT[b],IDENT[c],IDENT[d]))", + " a.b.c.d; "); +}