#include #include #include // For-loop parsing fzl_node_t *pa_for(fzl_parser_t *parser) { fzl_token_t *tok = consume(parser); fzl_token_t *lpar = consume(parser); if (!lpar || lpar->type != FZL_TOKTYPE_LPAREN) { snprintf(plast_err, sizeof(plast_err), "'%s': expected '(' after for keyword at %ld:%ld", last_known_tok->filename, last_known_tok->ln, last_known_tok->cn); return NULL; } fzl_node_t *start = NULL; if (!is(parser, FZL_TOKTYPE_SEMICOLON)) { start = pa_expression(parser); if (!start) { snprintf(plast_err, sizeof(plast_err), "'%s': expected loop init or ';' at %ld:%ld", last_known_tok->filename, last_known_tok->ln, last_known_tok->cn); return NULL; } fzl_token_t *sc = consume(parser); if (!sc || sc->type != FZL_TOKTYPE_SEMICOLON) { fzl_freeast(start); snprintf(plast_err, sizeof(plast_err), "'%s': missing ';' after init section at %ld:%ld", last_known_tok->filename, last_known_tok->ln, last_known_tok->cn); return NULL; } } else consume(parser); fzl_node_t *condition = NULL; if (!is(parser, FZL_TOKTYPE_SEMICOLON)) { condition = pa_expression(parser); if (!condition) { fzl_freeast(start); snprintf(plast_err, sizeof(plast_err), "'%s': expected loop condition or ';' at %ld:%ld", last_known_tok->filename, last_known_tok->ln, last_known_tok->cn); return NULL; } fzl_token_t *sc = consume(parser); if (!sc || sc->type != FZL_TOKTYPE_SEMICOLON) { fzl_freeast(start); fzl_freeast(condition); snprintf(plast_err, sizeof(plast_err), "'%s': missing ';' after condition at %ld:%ld", last_known_tok->filename, last_known_tok->ln, last_known_tok->cn); return NULL; } } else consume(parser); fzl_node_t *step = NULL; if (!is(parser, FZL_TOKTYPE_RPAREN)) { step = pa_expression(parser); if (!step) { fzl_freeast(start); fzl_freeast(condition); snprintf(plast_err, sizeof(plast_err), "'%s': expected loop step end or ')' at %ld:%ld", last_known_tok->filename, last_known_tok->ln, last_known_tok->cn); return NULL; } } fzl_token_t *rpar = consume(parser); if (!rpar || rpar->type != FZL_TOKTYPE_RPAREN) { fzl_freeast(start); fzl_freeast(condition); fzl_freeast(step); snprintf(plast_err, sizeof(plast_err), "'%s': missing ')' after loop setup 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) { fzl_freeast(start); fzl_freeast(condition); fzl_freeast(step); snprintf(plast_err, sizeof(plast_err), "'%s': missing body of for loop at %ld:%ld", last_known_tok->filename, last_known_tok->ln, last_known_tok->cn); return NULL; } fzl_node_t *node = fzl_mknode(FZL_NODETYPE_LOOP, tok); node->loop.init = start; node->loop.cond = condition; node->loop.step = step; node->loop.body = body; return node; }