struct instruction *parse_instruction(void) { struct expr *expr; struct instruction *res; switch (lookahead[0]->type) { case WHILE: return parse_while(); case DO: return parse_do(); case IDENTIFIER: case LPAREN: expr = parse_expression(); switch(lookahead[0]->type) { case ASSIGN: return parse_assignment_instr(expr); case EOL: if (expr->exprtype != funcalltype) { if (expr->exprtype == binopexprtype && expr->val.binopexpr.op == EQ) { error(expr->pos, "unexpected =, did you mean <- ?"); exit(1); } else syntaxerror("expected instruction, not expression"); } eat(EOL); res = funcallinstr(expr->val.funcall.fun_ident, expr->val.funcall.args, expr->pos); free(expr); return res; default: next(); syntaxerror("unexpected %s", tok->val); return parse_instruction(); } case RETURN: eat(RETURN); if (lookahead[0]->type == EOL) { eat(EOL); return return_stmt(NULL); } else { expr = parse_expression(); eat(EOL); return return_stmt(expr); } case FOR: return parse_for(); case IF: return parse_if(); case SWITCH: return parse_switch(); case ENDOFFILE: return NULL; default: next(); syntaxerror("expected instruction, not %s", tok->val); return parse_instruction(); } }
bool Parser::parse_statement(StatementList *list) { lexer.identify_keywords(); switch(lexeme()) { case Lexeme::KW_IF: parse_if(list); break; case Lexeme::KW_WHILE: parse_while(list); break; case Lexeme::KW_DO: parse_do(list); parse_terminator(); break; case Lexeme::KW_RETURN: parse_return(list); parse_terminator(); break; case Lexeme::KW_BREAK: parse_break(list); parse_terminator(); break; case Lexeme::KW_CONTINUE: parse_continue(list); parse_terminator(); break; case Lexeme::KW_CONST: step(); parse_local(true, parse_expression(), list); parse_terminator(); break; case Lexeme::BRACET_OPEN: list->append(parse_block<true, false>(Scope::EMPTY)); break; case Lexeme::SEMICOLON: step(); break; case Lexeme::END: case Lexeme::BRACET_CLOSE: return false; default: if(is_expression(lexeme())) { ExpressionNode *node = parse_expression(); if(lexeme() == Lexeme::IDENT && node->is_type_name(document, false)) parse_local(false, node, list); else list->append(node); parse_terminator(); } else return false; } return true; }