syntaxic sugar for function declaration.

main
bog 2024-04-06 09:17:08 +02:00
parent 603dc6f53a
commit 06b379c99c
5 changed files with 78 additions and 0 deletions

View File

@ -8,6 +8,9 @@ EXPR ::=
| BLOCK
| IF
| return EXPR
| FUN_DECL
FUN_DECL ::=
| fun ident opar PARAMS cpar EXPR* end
IF ::= if EXPR BLOCK (else (BLOCK | IF))?
BLOCK ::= begin EXPR* end
ASSIGN ::= ident assign EXPR

View File

@ -80,3 +80,8 @@ assert k() eq 39
assert k() eq 40
assert k() eq 41
fun l(x)
3 * x
end
assert l(7) eq 21

View File

@ -19,6 +19,7 @@ struct node* parser_try(struct parser* self,
struct node* parser_try_parse(struct parser* self);
struct node* parser_try_root(struct parser* self);
struct node* parser_try_expr(struct parser* self);
struct node* parser_try_fun_decl(struct parser* self);
struct node* parser_try_block(struct parser* self);
struct node* parser_try_inner_block(struct parser* self);
struct node* parser_try_if(struct parser* self);

View File

@ -137,9 +137,73 @@ struct node* parser_try_expr(struct parser* self)
return SK_TRY(parser_try_if);
}
if (lexer_next_is(&self->lexer, TOKEN_FUN)
&& lexer_next_nth_is(&self->lexer, TOKEN_IDENT, 1))
{
return SK_TRY(parser_try_fun_decl);
}
return SK_TRY(parser_try_or);
}
struct node* parser_try_fun_decl(struct parser* self)
{
if (!lexer_next_is(&self->lexer, TOKEN_FUN))
{
return NULL;
}
struct node* fun = malloc(sizeof(struct node));
node_init(fun, NODE_FUN, lexer_try_new_next(&self->lexer));
if (!lexer_next_is(&self->lexer, TOKEN_IDENT))
{
node_free(fun);
free(fun);
return NULL;
}
struct node* ident = malloc(sizeof(struct node));
node_init(ident, NODE_IDENT,
lexer_try_new_next(&self->lexer));
if (!lexer_next_is(&self->lexer, TOKEN_OPAR))
{
node_free(fun); free(fun);
node_free(ident); free(ident);
return NULL;
}
lexer_consume_next(&self->lexer);
struct node* params = SK_TRY(parser_try_params);
node_push_new_child(fun, params);
if (!lexer_next_is(&self->lexer, TOKEN_CPAR))
{
node_free(fun); free(fun);
node_free(ident); free(ident);
return NULL;
}
lexer_consume_next(&self->lexer);
struct node* body = SK_TRY(parser_try_inner_block);
node_push_new_child(fun, body);
if (!lexer_next_is(&self->lexer, TOKEN_END))
{
node_free(fun); free(fun);
node_free(ident); free(ident);
return NULL;
}
struct node* node = malloc(sizeof(struct node));
node_init(node, NODE_CONST_DECL, lexer_try_new_next(&self->lexer));
node_push_new_child(node, ident);
node_push_new_child(node, fun);
return node;
}
struct node* parser_try_block(struct parser* self)
{
assert(self);

View File

@ -140,6 +140,11 @@ static void test_parser_function()
test_parser("ROOT(FUN(PARAMS,BLOCK))",
"fun () end");
test_parser("ROOT(CONST_DECL(IDENT[hello]"
",FUN(PARAMS(IDENT[x],IDENT[y]),"
"BLOCK(INT[0],INT[1]))))",
"fun hello (x, y) 0 1 end");
test_parser("ROOT(CALL(IDENT[hello],ARGS))",
"hello()");