feat: implement functions

This commit is contained in:
samsonium
2026-10-15 02:23:43 +03:00
parent cc3087296f
commit 2c206822ca
15 changed files with 391 additions and 36 deletions
+101 -1
View File
@@ -514,6 +514,79 @@ fzl_node_t *parse_statement(fzl_parser_t *parser)
if (type->type == FZL_TOKTYPE_TYPE)
consume(parser);
if (type->type == FZL_TOKTYPE_TYPE &&
next(parser)->type == FZL_TOKTYPE_LPAREN)
{
fzl_token_t *tok = consume(parser);
if (tok->type != FZL_TOKTYPE_NAME)
{
snprintf(plast_err, sizeof(plast_err),
"expected name in function definition at %ld:%ld", tok->ln,
tok->cn);
return NULL;
}
fzl_token_t *lparen = consume(parser);
if (lparen->type != FZL_TOKTYPE_LPAREN)
{
snprintf(plast_err, sizeof(plast_err),
"expected '(' after name at %ld:%ld", lparen->ln, lparen->cn);
return NULL;
}
size_t remainder = 1;
size_t count = 0;
fzl_node_t **args = malloc(remainder * sizeof(fzl_node_t *));
while (peek(parser) && !is(parser, FZL_TOKTYPE_RPAREN))
{
fzl_node_t *arg = parse_statement(parser);
if (!arg)
return NULL;
if (remainder <= count)
{
remainder *= 2;
args = realloc(args, remainder * sizeof(fzl_node_t *));
}
args[count++] = arg;
if (is(parser, FZL_TOKTYPE_COMMA))
consume(parser);
}
fzl_token_t *rparen = consume(parser);
if (rparen->type != FZL_TOKTYPE_RPAREN)
{
snprintf(plast_err, sizeof(plast_err),
"expected ')' after argument list at %ld:%ld", rparen->ln,
rparen->cn);
return NULL;
}
if (!is(parser, FZL_TOKTYPE_LBRACE))
{
fzl_token_t *tok = peek(parser);
snprintf(plast_err, sizeof(plast_err), "expected '{' at %ld:%ld",
tok->ln, tok->cn);
return NULL;
}
fzl_node_t *body = parse_statement(parser);
if (!body)
return NULL;
fzl_node_t *node = fzl_mknode(FZL_NODETYPE_FUNCTION, tok);
node->fn.args = args;
node->fn.args_count = count;
node->fn.body = body;
node->fn.name = tok;
node->fn.type = type;
return node;
}
if (type->type == FZL_TOKTYPE_TYPE || next(parser)->type == FZL_TOKTYPE_EQ)
{
@@ -574,6 +647,25 @@ fzl_node_t *parse_statement(fzl_parser_t *parser)
return left;
}
if (is(parser, FZL_TOKTYPE_RETURN))
{
fzl_token_t *ret = consume(parser);
fzl_node_t *node = fzl_mknode(FZL_NODETYPE_RETURN, ret);
if (is(parser, FZL_TOKTYPE_DOT))
{
consume(parser);
return node;
}
fzl_node_t *retval = parse_expression(parser);
if (!retval)
return NULL;
node->ret.value = retval;
return node;
}
if (is(parser, FZL_TOKTYPE_IF))
{
fzl_token_t *if_tok = consume(parser);
@@ -637,7 +729,7 @@ fzl_node_t *parse_statement(fzl_parser_t *parser)
if (remainder <= count)
{
remainder *= 2;
stmts = realloc(stmts, remainder);
stmts = realloc(stmts, remainder * sizeof(fzl_node_t *));
}
stmts[count++] = node;
@@ -758,6 +850,14 @@ void fzl_freeast(fzl_node_t *root)
if (root->unary_op.operand)
fzl_freeast(root->unary_op.operand);
}
else if (root->type == FZL_NODETYPE_FUNCTION)
{
if (root->fn.args_count)
for (size_t i = 0; i < root->fn.args_count; i++)
fzl_freenode(root->fn.args[i]);
free(root->fn.args);
fzl_freenode(root->fn.body);
}
fzl_freenode(root);
root = root->next;