int statement(ParserState* ps) { Ast *start = ps->curr, *expr = 0; if (stepifis(ps, PSemi)) { parwrn(ps, "empty statement"); } else if (stepifis(ps, RBreak)) { if (stepifis(ps, PSemi)) {} else { parerr(ps, "expecting ';' after break"); } } else if (stepifis(ps, RReturn)) { if (expression(ps, &expr)) { ast_next_to_first_child(start); } if (stepifis(ps, PSemi)) {} else { parerr(ps, "expecting ';'"); } } else if (if_statement(ps)) {} else if (while_statement(ps)) {} else if (variable_decl(ps)) {} else if (statement_block(ps)) {} else if (expression(ps, &expr)) { Ast* lhs = expr; Ast* op = ps->curr; if (curris(ps, OpAsgn)) { step(ps); if (expression(ps, &expr)) { if (lhs->t == AstGetIdx || lhs->t == AstGetKey) { lhs->t++; free(ast_rmnext(lhs)); ast_next_to_last_child(lhs); } else { ast_swap(lhs, op); ast_next_to_first_child(lhs); ast_next_to_last_child(lhs); } } else { parerr(ps, "invalid assignment"); } } else if (stepifis(ps, OpInc) || stepifis(ps, OpDec)) { ast_swap(lhs, op); ast_next_to_first_child(lhs); } if (stepifis(ps, PSemi)) {} else { parerr(ps, "invalid syntax, missing ';'?"); } } else return 0; return 1; }
int compilation_unit(ParserState* ps) { while (ps->curr != 0) { if (function_decl(ps)) {} else if (variable_decl(ps)) {} else if (statement(ps)) {} else break; } if (ps->curr != 0) { parerr(ps, "invalid syntax"); } return 1; }
// Parse a declaration. // // decl -> [specifier-seq] entity-decl // // entity-decl -> variable-decl // | function-decl Decl* Parser::decl() { // optional specifier-seq Specifier spec = specifier_seq(); // entity-decl switch (lookahead()) { case var_kw: return variable_decl(spec); case def_kw: return function_decl(spec); case struct_kw: return record_decl(spec); default: // TODO: Is this a recoverable error? error("invalid declaration"); } }