✨ syntaxic sugar for function declaration.
parent
603dc6f53a
commit
06b379c99c
|
@ -8,6 +8,9 @@ EXPR ::=
|
||||||
| BLOCK
|
| BLOCK
|
||||||
| IF
|
| IF
|
||||||
| return EXPR
|
| return EXPR
|
||||||
|
| FUN_DECL
|
||||||
|
FUN_DECL ::=
|
||||||
|
| fun ident opar PARAMS cpar EXPR* end
|
||||||
IF ::= if EXPR BLOCK (else (BLOCK | IF))?
|
IF ::= if EXPR BLOCK (else (BLOCK | IF))?
|
||||||
BLOCK ::= begin EXPR* end
|
BLOCK ::= begin EXPR* end
|
||||||
ASSIGN ::= ident assign EXPR
|
ASSIGN ::= ident assign EXPR
|
||||||
|
|
|
@ -80,3 +80,8 @@ assert k() eq 39
|
||||||
assert k() eq 40
|
assert k() eq 40
|
||||||
assert k() eq 41
|
assert k() eq 41
|
||||||
|
|
||||||
|
fun l(x)
|
||||||
|
3 * x
|
||||||
|
end
|
||||||
|
|
||||||
|
assert l(7) eq 21
|
||||||
|
|
|
@ -19,6 +19,7 @@ struct node* parser_try(struct parser* self,
|
||||||
struct node* parser_try_parse(struct parser* self);
|
struct node* parser_try_parse(struct parser* self);
|
||||||
struct node* parser_try_root(struct parser* self);
|
struct node* parser_try_root(struct parser* self);
|
||||||
struct node* parser_try_expr(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_block(struct parser* self);
|
||||||
struct node* parser_try_inner_block(struct parser* self);
|
struct node* parser_try_inner_block(struct parser* self);
|
||||||
struct node* parser_try_if(struct parser* self);
|
struct node* parser_try_if(struct parser* self);
|
||||||
|
|
|
@ -137,9 +137,73 @@ struct node* parser_try_expr(struct parser* self)
|
||||||
return SK_TRY(parser_try_if);
|
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);
|
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)
|
struct node* parser_try_block(struct parser* self)
|
||||||
{
|
{
|
||||||
assert(self);
|
assert(self);
|
||||||
|
|
|
@ -140,6 +140,11 @@ static void test_parser_function()
|
||||||
test_parser("ROOT(FUN(PARAMS,BLOCK))",
|
test_parser("ROOT(FUN(PARAMS,BLOCK))",
|
||||||
"fun () end");
|
"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))",
|
test_parser("ROOT(CALL(IDENT[hello],ARGS))",
|
||||||
"hello()");
|
"hello()");
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue