ADD: function declaration syntaxic sugar.
parent
227a9b7a25
commit
03cc9b58e2
|
@ -3,10 +3,12 @@ EXPR ::=
|
||||||
LITERAL
|
LITERAL
|
||||||
| FUNCALL
|
| FUNCALL
|
||||||
| VARDECL
|
| VARDECL
|
||||||
|
| FUNDECL
|
||||||
| LAMBDA
|
| LAMBDA
|
||||||
LAMBDA ::= opar rarrow opar PARAMS cpar BODY cpar
|
LAMBDA ::= opar rarrow opar PARAMS cpar BODY cpar
|
||||||
PARAMS ::= ident*
|
PARAMS ::= ident*
|
||||||
BODY ::= expr*
|
BODY ::= expr*
|
||||||
VARDECL ::= opar decl ident EXPR cpar
|
VARDECL ::= opar decl ident EXPR cpar
|
||||||
|
FUNDECL ::= opar decl opar ident PARAMS cpar EXPR cpar
|
||||||
FUNCALL ::= opar ident EXPR* cpar
|
FUNCALL ::= opar ident EXPR* cpar
|
||||||
LITERAL ::= int | ident
|
LITERAL ::= int | ident
|
||||||
|
|
|
@ -99,6 +99,13 @@ namespace jk
|
||||||
|
|
||||||
std::shared_ptr<Node> Parser::parse_expr()
|
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)
|
if (type_is(NODE_OPAR)
|
||||||
&& type_is(NODE_IDENT, 1))
|
&& type_is(NODE_IDENT, 1))
|
||||||
{
|
{
|
||||||
|
@ -132,6 +139,31 @@ namespace jk
|
||||||
return root;
|
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()
|
std::shared_ptr<Node> Parser::parse_lambda()
|
||||||
{
|
{
|
||||||
auto root = std::make_shared<Node>(NODE_LAMBDA, "", loc());
|
auto root = std::make_shared<Node>(NODE_LAMBDA, "", loc());
|
||||||
|
|
|
@ -32,6 +32,7 @@ namespace jk
|
||||||
std::shared_ptr<Node> parse_prog();
|
std::shared_ptr<Node> parse_prog();
|
||||||
std::shared_ptr<Node> parse_expr();
|
std::shared_ptr<Node> parse_expr();
|
||||||
std::shared_ptr<Node> parse_vardecl();
|
std::shared_ptr<Node> parse_vardecl();
|
||||||
|
std::shared_ptr<Node> parse_fundecl();
|
||||||
std::shared_ptr<Node> parse_lambda();
|
std::shared_ptr<Node> parse_lambda();
|
||||||
std::shared_ptr<Node> parse_params();
|
std::shared_ptr<Node> parse_params();
|
||||||
std::shared_ptr<Node> parse_body();
|
std::shared_ptr<Node> parse_body();
|
||||||
|
|
|
@ -61,3 +61,13 @@ TEST_CASE_METHOD(ParserTest, "Parser_lambda")
|
||||||
")))",
|
")))",
|
||||||
" (-> (x) x)");
|
" (-> (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)) ");
|
||||||
|
}
|
||||||
|
|
Reference in New Issue