#include #include #include #include // Functions parsing fzl_node_t *pa_function(fzl_parser_t *parser) { if (!parser) return NULL; fzl_token_t *fn = consume(parser); if (!fn || fn->type != FZL_TOKTYPE_FUNCTION) { snprintf(plast_err, sizeof(plast_err), "'%s': expected keyword 'fn' at %ld:%ld", last_known_tok->filename, last_known_tok->ln, last_known_tok->cn); return NULL; } fzl_token_t *name = consume(parser); if (!name || name->type != FZL_TOKTYPE_NAME) { snprintf(plast_err, sizeof(plast_err), "'%s': expected function name at %ld:%ld", last_known_tok->filename, last_known_tok->ln, last_known_tok->cn); return NULL; } fzl_token_t *lpar = consume(parser); if (!lpar || lpar->type != FZL_TOKTYPE_LPAREN) { snprintf(plast_err, sizeof(plast_err), "'%s': expected '(' at %ld:%ld", last_known_tok->filename, last_known_tok->ln, last_known_tok->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 = pa_expression(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 *rpar = consume(parser); if (!rpar || rpar->type != FZL_TOKTYPE_RPAREN) { free(args); snprintf(plast_err, sizeof(plast_err), "'%s': expected ')' after argument list at %ld:%ld", last_known_tok->filename, last_known_tok->ln, last_known_tok->cn); return NULL; } fzl_token_t *type = NULL; if (is(parser, FZL_TOKTYPE_TYPE) || is(parser, FZL_TOKTYPE_NAME)) type = consume(parser); if (!type) type = &null_tok; if (!is(parser, FZL_TOKTYPE_LBRACE)) { free(args); snprintf(plast_err, sizeof(plast_err), "'%s': expected '{' after function declaration at %ld:%ld", last_known_tok->filename, last_known_tok->ln, last_known_tok->cn); return NULL; } fzl_node_t *body = pa_statement(parser); if (!body) { free(args); return NULL; } fzl_node_t *node = fzl_mknode(FZL_NODETYPE_FUNCTION, name); node->fn.args = args; node->fn.args_count = count; node->fn.body = body; node->fn.name = name; node->fn.type = type; return node; }