function Expr* parse_expr(Parser* p); function Expr* parse_list_expr(Parser* p); function Expr* parse_atom_expr(Parser* p){ Expr* result = 0; if (token_is(p, TK_Identifier) || token_is(p, TK_StringLit) || token_is(p, TK_U8Lit) || token_is(p, TK_Int)){ result = expr_atom(p, token_next(p)); } else if (token_match(p, TK_OpenParen)){ result = parse_list_expr(p); token_expect(p, TK_CloseParen); } else { parser_push_error(p, token_next(p), "Invalid expression token"); } return result; } function Expr* parse_postfix_expr(Parser* p){ Expr* result = parse_atom_expr(p); while (token_is(p, TK_Dot) || token_is(p, TK_Arrow) || token_is(p, TK_DoubleColon) || token_is(p, TK_OpenParen) || token_is(p, TK_OpenBracket) || token_is(p, TK_Decrement) || token_is(p, TK_Increment)){ Token *op = token_get(p); if (token_match(p, TK_Arrow) || token_match(p, TK_DoubleColon) || token_match(p, TK_Dot)){ Expr* r = parse_atom_expr(p); result = expr_binary(p, op, result, r); } else if (token_match(p, TK_OpenParen)){ Expr* list = 0; if (!token_match(p, TK_CloseParen)){ list = parse_list_expr(p); token_expect(p, TK_CloseParen); } result = expr_call(p, op, result, list); } else if (token_match(p, TK_OpenBracket)){ Expr* list = 0; if (!token_match(p, TK_CloseBracket)){ list = parse_list_expr(p); token_match(p, TK_CloseBracket); } result = expr_index(p, op, result, list); } else { assert(op->kind == TK_Increment || op->kind == TK_Decrement); token_next(p); if (op->kind == TK_Increment) op->kind = TK_PostIncrement; else if (op->kind == TK_Decrement) op->kind = TK_PostDecrement; result = expr_unary(p, op, result); } } return result; } function Expr* parse_unary_expr(Parser* p) { Expr* result = 0; if (token_is(p, TK_Sub) || token_is(p, TK_Add) || token_is(p, TK_Mul) || token_is(p, TK_BitAnd) || token_is(p, TK_Not) || token_is(p, TK_Neg) || token_is(p, TK_Increment) || token_is(p, TK_Decrement)) { Token *op = token_next(p); result = parse_unary_expr(p); result = expr_unary(p, op, result); } else if (token_is_keyword(p, keyword_sizeof)) { Token *token = token_next(p); result = parse_unary_expr(p); result = expr_unary(p, token, result); } /* else if (token_is(p, TK_OpenParen)) { // cast requires lookahead Token *token = token_peek(p, 1); if (token->kind == TK_Identifier) { AST_Node *type = symbol_lookup_type(p, token->intern_val); if(type){ token_next(p); token_next(p); // @Todo(Krzosa): Parse pointer types token_expect(p, TK_CloseParen); result = parse_unary_expr(p); result = expr_cast(p, token, type, result); } else { result = parse_postfix_expr(p); } } else { result = parse_postfix_expr(p); } } */ else { result = parse_postfix_expr(p); } return result; } function Expr* parse_mul_expr(Parser* p) { Expr* result = parse_unary_expr(p); while (token_is(p, TK_Mul) || token_is(p, TK_Div) || token_is(p, TK_Mod)) { Token *op = token_next(p); Expr* r = parse_unary_expr(p); result = expr_binary(p, op, result, r); } return result; } function Expr* parse_add_expr(Parser* p) { Expr* result = parse_mul_expr(p); while (token_is(p, TK_Add) || token_is(p, TK_Sub)) { Token *op = token_next(p); Expr* right = parse_mul_expr(p); result = expr_binary(p, op, result, right); } return result; } function Expr* parse_shift_expr(Parser* p) { Expr* result = parse_add_expr(p); while (token_is(p, TK_RightShift) || token_is(p, TK_LeftShift)) { Token *op = token_next(p); Expr* r = parse_add_expr(p); result = expr_binary(p, op, result, r); } return result; } function Expr* parse_compare_expr(Parser* p) { Expr* result = parse_shift_expr(p); while (token_is(p, TK_LesserThen) || token_is(p, TK_GreaterThen) || token_is(p, TK_LesserThenOrEqual) || token_is(p, TK_GreaterThenOrEqual)) { Token *op = token_next(p); Expr* r = parse_shift_expr(p); result = expr_binary(p, op, result, r); } return result; } function Expr* parse_equality_expr(Parser* p) { Expr* result = parse_compare_expr(p); while (token_is(p, TK_Equals) || token_is(p, TK_NotEquals)) { Token *op = token_next(p); Expr* r = parse_compare_expr(p); result = expr_binary(p, op, result, r); } return result; } function Expr* parse_bit_and_expr(Parser* p) { Expr* result = parse_equality_expr(p); while (token_is(p, TK_BitAnd)) { Token *op = token_next(p); Expr* r = parse_equality_expr(p); result = expr_binary(p, op, result, r); } return result; } function Expr* parse_bit_xor_expr(Parser* p) { Expr* result = parse_bit_and_expr(p); while (token_is(p, TK_BitXor)) { Token *op = token_next(p); Expr* r = parse_bit_and_expr(p); result = expr_binary(p, op, result, r); } return result; } function Expr* parse_bit_or_expr(Parser* p) { Expr* result = parse_bit_xor_expr(p); while (token_is(p, TK_BitOr)) { Token *op = token_next(p); Expr* r = parse_bit_xor_expr(p); result = expr_binary(p, op, result, r); } return result; } function Expr* parse_and_expr(Parser* p) { Expr* result = parse_bit_or_expr(p); while (token_is(p, TK_And)) { Token *op = token_next(p); Expr* r = parse_bit_or_expr(p); result = expr_binary(p, op, result, r); } return result; } function Expr* parse_or_expr(Parser* p) { Expr* result = parse_and_expr(p); while (token_is(p, TK_Or)) { Token *op = token_next(p); Expr* r = parse_and_expr(p); result = expr_binary(p, op, result, r); } return result; } function Expr* parse_ternary_expr(Parser* p) { Expr* result = parse_or_expr(p); if (token_is(p, TK_Question)) { Token *token = token_next(p); Expr* on_true = parse_ternary_expr(p); token_expect(p, TK_Colon); Expr* on_false = parse_ternary_expr(p); result = expr_ternary(p, token, result, on_true, on_false); } return result; } function Expr* parse_assign_expr(Parser* p) { Expr* result = parse_ternary_expr(p); if (token_is_assignment(p)) { Token *op = token_next(p); Expr* right = parse_assign_expr(p); result = expr_binary(p, op, result, right); } return result; } function Expr* parse_list_expr(Parser* p) { Expr* result = parse_assign_expr(p); if (token_is(p, TK_Comma)) { Expr *list = expr_list(p, token_get(p)); expr_list_push(list, result); result = list; } while (token_is(p, TK_Comma)) { Token *token = token_next(p); Expr* expr = parse_assign_expr(p); expr_list_push(result, expr); } return result; } function Expr* parse_expr(Parser* p) { return parse_assign_expr(p); }