diff --git a/doc/grammar.bnf b/doc/grammar.bnf index b34640f..aec8570 100644 --- a/doc/grammar.bnf +++ b/doc/grammar.bnf @@ -4,7 +4,10 @@ EXPR ::= | ident | CALL | LAMBDA +| FUNDECL CALL ::= opar EXPR EXPR* cpar LAMBDA ::= opar rarrow opar PARAMS cpar BODY cpar PARAMS ::= ident* BODY ::= EXPR* +FUNDECL ::= +| opar ident opar ident PARAMS cpar BODY cpar diff --git a/examples/fundecl.fk b/examples/fundecl.fk new file mode 100644 index 0000000..4def0c8 --- /dev/null +++ b/examples/fundecl.fk @@ -0,0 +1,3 @@ +($ (f x y) (* x y)) + +(assert= 42 (f 6 7)) \ No newline at end of file diff --git a/src/Parser.cpp b/src/Parser.cpp index d5dde6f..b21230e 100644 --- a/src/Parser.cpp +++ b/src/Parser.cpp @@ -59,7 +59,12 @@ namespace fk return consume(); } - if (type_all({NODE_OPAR, NODE_RARROW})) + if (type_all({NODE_OPAR, NODE_IDENT, NODE_OPAR, NODE_IDENT}) + && m_tokens[m_cursor + 1]->repr() == "$") + { + return parse_fundecl(); + } + else if (type_all({NODE_OPAR, NODE_RARROW})) { return parse_lambda(); } @@ -134,6 +139,31 @@ namespace fk return node; } + std::shared_ptr Parser::parse_fundecl() + { + consume(NODE_OPAR); + auto dollar = consume(NODE_IDENT); + + consume(NODE_OPAR); + auto ident = consume(NODE_IDENT); + auto params = parse_params(); + consume(NODE_CPAR); + + auto body = parse_body(); + consume(NODE_CPAR); + + auto res = make_node(NODE_CALL); + res->add_child(dollar); + res->add_child(ident); + + auto lambda = make_node(NODE_LAMBDA); + lambda->add_child(params); + lambda->add_child(body); + res->add_child(lambda); + + return res; + } + std::shared_ptr Parser::make_node(NodeType type) { return std::make_shared(type, "", loc()); diff --git a/src/Parser.hpp b/src/Parser.hpp index 815243f..cd7df9d 100644 --- a/src/Parser.hpp +++ b/src/Parser.hpp @@ -26,6 +26,7 @@ namespace fk std::shared_ptr parse_lambda(); std::shared_ptr parse_params(); std::shared_ptr parse_body(); + std::shared_ptr parse_fundecl(); std::shared_ptr make_node(NodeType type); Loc loc() const; diff --git a/tests/Parser.cpp b/tests/Parser.cpp index f2fa06e..f762b42 100644 --- a/tests/Parser.cpp +++ b/tests/Parser.cpp @@ -47,3 +47,10 @@ TEST_CASE_METHOD(ParserTest, "Parser_lambda") test_parse("MODULE(LAMBDA(PARAMS(IDENT[x],IDENT[y]),BODY(INT[7])))", " (-> (x y) 7) "); } + +TEST_CASE_METHOD(ParserTest, "Parser_fundecl") +{ + test_parse("MODULE(CALL(IDENT[$],IDENT[f]," + "LAMBDA(PARAMS(IDENT[x]),BODY(INT[7]))))", + " ($ (f x) 7) "); +}