From 03cc9b58e229691b995ba54295abdc5d1e34b5bf Mon Sep 17 00:00:00 2001 From: bog Date: Sun, 10 Sep 2023 11:10:30 +0200 Subject: [PATCH] ADD: function declaration syntaxic sugar. --- doc/grammar.bnf | 2 ++ lib/Parser.cpp | 32 ++++++++++++++++++++++++++++++++ lib/Parser.hpp | 1 + tests/Parser.cpp | 10 ++++++++++ 4 files changed, 45 insertions(+) diff --git a/doc/grammar.bnf b/doc/grammar.bnf index f3a9f41..41ec2cc 100644 --- a/doc/grammar.bnf +++ b/doc/grammar.bnf @@ -3,10 +3,12 @@ EXPR ::= LITERAL | FUNCALL | VARDECL +| FUNDECL | LAMBDA LAMBDA ::= opar rarrow opar PARAMS cpar BODY cpar PARAMS ::= ident* BODY ::= expr* VARDECL ::= opar decl ident EXPR cpar +FUNDECL ::= opar decl opar ident PARAMS cpar EXPR cpar FUNCALL ::= opar ident EXPR* cpar LITERAL ::= int | ident diff --git a/lib/Parser.cpp b/lib/Parser.cpp index 72b3116..c2662a0 100644 --- a/lib/Parser.cpp +++ b/lib/Parser.cpp @@ -99,6 +99,13 @@ namespace jk std::shared_ptr Parser::parse_expr() { + if (type_is(NODE_OPAR) + && type_is(NODE_DECL, 1) + && type_is(NODE_OPAR, 2)) + { + return parse_fundecl(); + } + if (type_is(NODE_OPAR) && type_is(NODE_IDENT, 1)) { @@ -132,6 +139,31 @@ namespace jk return root; } + std::shared_ptr Parser::parse_fundecl() + { + consume(NODE_OPAR); + consume(NODE_DECL); + + consume(NODE_OPAR); + auto ident = consume(NODE_IDENT); + auto params = parse_params(); + + consume(NODE_CPAR); + + auto body = parse_body(); + consume(NODE_CPAR); + + auto vardecl = std::make_shared(NODE_VARDECL, "", ident->loc()); + vardecl->add_child(ident); + + auto lambda = std::make_shared(NODE_LAMBDA, "", ident->loc()); + lambda->add_child(params); + lambda->add_child(body); + vardecl->add_child(lambda); + + return vardecl; + } + std::shared_ptr Parser::parse_lambda() { auto root = std::make_shared(NODE_LAMBDA, "", loc()); diff --git a/lib/Parser.hpp b/lib/Parser.hpp index 9830478..e6282fb 100644 --- a/lib/Parser.hpp +++ b/lib/Parser.hpp @@ -32,6 +32,7 @@ namespace jk std::shared_ptr parse_prog(); std::shared_ptr parse_expr(); std::shared_ptr parse_vardecl(); + std::shared_ptr parse_fundecl(); std::shared_ptr parse_lambda(); std::shared_ptr parse_params(); std::shared_ptr parse_body(); diff --git a/tests/Parser.cpp b/tests/Parser.cpp index 2160df6..451e179 100644 --- a/tests/Parser.cpp +++ b/tests/Parser.cpp @@ -61,3 +61,13 @@ TEST_CASE_METHOD(ParserTest, "Parser_lambda") ")))", " (-> (x) x)"); } + +TEST_CASE_METHOD(ParserTest, "Parser_fundecl") +{ + test_parser("PROG(VARDECL(IDENT[f],LAMBDA(" + "PARAMS(IDENT[x],IDENT[y]),BODY(" + "FUNCALL(IDENT[add],IDENT[y],IDENT[x])" + ")" + ")))", + " ($ (f x y) (add y x)) "); +}