ADD: function declaration syntaxic sugar.

main
bog 2023-09-10 11:10:30 +02:00
parent 227a9b7a25
commit 03cc9b58e2
4 changed files with 45 additions and 0 deletions

View File

@ -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

View File

@ -99,6 +99,13 @@ namespace jk
std::shared_ptr<Node> 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<Node> 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>(NODE_VARDECL, "", ident->loc());
vardecl->add_child(ident);
auto lambda = std::make_shared<Node>(NODE_LAMBDA, "", ident->loc());
lambda->add_child(params);
lambda->add_child(body);
vardecl->add_child(lambda);
return vardecl;
}
std::shared_ptr<Node> Parser::parse_lambda()
{
auto root = std::make_shared<Node>(NODE_LAMBDA, "", loc());

View File

@ -32,6 +32,7 @@ namespace jk
std::shared_ptr<Node> parse_prog();
std::shared_ptr<Node> parse_expr();
std::shared_ptr<Node> parse_vardecl();
std::shared_ptr<Node> parse_fundecl();
std::shared_ptr<Node> parse_lambda();
std::shared_ptr<Node> parse_params();
std::shared_ptr<Node> parse_body();

View File

@ -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)) ");
}