diff --git a/src/compiler/compiler.c b/src/compiler/compiler.c index 5fd1bf73b..16223f3e4 100644 --- a/src/compiler/compiler.c +++ b/src/compiler/compiler.c @@ -8,7 +8,6 @@ #define MAX_OUTPUT_FILES 1000000 #define MAX_MODULES 100000 - GlobalContext global_context; BuildTarget active_target; diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index 91902bcdd..ded0cb2fe 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -2385,10 +2385,11 @@ bool obj_format_linking_supported(ObjectFormatType format_type); bool linker(const char *output_file, const char **files, unsigned file_count); void platform_linker(const char *output_file, const char **files, unsigned file_count); -#define TRY_AST_OR(_ast_stmt, _res) ({ Ast* _ast = (_ast_stmt); if (!ast_ok(_ast)) return _res; _ast; }) -#define TRY_EXPR_OR(_expr_stmt, _res) ({ Expr* _expr = (_expr_stmt); if (!expr_ok(_expr)) return _res; _expr; }) -#define TRY_TYPE_OR(_type_stmt, _res) ({ TypeInfo* _type = (_type_stmt); if (!type_info_ok(_type)) return _res; _type; }) -#define TRY_TYPE_REAL_OR(_type_stmt, _res) ({ Type* _type = (_type_stmt); if (!type_ok(_type)) return _res; _type; }) -#define TRY_DECL_OR(_decl_stmt, _res) ({ Decl* _decl = (_decl_stmt); if (!decl_ok(_decl)) return _res; _decl; }) - +#define CAT(a,b) CAT2(a,b) // force expand +#define CAT2(a,b) a##b // actually concatenate +#define TEMP(X) CAT(X, __LINE__) +#define ASSIGN_AST_ELSE(_assign, _ast_stmt, _res) Ast* TEMP(_ast) = (_ast_stmt); if (!ast_ok(TEMP(_ast))) return _res; _assign = TEMP(_ast) +#define ASSIGN_EXPR_ELSE(_assign, _expr_stmt, _res) Expr* TEMP(_expr) = (_expr_stmt); if (!expr_ok(TEMP(_expr))) return _res; _assign = TEMP(_expr) +#define ASSIGN_TYPE_ELSE(_assign, _type_stmt, _res) TypeInfo* TEMP(_type) = (_type_stmt); if (!type_info_ok(TEMP(_type))) return _res; _assign = TEMP(_type) +#define ASSIGN_DECL_ELSE(_assign, _decl_stmt, _res) Decl* TEMP(_decl) = (_decl_stmt); if (!decl_ok(TEMP(_decl))) return _res; _assign = TEMP(_decl) diff --git a/src/compiler/parse_expr.c b/src/compiler/parse_expr.c index 6ebe4e212..3f8036b8a 100644 --- a/src/compiler/parse_expr.c +++ b/src/compiler/parse_expr.c @@ -81,8 +81,15 @@ static inline Expr *parse_catch_unwrap(Context *context) { advance_and_verify(context, TOKEN_CATCH); Expr *expr = expr_new(EXPR_CATCH_UNWRAP, source_span_from_token_id(context->prev_tok)); - expr->catch_unwrap_expr.type = parse_next_is_decl(context) ? TRY_TYPE_OR(parse_type(context), poisoned_expr) : NULL; - expr->catch_unwrap_expr.variable = TRY_EXPR_OR(parse_for_try_expr(context), poisoned_expr); + if (parse_next_is_decl(context)) + { + ASSIGN_TYPE_ELSE(expr->catch_unwrap_expr.type, parse_type(context), poisoned_expr); + } + else + { + expr->catch_unwrap_expr.type = NULL; + } + ASSIGN_EXPR_ELSE(expr->catch_unwrap_expr.variable, parse_for_try_expr(context), poisoned_expr); if (!try_consume(context, TOKEN_EQ)) { if (expr->catch_unwrap_expr.type) @@ -99,14 +106,14 @@ static inline Expr *parse_catch_unwrap(Context *context) { do { - Expr *init_expr = TRY_EXPR_OR(parse_expr(context), poisoned_expr); + ASSIGN_EXPR_ELSE(Expr *init_expr, parse_expr(context), poisoned_expr); vec_add(expr->catch_unwrap_expr.exprs, init_expr); } while (try_consume(context, TOKEN_COMMA)); CONSUME_OR(TOKEN_RPAREN, poisoned_expr); } else { - Expr *init_expr = TRY_EXPR_OR(parse_expr(context), poisoned_expr); + ASSIGN_EXPR_ELSE(Expr *init_expr, parse_expr(context), poisoned_expr); vec_add(expr->catch_unwrap_expr.exprs, init_expr); } RANGE_EXTEND_PREV(expr); @@ -122,9 +129,9 @@ static inline Expr *parse_try_unwrap(Context *context) advance_and_verify(context, TOKEN_TRY); if (parse_next_is_decl(context)) { - expr->try_unwrap_expr.type = TRY_TYPE_OR(parse_type(context), poisoned_expr); + ASSIGN_TYPE_ELSE(expr->try_unwrap_expr.type, parse_type(context), poisoned_expr); } - expr->try_unwrap_expr.variable = TRY_EXPR_OR(parse_for_try_expr(context), poisoned_expr); + ASSIGN_EXPR_ELSE(expr->try_unwrap_expr.variable, parse_for_try_expr(context), poisoned_expr); if (expr->try_unwrap_expr.type && expr->try_unwrap_expr.variable->expr_kind != EXPR_IDENTIFIER) { SEMA_ERROR(expr->try_unwrap_expr.variable, "Expected a variable name after the type."); @@ -132,7 +139,7 @@ static inline Expr *parse_try_unwrap(Context *context) } if (try_consume(context, TOKEN_EQ)) { - expr->try_unwrap_expr.init = TRY_EXPR_OR(parse_for_try_expr(context), poisoned_expr); + ASSIGN_EXPR_ELSE(expr->try_unwrap_expr.init, parse_for_try_expr(context), poisoned_expr); } RANGE_EXTEND_PREV(expr); return expr; @@ -145,17 +152,17 @@ static inline Expr *parse_try_unwrap(Context *context) static inline Expr *parse_try_unwrap_chain(Context *context) { Expr **unwraps = NULL; - Expr *first_unwrap = TRY_EXPR_OR(parse_try_unwrap(context), poisoned_expr); +ASSIGN_EXPR_ELSE(Expr *first_unwrap , parse_try_unwrap(context), poisoned_expr); vec_add(unwraps, first_unwrap); while (try_consume(context, TOKEN_AND)) { if (next_is_try_unwrap(context)) { - Expr *expr = TRY_EXPR_OR(parse_try_unwrap(context), poisoned_expr); + ASSIGN_EXPR_ELSE(Expr *expr, parse_try_unwrap(context), poisoned_expr); vec_add(unwraps, expr); continue; } - Expr *next_unwrap = TRY_EXPR_OR(parse_for_try_expr(context), poisoned_expr); + ASSIGN_EXPR_ELSE(Expr *next_unwrap, parse_for_try_expr(context), poisoned_expr); vec_add(unwraps, next_unwrap); } Expr *try_unwrap_chain = EXPR_NEW_EXPR(EXPR_TRY_UNWRAP_CHAIN, first_unwrap); @@ -185,7 +192,7 @@ Expr *parse_cond(Context *context) { if (next_is_try_unwrap(context)) { - Expr *try_unwrap = TRY_EXPR_OR(parse_try_unwrap_chain(context), poisoned_expr); + ASSIGN_EXPR_ELSE(Expr *try_unwrap, parse_try_unwrap_chain(context), poisoned_expr); vec_add(decl_expr->cond_expr, try_unwrap); if (tok_is(context, TOKEN_COMMA)) { @@ -196,7 +203,7 @@ Expr *parse_cond(Context *context) } if (next_is_catch_unwrap(context)) { - Expr *catch_unwrap = TRY_EXPR_OR(parse_catch_unwrap(context), poisoned_expr); + ASSIGN_EXPR_ELSE(Expr *catch_unwrap, parse_catch_unwrap(context), poisoned_expr); vec_add(decl_expr->cond_expr, catch_unwrap); if (tok_is(context, TOKEN_COMMA)) { @@ -207,14 +214,14 @@ Expr *parse_cond(Context *context) } if (parse_next_is_decl(context)) { - Decl *decl = TRY_DECL_OR(parse_decl(context), poisoned_expr); + ASSIGN_DECL_ELSE(Decl *decl, parse_decl(context), poisoned_expr); Expr *expr = expr_new(EXPR_DECL, decl->span); expr->decl_expr = decl; vec_add(decl_expr->cond_expr, expr); } else { - Expr *expr = TRY_EXPR_OR(parse_expr(context), poisoned_expr); + ASSIGN_EXPR_ELSE(Expr *expr, parse_expr(context), poisoned_expr); vec_add(decl_expr->cond_expr, expr); } if (!try_consume(context, TOKEN_COMMA)) break; @@ -251,11 +258,12 @@ static bool parse_param_path(Context *context, DesignatorElement ***path) DesignatorElement *element = CALLOCS(DesignatorElement); element->kind = DESIGNATOR_ARRAY; advance_and_verify(context, TOKEN_LBRACKET); - element->index_expr = TRY_EXPR_OR(parse_expr(context), false); + ASSIGN_EXPR_ELSE(element->index_expr, parse_expr(context), false); + // Possible range if (try_consume(context, TOKEN_DOTDOT)) { - element->index_end_expr = TRY_EXPR_OR(parse_expr(context), false); + ASSIGN_EXPR_ELSE(element->index_end_expr, parse_expr(context), false); element->kind = DESIGNATOR_RANGE; } CONSUME_OR(TOKEN_RBRACKET, false); @@ -303,7 +311,7 @@ bool parse_arg_list(Context *context, Expr ***result, TokenType param_end, bool CONSUME_OR(TOKEN_EQ, false); // Now parse the rest - expr->designator_expr.value = TRY_EXPR_OR(parse_expr_or_initializer_list(context), false); + ASSIGN_EXPR_ELSE(expr->designator_expr.value, parse_expr_or_initializer_list(context), false); } else { @@ -311,7 +319,7 @@ bool parse_arg_list(Context *context, Expr ***result, TokenType param_end, bool { *unsplat = try_consume(context, TOKEN_ELLIPSIS); } - expr = TRY_EXPR_OR(parse_expr_or_initializer_list(context), false); + ASSIGN_EXPR_ELSE(expr, parse_expr_or_initializer_list(context), false); } vec_add(*result, expr); if (!try_consume(context, TOKEN_COMMA)) @@ -335,7 +343,7 @@ static Expr *parse_macro_expansion(Context *context, Expr *left) assert(!left && "Unexpected left hand side"); Expr *macro_expression = EXPR_NEW_TOKEN(EXPR_MACRO_EXPANSION, context->tok); advance_and_verify(context, TOKEN_AT); - Expr *inner = TRY_EXPR_OR(parse_precedence(context, PREC_MACRO), poisoned_expr); + ASSIGN_EXPR_ELSE(Expr *inner, parse_precedence(context, PREC_MACRO), poisoned_expr); macro_expression->macro_expansion_expr.inner = inner; assert(inner); RANGE_EXTEND_PREV(macro_expression); @@ -356,7 +364,7 @@ Expr *parse_expression_list(Context *context) while (1) { Expr *expr = NULL; - expr = TRY_EXPR_OR(parse_expr_or_initializer_list(context), poisoned_expr); + ASSIGN_EXPR_ELSE(expr, parse_expr_or_initializer_list(context), poisoned_expr); vec_add(expr_list->expression_list, expr); if (!try_consume(context, TOKEN_COMMA)) break; } @@ -377,7 +385,7 @@ static Expr *parse_typeof_expr(Context *context, Expr *left) { assert(!left && "Unexpected left hand side"); Expr *expr = EXPR_NEW_TOKEN(EXPR_TYPEINFO, context->tok); - TypeInfo *type = TRY_TYPE_OR(parse_type(context), poisoned_expr); + ASSIGN_TYPE_ELSE(TypeInfo *type, parse_type(context), poisoned_expr); expr->span = type->span; expr->type_expr = type; return expr; @@ -432,12 +440,12 @@ static Expr *parse_ternary_expr(Context *context, Expr *left_side) else { advance_and_verify(context, TOKEN_QUESTION); - Expr *true_expr = TRY_EXPR_OR(parse_precedence(context, PREC_TERNARY + 1), poisoned_expr); + ASSIGN_EXPR_ELSE(Expr *true_expr, parse_precedence(context, PREC_TERNARY + 1), poisoned_expr); expr_ternary->ternary_expr.then_expr = true_expr; CONSUME_OR(TOKEN_COLON, poisoned_expr); } - Expr *false_expr = TRY_EXPR_OR(parse_precedence(context, PREC_TERNARY + 1), poisoned_expr); + ASSIGN_EXPR_ELSE(Expr *false_expr, parse_precedence(context, PREC_TERNARY + 1), poisoned_expr); expr_ternary->ternary_expr.else_expr = false_expr; RANGE_EXTEND_PREV(expr_ternary); return expr_ternary; @@ -453,7 +461,7 @@ static Expr *parse_grouping_expr(Context *context, Expr *left) assert(!left && "Unexpected left hand side"); Expr *expr = EXPR_NEW_TOKEN(EXPR_GROUP, context->tok); advance_and_verify(context, TOKEN_LPAREN); - expr->group_expr = TRY_EXPR_OR(parse_expr(context), poisoned_expr); + ASSIGN_EXPR_ELSE(expr->group_expr, parse_expr(context), poisoned_expr); CONSUME_OR(TOKEN_RPAREN, poisoned_expr); if (expr->group_expr->expr_kind == EXPR_TYPEINFO && try_consume(context, TOKEN_LPAREN)) { @@ -463,7 +471,7 @@ static Expr *parse_grouping_expr(Context *context, Expr *left) SEMA_TOKEN_ERROR(context->tok, "Unexpected start of a block '{' here. If you intended a compound literal, remove the () around the type."); return poisoned_expr; } - Expr *cast_expr = TRY_EXPR_OR(parse_expr(context), poisoned_expr); + ASSIGN_EXPR_ELSE(Expr *cast_expr, parse_expr(context), poisoned_expr); CONSUME_OR(TOKEN_RPAREN, poisoned_expr); expr->expr_kind = EXPR_CAST; expr->cast_expr.type_info = info; @@ -551,18 +559,18 @@ static Expr *parse_binary(Context *context, Expr *left_side) Expr *right_side; if (TOKEN_IS(TOKEN_LBRACE) && operator_type == TOKEN_EQ) { - right_side = TRY_EXPR_OR(parse_initializer_list(context), poisoned_expr); + ASSIGN_EXPR_ELSE(right_side, parse_initializer_list(context), poisoned_expr); } else { // Assignment operators have precedence right -> left. if (rules[operator_type].precedence == PREC_ASSIGNMENT) { - right_side = TRY_EXPR_OR(parse_precedence(context, PREC_ASSIGNMENT), poisoned_expr); + ASSIGN_EXPR_ELSE(right_side, parse_precedence(context, PREC_ASSIGNMENT), poisoned_expr); } else { - right_side = TRY_EXPR_OR(parse_precedence(context, rules[operator_type].precedence + 1), poisoned_expr); + ASSIGN_EXPR_ELSE(right_side, parse_precedence(context, rules[operator_type].precedence + 1), poisoned_expr); } } @@ -611,7 +619,7 @@ static Expr *parse_call_expr(Context *context, Expr *left) } if (TOKEN_IS(TOKEN_LBRACE)) { - call->call_expr.body = TRY_AST_OR(parse_compound_stmt(context), poisoned_expr); + ASSIGN_AST_ELSE(call->call_expr.body, parse_compound_stmt(context), poisoned_expr); } if (!parse_attributes(context, &call->call_expr.attributes)) return false; return call; @@ -636,7 +644,7 @@ static Expr *parse_subscript_expr(Context *context, Expr *left) { // Might be ^ prefix from_back = try_consume(context, TOKEN_BIT_XOR); - index = TRY_EXPR_OR(parse_expr(context), poisoned_expr); + ASSIGN_EXPR_ELSE(index, parse_expr(context), poisoned_expr); } else { @@ -652,7 +660,7 @@ static Expr *parse_subscript_expr(Context *context, Expr *left) if (!TOKEN_IS(TOKEN_RBRACKET)) { end_from_back = try_consume(context, TOKEN_BIT_XOR); - end = TRY_EXPR_OR(parse_expr(context), poisoned_expr); + ASSIGN_EXPR_ELSE(end, parse_expr(context), poisoned_expr); } } CONSUME_OR(TOKEN_RBRACKET, poisoned_expr); @@ -683,7 +691,7 @@ static Expr *parse_access_expr(Context *context, Expr *left) advance_and_verify(context, TOKEN_DOT); Expr *access_expr = EXPR_NEW_EXPR(EXPR_ACCESS, left); access_expr->access_expr.parent = left; - access_expr->access_expr.child = TRY_EXPR_OR(parse_precedence(context, PREC_CALL + 1), poisoned_expr); + ASSIGN_EXPR_ELSE(access_expr->access_expr.child, parse_precedence(context, PREC_CALL + 1), poisoned_expr); RANGE_EXTEND_PREV(access_expr); return access_expr; } @@ -720,7 +728,7 @@ static Expr *parse_ct_call(Context *context, Expr *left) expr->ct_call_expr.token_type = context->tok.type; advance(context); CONSUME_OR(TOKEN_LPAREN, poisoned_expr); - Expr *internal = TRY_EXPR_OR(parse_precedence(context, PREC_FIRST + 1), poisoned_expr); + ASSIGN_EXPR_ELSE(Expr *internal, parse_precedence(context, PREC_FIRST + 1), poisoned_expr); ExprFlatElement *flat_path = NULL; if (context->tok.type == TOKEN_DOT || context->tok.type == TOKEN_LBRACKET) { @@ -729,7 +737,7 @@ static Expr *parse_ct_call(Context *context, Expr *left) ExprFlatElement flat_element; if (try_consume(context, TOKEN_LBRACKET)) { - Expr *int_expr = TRY_EXPR_OR(parse_expr(context), poisoned_expr); + ASSIGN_EXPR_ELSE(Expr *int_expr, parse_expr(context), poisoned_expr); if (int_expr->expr_kind != EXPR_CONST || int_expr->const_expr.const_kind != CONST_INTEGER) { SEMA_TOKEN_ERROR(context->tok, "Expected an integer index."); @@ -829,7 +837,7 @@ static Expr *parse_try_expr(Context *context, Expr *left) return poisoned_expr; } } - try_expr->try_expr.expr = TRY_EXPR_OR(parse_expr(context), poisoned_expr); + ASSIGN_EXPR_ELSE(try_expr->try_expr.expr, parse_expr(context), poisoned_expr); try_expr->try_expr.is_try = is_try; CONSUME_OR(TOKEN_RPAREN, poisoned_expr); RANGE_EXTEND_PREV(try_expr); @@ -857,7 +865,7 @@ static Expr *parse_else_expr(Context *context, Expr *left) case TOKEN_CONTINUE: case TOKEN_NEXTCASE: { - Ast *ast = TRY_AST_OR(parse_jump_stmt_no_eos(context), poisoned_expr); + ASSIGN_AST_ELSE(Ast *ast, parse_jump_stmt_no_eos(context), poisoned_expr); else_expr->else_expr.is_jump = true; else_expr->else_expr.else_stmt = ast; if (!TOKEN_IS(TOKEN_EOS)) @@ -868,8 +876,10 @@ static Expr *parse_else_expr(Context *context, Expr *left) break; } default: - else_expr->else_expr.else_expr = TRY_EXPR_OR(parse_precedence(context, PREC_ASSIGNMENT), poisoned_expr); + { + ASSIGN_EXPR_ELSE(else_expr->else_expr.else_expr, parse_precedence(context, PREC_ASSIGNMENT), poisoned_expr); break; + } } return else_expr; } @@ -878,7 +888,7 @@ static Expr *parse_placeholder(Context *context, Expr *left) { assert(!left && "Had left hand side"); advance_and_verify(context, TOKEN_PLACEHOLDER); - Expr *expr = TRY_EXPR_OR(parse_expr(context), poisoned_expr); + ASSIGN_EXPR_ELSE(Expr *expr, parse_expr(context), poisoned_expr); CONSUME_OR(TOKEN_RBRACE, poisoned_expr); if (expr->expr_kind != EXPR_IDENTIFIER && TOKTYPE(expr->identifier_expr.identifier) != TOKEN_CONST_IDENT) @@ -1256,7 +1266,7 @@ Expr *parse_type_compound_literal_expr_after_type(Context *context, TypeInfo *ty advance_and_verify(context, TOKEN_LPAREN); Expr *expr = expr_new(EXPR_COMPOUND_LITERAL, type_info->span); expr->expr_compound_literal.type_info = type_info; - expr->expr_compound_literal.initializer = TRY_EXPR_OR(parse_initializer_list(context), poisoned_expr); + ASSIGN_EXPR_ELSE(expr->expr_compound_literal.initializer, parse_initializer_list(context), poisoned_expr); CONSUME_OR(TOKEN_RPAREN, poisoned_expr); RANGE_EXTEND_PREV(expr); return expr; @@ -1280,11 +1290,11 @@ Expr *parse_type_expression_with_path(Context *context, Path *path) type->unresolved.name_loc = context->tok.id; advance_and_verify(context, TOKEN_TYPE_IDENT); RANGE_EXTEND_PREV(type); - type = TRY_TYPE_OR(parse_type_with_base(context, type), poisoned_expr); + ASSIGN_TYPE_ELSE(type, parse_type_with_base(context, type), poisoned_expr); } else { - type = TRY_TYPE_OR(parse_type(context), poisoned_expr); + ASSIGN_TYPE_ELSE(type, parse_type(context), poisoned_expr); } if (!type->virtual_type && TOKEN_IS(TOKEN_LPAREN) && context->next_tok.type == TOKEN_LBRACE) { diff --git a/src/compiler/parse_global.c b/src/compiler/parse_global.c index b143a7ecd..0d1837b4a 100644 --- a/src/compiler/parse_global.c +++ b/src/compiler/parse_global.c @@ -139,7 +139,7 @@ static inline Decl *parse_ct_if_top_level(Context *context) { Decl *ct = DECL_NEW(DECL_CT_IF, VISIBLE_LOCAL); advance_and_verify(context, TOKEN_CT_IF); - ct->ct_if_decl.expr = TRY_EXPR_OR(parse_const_paren_expr(context), poisoned_decl); + ASSIGN_EXPR_ELSE(ct->ct_if_decl.expr, parse_const_paren_expr(context), poisoned_decl); if (!parse_top_level_block(context, &ct->ct_if_decl.then, TOKEN_CT_ENDIF, TOKEN_CT_ELIF, TOKEN_CT_ELSE)) return poisoned_decl; @@ -148,7 +148,8 @@ static inline Decl *parse_ct_if_top_level(Context *context) { advance_and_verify(context, TOKEN_CT_ELIF); Decl *ct_elif = DECL_NEW(DECL_CT_ELIF, VISIBLE_LOCAL); - ct_elif->ct_elif_decl.expr = TRY_EXPR_OR(parse_const_paren_expr(context), poisoned_decl); + ASSIGN_EXPR_ELSE(ct_elif->ct_elif_decl.expr, parse_const_paren_expr(context), poisoned_decl); + if (!parse_top_level_block(context, &ct_elif->ct_elif_decl.then, TOKEN_CT_ENDIF, TOKEN_CT_ELIF, TOKEN_CT_ELSE)) return poisoned_decl; ct_if_decl->elif = ct_elif; ct_if_decl = &ct_elif->ct_elif_decl; @@ -183,7 +184,7 @@ static inline Decl *parse_ct_case(Context *context) case TOKEN_CT_CASE: decl = DECL_NEW(DECL_CT_CASE, VISIBLE_LOCAL); advance(context); - decl->ct_case_decl.type = TRY_TYPE_OR(parse_type(context), poisoned_decl); + ASSIGN_TYPE_ELSE(decl->ct_case_decl.type, parse_type(context), poisoned_decl); break; default: SEMA_TOKEN_ERROR(context->tok, "Expected a $case or $default statement here."); @@ -194,7 +195,7 @@ static inline Decl *parse_ct_case(Context *context) { TokenType type = context->tok.type; if (type == TOKEN_CT_DEFAULT || type == TOKEN_CT_CASE || type == TOKEN_LBRACE) break; - Decl *stmt = TRY_DECL_OR(parse_top_level_statement(context), poisoned_decl); + ASSIGN_DECL_ELSE(Decl *stmt, parse_top_level_statement(context), poisoned_decl); vec_add(decl->ct_case_decl.body, stmt); } return decl; @@ -209,12 +210,12 @@ static inline Decl *parse_ct_switch_top_level(Context *context) { Decl *ct = DECL_NEW(DECL_CT_SWITCH, VISIBLE_LOCAL); advance_and_verify(context, TOKEN_CT_SWITCH); - ct->ct_switch_decl.expr = TRY_EXPR_OR(parse_const_paren_expr(context), poisoned_decl); + ASSIGN_EXPR_ELSE(ct->ct_switch_decl.expr, parse_const_paren_expr(context), poisoned_decl); CONSUME_OR(TOKEN_LBRACE, poisoned_decl); while (!try_consume(context, TOKEN_RBRACE)) { - Decl *result = TRY_DECL_OR(parse_ct_case(context), poisoned_decl); + ASSIGN_DECL_ELSE(Decl *result, parse_ct_case(context), poisoned_decl); vec_add(ct->ct_switch_decl.cases, result); } return ct; @@ -545,7 +546,7 @@ static inline TypeInfo *parse_base_type(Context *context) { TypeInfo *type_info = type_info_new(TYPE_INFO_EXPRESSION, source_span_from_token_id(context->prev_tok)); CONSUME_OR(TOKEN_LPAREN, poisoned_type_info); - type_info->unresolved_type_expr = TRY_EXPR_OR(parse_expr(context), poisoned_type_info); + ASSIGN_EXPR_ELSE(type_info->unresolved_type_expr, parse_expr(context), poisoned_type_info); CONSUME_OR(TOKEN_RPAREN, poisoned_type_info); RANGE_EXTEND_PREV(type_info); return type_info; @@ -656,7 +657,7 @@ static inline TypeInfo *parse_array_type_index(Context *context, TypeInfo *type) } TypeInfo *array = type_info_new(TYPE_INFO_ARRAY, type->span); array->array.base = type; - array->array.len = TRY_EXPR_OR(parse_expr(context), poisoned_type_info); + ASSIGN_EXPR_ELSE(array->array.len, parse_expr(context), poisoned_type_info); CONSUME_OR(TOKEN_RBRACKET, poisoned_type_info); RANGE_EXTEND_PREV(array); return array; @@ -708,7 +709,7 @@ TypeInfo *parse_type_with_base(Context *context, TypeInfo *type_info) */ TypeInfo *parse_type(Context *context) { - TypeInfo *base = TRY_TYPE_OR(parse_base_type(context), poisoned_type_info); + ASSIGN_TYPE_ELSE(TypeInfo *base, parse_base_type(context), poisoned_type_info); return parse_type_with_base(context, base); } @@ -744,7 +745,7 @@ Decl *parse_decl_after_type(Context *context, TypeInfo *type) return poisoned_decl; } advance_and_verify(context, TOKEN_EQ); - decl->var.init_expr = TRY_EXPR_OR(parse_initializer(context), poisoned_decl); + ASSIGN_EXPR_ELSE(decl->var.init_expr, parse_initializer(context), poisoned_decl); } return decl; } @@ -764,11 +765,11 @@ Decl *parse_decl(Context *context) bool is_static = try_consume(context, TOKEN_STATIC); - TypeInfo *type = TRY_TYPE_OR(parse_type(context), poisoned_decl); + ASSIGN_TYPE_ELSE(TypeInfo *type, parse_type(context), poisoned_decl); bool failable = try_consume(context, TOKEN_BANG); - Decl *decl = TRY_DECL_OR(parse_decl_after_type(context, type), poisoned_decl); + ASSIGN_DECL_ELSE(Decl *decl, parse_decl_after_type(context, type), poisoned_decl); if (failable && decl->var.unwrap) { SEMA_ERROR(decl, "You cannot use unwrap with a failable variable."); @@ -795,7 +796,7 @@ static Decl *parse_const_declaration(Context *context, Visibility visibility) if (parse_next_is_decl(context)) { - decl->var.type_info = TRY_TYPE_OR(parse_type(context), poisoned_decl); + ASSIGN_TYPE_ELSE(decl->var.type_info, parse_type(context), poisoned_decl); } decl->name = TOKSTR(context->tok); decl->name_token = context->tok.id; @@ -803,7 +804,7 @@ static Decl *parse_const_declaration(Context *context, Visibility visibility) CONSUME_OR(TOKEN_EQ, poisoned_decl); - decl->var.init_expr = TRY_EXPR_OR(parse_initializer(context), poisoned_decl); + ASSIGN_EXPR_ELSE(decl->var.init_expr, parse_initializer(context), poisoned_decl); return decl; } @@ -855,7 +856,7 @@ static inline Decl *parse_incremental_array(Context *context) return poisoned_decl; } Decl *decl = decl_new(DECL_ARRAY_VALUE, name.id, VISIBLE_LOCAL); - decl->incr_array_decl = TRY_EXPR_OR(parse_initializer(context), poisoned_decl); + ASSIGN_EXPR_ELSE(decl->incr_array_decl, parse_initializer(context), poisoned_decl); TRY_CONSUME_EOS_OR(poisoned_decl); return decl; } @@ -949,7 +950,7 @@ bool parse_attributes(Context *context, Attr ***attributes_ref) if (TOKEN_IS(TOKEN_LPAREN)) { - attr->expr = TRY_EXPR_OR(parse_const_paren_expr(context), false); + ASSIGN_EXPR_ELSE(attr->expr, parse_const_paren_expr(context), false); } const char *name = TOKSTR(attr->name); VECEACH(*attributes_ref, i) @@ -979,7 +980,7 @@ bool parse_attributes(Context *context, Attr ***attributes_ref) */ static inline Decl *parse_global_declaration(Context *context, Visibility visibility) { - TypeInfo *type = TRY_TYPE_OR(parse_type(context), poisoned_decl); + ASSIGN_TYPE_ELSE(TypeInfo *type, parse_type(context), poisoned_decl); bool failable = try_consume(context, TOKEN_BANG); @@ -1008,7 +1009,7 @@ static inline Decl *parse_global_declaration(Context *context, Visibility visibi if (!parse_attributes(context, &decl->attributes)) return poisoned_decl; if (try_consume(context, TOKEN_EQ)) { - decl->var.init_expr = TRY_EXPR_OR(parse_initializer(context), poisoned_decl); + ASSIGN_EXPR_ELSE(decl->var.init_expr, parse_initializer(context), poisoned_decl); } TRY_CONSUME_EOS_OR(poisoned_decl); return decl; @@ -1023,7 +1024,7 @@ static inline Decl *parse_global_declaration(Context *context, Visibility visibi static inline bool parse_param_decl(Context *context, Visibility parent_visibility, Decl*** parameters, bool require_name) { TokenId first = context->tok.id; - TypeInfo *type = TRY_TYPE_OR(parse_type(context), false); + ASSIGN_TYPE_ELSE(TypeInfo *type, parse_type(context), false); bool vararg = try_consume(context, TOKEN_ELLIPSIS); Decl *param = decl_new_var(context->tok.id, type, VARDECL_PARAM, parent_visibility); param->span = (SourceSpan) { first, context->tok.id }; @@ -1051,7 +1052,7 @@ static inline bool parse_param_decl(Context *context, Visibility parent_visibili } if (name && try_consume(context, TOKEN_EQ)) { - param->var.init_expr = TRY_EXPR_OR(parse_initializer(context), false); + ASSIGN_EXPR_ELSE(param->var.init_expr, parse_initializer(context), false); } vec_add(*parameters, param); @@ -1082,7 +1083,7 @@ bool parse_parameters(Context *context, Visibility visibility, Decl ***params_re // so consequently we need fix this and ignore CT_TYPE_IDENT if (!ellipsis && context_next_is_type_and_not_ident(context) && context->tok.type != TOKEN_CT_TYPE_IDENT ) { - type = TRY_TYPE_OR(parse_type(context), false); + ASSIGN_TYPE_ELSE(type, parse_type(context), false); ellipsis = try_consume(context, TOKEN_ELLIPSIS); } @@ -1156,7 +1157,7 @@ bool parse_parameters(Context *context, Visibility visibility, Decl ***params_re advance(context); if (try_consume(context, TOKEN_EQ)) { - param->var.init_expr = TRY_EXPR_OR(parse_initializer(context), false); + ASSIGN_EXPR_ELSE(param->var.init_expr, parse_initializer(context), false); } } var_arg_found |= ellipsis; @@ -1280,7 +1281,8 @@ bool parse_struct_body(Context *context, Decl *parent) was_inline = true; advance(context); } - TypeInfo *type = TRY_TYPE_OR(parse_type(context), false); + ASSIGN_TYPE_ELSE(TypeInfo *type, parse_type(context), false); + while (1) { EXPECT_OR(TOKEN_IDENT, false); @@ -1352,7 +1354,7 @@ static inline bool parse_bitstruct_body(Context *context, Decl *decl) while (!try_consume(context, TOKEN_RBRACE)) { - TypeInfo *type = TRY_TYPE_OR(parse_type(context), false); + ASSIGN_TYPE_ELSE(TypeInfo *type, parse_type(context), false); if (!try_consume(context, TOKEN_IDENT)) { @@ -1366,9 +1368,9 @@ static inline bool parse_bitstruct_body(Context *context, Decl *decl) } Decl *member_decl = decl_new_var(context->prev_tok, type, VARDECL_MEMBER, VISIBLE_LOCAL); CONSUME_OR(TOKEN_COLON, false); - member_decl->var.start = TRY_EXPR_OR(parse_constant_expr(context), false); + ASSIGN_EXPR_ELSE(member_decl->var.start, parse_constant_expr(context), false); CONSUME_OR(TOKEN_DOTDOT, false); - member_decl->var.end = TRY_EXPR_OR(parse_constant_expr(context), false); + ASSIGN_EXPR_ELSE(member_decl->var.end, parse_constant_expr(context), false); CONSUME_OR(TOKEN_EOS, false); vec_add(decl->bitstruct.members, member_decl); } @@ -1389,7 +1391,7 @@ static inline Decl *parse_bitstruct_declaration(Context *context, Visibility vis CONSUME_OR(TOKEN_COLON, poisoned_decl); - decl->bitstruct.base_type = TRY_TYPE_OR(parse_type(context), poisoned_decl); + ASSIGN_TYPE_ELSE(decl->bitstruct.base_type, parse_type(context), poisoned_decl); if (!parse_attributes(context, &decl->attributes)) { @@ -1407,7 +1409,7 @@ static inline Decl *parse_bitstruct_declaration(Context *context, Visibility vis static inline Decl *parse_top_level_const_declaration(Context *context, Visibility visibility) { - Decl *decl = TRY_DECL_OR(parse_const_declaration(context, visibility), poisoned_decl); + ASSIGN_DECL_ELSE(Decl *decl, parse_const_declaration(context, visibility), poisoned_decl); TRY_CONSUME_EOS_OR(poisoned_decl); return decl; } @@ -1456,8 +1458,8 @@ static inline TypeInfo **parse_generic_parameters(Context *context) TypeInfo **types = NULL; while (!try_consume(context, TOKEN_GREATER)) { - TypeInfo *expr = TRY_TYPE_OR(parse_type(context), NULL); - vec_add(types, expr); + ASSIGN_TYPE_ELSE(TypeInfo *type_info, parse_type(context), NULL); + vec_add(types, type_info); if (context->tok.type != TOKEN_RPAREN && context->tok.type != TOKEN_GREATER) { TRY_CONSUME_OR(TOKEN_COMMA, "Expected ',' after argument.", NULL); @@ -1507,7 +1509,7 @@ static inline Decl *parse_define_type(Context *context, Visibility visibility) decl->span.loc = start; decl->typedef_decl.is_func = true; decl->typedef_decl.is_distinct = distinct; - TypeInfo *type_info = TRY_TYPE_OR(parse_type(context), poisoned_decl); + ASSIGN_TYPE_ELSE(TypeInfo *type_info, parse_type(context), poisoned_decl); decl->typedef_decl.function_signature.rtype = type_info; if (try_consume(context, TOKEN_BANG)) { @@ -1523,7 +1525,7 @@ static inline Decl *parse_define_type(Context *context, Visibility visibility) } // 2. Now parse the type which we know is here. - TypeInfo *type_info = TRY_TYPE_OR(parse_type(context), poisoned_decl); + ASSIGN_TYPE_ELSE(TypeInfo *type_info, parse_type(context), poisoned_decl); // 3. Do we have '<' if so it's a parameterized type e.g. foo::bar::Type. if (try_consume(context, TOKEN_LESS)) @@ -1671,7 +1673,7 @@ static inline bool parse_func_macro_header(Context *context, bool rtype_is_optio } // 2. Now we must have a type - either that is the return type or the method type. - rtype = TRY_TYPE_OR(parse_type(context), false); + ASSIGN_TYPE_ELSE(rtype, parse_type(context), false); // 3. We possibly have a failable return at this point. failable = try_consume(context, TOKEN_BANG); @@ -1679,7 +1681,7 @@ static inline bool parse_func_macro_header(Context *context, bool rtype_is_optio // 4. We might have a type here, if so then we read it. if (!TOKEN_IS(TOKEN_DOT) && context_next_is_type_and_not_ident(context)) { - method_type = TRY_TYPE_OR(parse_type(context), false); + ASSIGN_TYPE_ELSE(method_type, parse_type(context), false); } // 5. If we have a dot here, then we need to interpret this as method function. @@ -1737,7 +1739,7 @@ static inline Decl *parse_macro_declaration(Context *context, Visibility visibil TokenId block_parameter = {}; if (!parse_macro_arguments(context, visibility, &decl->macro_decl.parameters, &decl->macro_decl.body_parameters, &block_parameter)) return poisoned_decl; decl->macro_decl.block_parameter = block_parameter; - decl->macro_decl.body = TRY_AST_OR(parse_stmt(context), poisoned_decl); + ASSIGN_AST_ELSE(decl->macro_decl.body, parse_stmt(context), poisoned_decl); return decl; } @@ -1789,7 +1791,7 @@ static inline Decl *parse_error_declaration(Context *context, Visibility visibil } if (try_consume(context, TOKEN_EQ)) { - enum_const->enum_constant.expr = TRY_EXPR_OR(parse_expr(context), poisoned_decl); + ASSIGN_EXPR_ELSE(enum_const->enum_constant.expr, parse_expr(context), poisoned_decl); } vec_add(decl->enums.values, enum_const); // Allow trailing ',' @@ -1809,7 +1811,9 @@ static inline Decl *parse_error_declaration(Context *context, Visibility visibil */ static inline bool parse_enum_spec(Context *context, TypeInfo **type_ref, Decl*** parameters_ref, Visibility parent_visibility) { - *type_ref = TRY_TYPE_OR(parse_type(context), false); + + ASSIGN_TYPE_ELSE(*type_ref, parse_type(context), false); + if (!try_consume(context, TOKEN_LPAREN)) return true; while (!try_consume(context, TOKEN_RPAREN)) { @@ -1894,7 +1898,7 @@ static inline Decl *parse_enum_declaration(Context *context, Visibility visibili } if (try_consume(context, TOKEN_EQ)) { - enum_const->enum_constant.expr = TRY_EXPR_OR(parse_expr(context), poisoned_decl); + ASSIGN_EXPR_ELSE(enum_const->enum_constant.expr, parse_expr(context), poisoned_decl); } vec_add(decl->enums.values, enum_const); // Allow trailing ',' @@ -1964,7 +1968,7 @@ static inline Decl *parse_func_definition(Context *context, Visibility visibilit TRY_EXPECT_OR(TOKEN_LBRACE, "Expected the beginning of a block with '{'", poisoned_decl); - func->func_decl.body = TRY_AST_OR(parse_compound_stmt(context), poisoned_decl); + ASSIGN_AST_ELSE(func->func_decl.body, parse_compound_stmt(context), poisoned_decl); DEBUG_LOG("Finished parsing function %s", func->name); return func; @@ -1999,7 +2003,7 @@ static inline Decl *parse_interface_declaration(Context *context, Visibility vis SEMA_TOKEN_ERROR(context->tok, "Expected a function here."); return poisoned_decl; } - Decl *function = TRY_DECL_OR(parse_func_definition(context, visibility, true), poisoned_decl); + ASSIGN_DECL_ELSE(Decl *function, parse_func_definition(context, visibility, true), poisoned_decl); vec_add(decl->methods, function); } @@ -2122,10 +2126,11 @@ static inline bool parse_doc_errors(Context *context, Ast *docs) static inline bool parse_doc_contract(Context *context, Ast *docs) { - docs->doc_directive.contract.decl_exprs = TRY_EXPR_OR(parse_cond(context), false); + ASSIGN_EXPR_ELSE(docs->doc_directive.contract.decl_exprs, parse_cond(context), false); + if (try_consume(context, TOKEN_COLON)) { - docs->doc_directive.contract.comment = TRY_EXPR_OR(parse_expr(context), false); + ASSIGN_EXPR_ELSE(docs->doc_directive.contract.comment, parse_expr(context), false); } return true; } @@ -2238,18 +2243,22 @@ Decl *parse_top_level_statement(Context *context) SEMA_TOKEN_ERROR(context->tok, "There are more than one doc comment in a row, that is not allowed."); return poisoned_decl; case TOKEN_DEFINE: - decl = TRY_DECL_OR(parse_define(context, visibility), poisoned_decl); + { + ASSIGN_DECL_ELSE(decl, parse_define(context, visibility), poisoned_decl); break; + } case TOKEN_ATTRIBUTE: TODO break; case TOKEN_FUNC: - decl = TRY_DECL_OR(parse_func_definition(context, visibility, false), poisoned_decl); + { + ASSIGN_DECL_ELSE(decl, parse_func_definition(context, visibility, false), poisoned_decl); break; + } case TOKEN_CT_ASSERT: if (!check_no_visibility_before(context, visibility)) return poisoned_decl; { - Ast *ast = TRY_AST_OR(parse_ct_assert_stmt(context), false); + ASSIGN_AST_ELSE(Ast *ast, parse_ct_assert_stmt(context), false); decl = decl_new(DECL_CT_ASSERT, ast->span.loc, visibility); decl->ct_assert_decl = ast; if (docs) @@ -2260,54 +2269,72 @@ Decl *parse_top_level_statement(Context *context) return decl; } case TOKEN_CT_IF: + { if (!check_no_visibility_before(context, visibility)) return poisoned_decl; - decl = TRY_DECL_OR(parse_ct_if_top_level(context), poisoned_decl); + ASSIGN_DECL_ELSE(decl, parse_ct_if_top_level(context), poisoned_decl); if (docs) { SEMA_ERROR(docs, "Unexpected doc comment before $if, did you mean to use a regular comment?"); return poisoned_decl; } break; + } case TOKEN_CT_SWITCH: + { if (!check_no_visibility_before(context, visibility)) return poisoned_decl; - decl = TRY_DECL_OR(parse_ct_switch_top_level(context), poisoned_decl); + ASSIGN_DECL_ELSE(decl, parse_ct_switch_top_level(context), poisoned_decl); if (docs) { SEMA_ERROR(docs, "Unexpected doc comment before $switch, did you mean to use a regular comment?"); return poisoned_decl; } break; + } case TOKEN_BITSTRUCT: - decl = TRY_DECL_OR(parse_bitstruct_declaration(context, visibility), poisoned_decl); + { + ASSIGN_DECL_ELSE(decl, parse_bitstruct_declaration(context, visibility), poisoned_decl); break; + } case TOKEN_CONST: - decl = TRY_DECL_OR(parse_top_level_const_declaration(context, visibility), poisoned_decl); + { + ASSIGN_DECL_ELSE(decl, parse_top_level_const_declaration(context, visibility), poisoned_decl); break; + } case TOKEN_INTERFACE: - decl = TRY_DECL_OR(parse_interface_declaration(context, visibility), poisoned_decl); + { + ASSIGN_DECL_ELSE(decl, parse_interface_declaration(context, visibility), poisoned_decl); break; + } case TOKEN_STRUCT: case TOKEN_UNION: - decl = TRY_DECL_OR(parse_struct_declaration(context, visibility), poisoned_decl); + { + ASSIGN_DECL_ELSE(decl, parse_struct_declaration(context, visibility), poisoned_decl); break; + } case TOKEN_GENERIC: case TOKEN_MACRO: - decl = TRY_DECL_OR(parse_macro_declaration(context, visibility), poisoned_decl); + { + ASSIGN_DECL_ELSE(decl, parse_macro_declaration(context, visibility), poisoned_decl); break; + } case TOKEN_ENUM: - decl = TRY_DECL_OR(parse_enum_declaration(context, visibility), poisoned_decl); + { + ASSIGN_DECL_ELSE(decl, parse_enum_declaration(context, visibility), poisoned_decl); break; + } case TOKEN_ERRTYPE: - decl = TRY_DECL_OR(parse_error_declaration(context, visibility), poisoned_decl); + { + ASSIGN_DECL_ELSE(decl, parse_error_declaration(context, visibility), poisoned_decl); break; + } case TOKEN_IDENT: if (context->next_tok.type == TOKEN_SCOPE) { - decl = TRY_DECL_OR(parse_global_declaration(context, visibility), poisoned_decl); + ASSIGN_DECL_ELSE(decl, parse_global_declaration(context, visibility), poisoned_decl); break; } if (!check_no_visibility_before(context, visibility)) return poisoned_decl; - decl = TRY_DECL_OR(parse_incremental_array(context), poisoned_decl); + ASSIGN_DECL_ELSE(decl, parse_incremental_array(context), poisoned_decl); if (docs) { SEMA_ERROR(docs, @@ -2333,8 +2360,10 @@ Decl *parse_top_level_statement(Context *context) SEMA_TOKEN_ERROR(context->tok, "Imports are only allowed directly after the module declaration."); return poisoned_decl; case TYPELIKE_TOKENS: - decl = TRY_DECL_OR(parse_global_declaration(context, visibility), poisoned_decl); + { + ASSIGN_DECL_ELSE(decl, parse_global_declaration(context, visibility), poisoned_decl); break; + } default: SEMA_TOKEN_ERROR(context->tok, "Expected a top level declaration here."); return poisoned_decl; diff --git a/src/compiler/parse_stmt.c b/src/compiler/parse_stmt.c index 5d0141505..0819ff28f 100644 --- a/src/compiler/parse_stmt.c +++ b/src/compiler/parse_stmt.c @@ -18,7 +18,7 @@ Ast *parse_unreachable_stmt(Context *context); static inline Ast *parse_declaration_stmt(Context *context) { Ast *decl_stmt = AST_NEW_TOKEN(AST_DECLARE_STMT, context->tok); - decl_stmt->declare_stmt = TRY_DECL_OR(parse_decl(context), poisoned_ast); + ASSIGN_DECL_ELSE(decl_stmt->declare_stmt, parse_decl(context), poisoned_ast); CONSUME_OR(TOKEN_EOS, poisoned_ast); return decl_stmt; } @@ -147,7 +147,7 @@ static inline Ast* parse_asm_stmt(Context *context) advance_and_verify(context, TOKEN_ASM); ast->asm_stmt.is_volatile = try_consume(context, TOKEN_VOLATILE); CONSUME_OR(TOKEN_LPAREN, poisoned_ast); - ast->asm_stmt.body = TRY_EXPR_OR(parse_expr(context), poisoned_ast); + ASSIGN_EXPR_ELSE(ast->asm_stmt.body, parse_expr(context), poisoned_ast); ast->asm_stmt.is_volatile = true; CONSUME_OR(TOKEN_RPAREN, poisoned_ast); RANGE_EXTEND_PREV(ast); @@ -166,13 +166,13 @@ static inline Ast* parse_do_stmt(Context *context) advance_and_verify(context, TOKEN_DO); - do_ast->do_stmt.flow.label = TRY_DECL_OR(parse_optional_label(context, do_ast), poisoned_ast); - do_ast->do_stmt.body = TRY_AST(parse_stmt(context)); + ASSIGN_DECL_ELSE(do_ast->do_stmt.flow.label, parse_optional_label(context, do_ast), poisoned_ast); + ASSIGN_AST_ELSE(do_ast->do_stmt.body, parse_stmt(context), poisoned_ast); if (try_consume(context, TOKEN_WHILE)) { CONSUME_OR(TOKEN_LPAREN, poisoned_ast); - do_ast->do_stmt.expr = TRY_EXPR_OR(parse_expr(context), poisoned_ast); + ASSIGN_EXPR_ELSE(do_ast->do_stmt.expr, parse_expr(context), poisoned_ast); CONSUME_OR(TOKEN_RPAREN, poisoned_ast); CONSUME_OR(TOKEN_EOS, poisoned_ast); } @@ -191,7 +191,7 @@ static inline Ast *parse_case_stmts(Context *context, TokenType case_type, Token Ast *compound = AST_NEW_TOKEN(AST_COMPOUND_STMT, context->tok); while (!token_type_ends_case(context->tok.type, case_type, default_type)) { - Ast *stmt = TRY_AST(parse_stmt(context)); + ASSIGN_AST_ELSE(Ast *stmt, parse_stmt(context), poisoned_ast); vec_add(compound->compound_stmt.stmts, stmt); } return compound; @@ -207,7 +207,7 @@ static inline Ast* parse_defer_stmt(Context *context) { advance_and_verify(context, TOKEN_DEFER); Ast *defer_stmt = AST_NEW_TOKEN(AST_DEFER_STMT, context->tok); - defer_stmt->defer_stmt.body = TRY_AST(parse_stmt(context)); + ASSIGN_AST_ELSE(defer_stmt->defer_stmt.body, parse_stmt(context), poisoned_ast); return defer_stmt; } @@ -220,12 +220,12 @@ static inline Ast* parse_while_stmt(Context *context) Ast *while_ast = AST_NEW_TOKEN(AST_WHILE_STMT, context->tok); advance_and_verify(context, TOKEN_WHILE); - while_ast->while_stmt.flow.label = TRY_DECL_OR(parse_optional_label(context, while_ast), poisoned_ast); + ASSIGN_DECL_ELSE(while_ast->while_stmt.flow.label, parse_optional_label(context, while_ast), poisoned_ast); CONSUME_OR(TOKEN_LPAREN, poisoned_ast); - while_ast->while_stmt.cond = TRY_EXPR_OR(parse_cond(context), poisoned_ast); + ASSIGN_EXPR_ELSE(while_ast->while_stmt.cond, parse_cond(context), poisoned_ast); CONSUME_OR(TOKEN_RPAREN, poisoned_ast); - while_ast->while_stmt.body = TRY_AST(parse_stmt(context)); + ASSIGN_AST_ELSE(while_ast->while_stmt.body, parse_stmt(context), poisoned_ast); return while_ast; } @@ -252,9 +252,9 @@ static inline Ast* parse_if_stmt(Context *context) { Ast *if_ast = AST_NEW_TOKEN(AST_IF_STMT, context->tok); advance_and_verify(context, TOKEN_IF); - if_ast->if_stmt.flow.label = TRY_DECL_OR(parse_optional_label(context, if_ast), poisoned_ast); + ASSIGN_DECL_ELSE(if_ast->if_stmt.flow.label, parse_optional_label(context, if_ast), poisoned_ast); CONSUME_OR(TOKEN_LPAREN, poisoned_ast); - if_ast->if_stmt.cond = TRY_EXPR_OR(parse_cond(context), poisoned_ast); + ASSIGN_EXPR_ELSE(if_ast->if_stmt.cond, parse_cond(context), poisoned_ast); CONSUME_OR(TOKEN_RPAREN, poisoned_ast); // Special case, we might have if ( ) { case ... } if (tok_is(context, TOKEN_LBRACE) && (context->next_tok.type == TOKEN_CASE || context->next_tok.type == TOKEN_DEFAULT)) @@ -267,13 +267,13 @@ static inline Ast* parse_if_stmt(Context *context) } else { - if_ast->if_stmt.then_body = TRY_AST(parse_stmt(context)); + ASSIGN_AST_ELSE(if_ast->if_stmt.then_body, parse_stmt(context), poisoned_ast); } if (!try_consume(context, TOKEN_ELSE)) { return if_ast; } - if_ast->if_stmt.else_body = TRY_AST(parse_stmt(context)); + ASSIGN_AST_ELSE(if_ast->if_stmt.else_body, parse_stmt(context), poisoned_ast); return if_ast; } @@ -283,10 +283,11 @@ static bool parse_type_or_expr(Context *context, TypeInfo **type_info, Expr **ex { if (parse_next_is_case_type(context)) { - *type_info = TRY_TYPE_OR(parse_type(context), false); + ASSIGN_TYPE_ELSE(*type_info, parse_type(context), false); return true; } - *expr = TRY_EXPR_OR(parse_constant_expr(context), false);; + ASSIGN_EXPR_ELSE(*expr, parse_constant_expr(context), false); + return true; } @@ -302,7 +303,7 @@ static inline Ast *parse_case_stmt(Context *context, TokenType case_type, TokenT { Ast *ast = AST_NEW_TOKEN(AST_CASE_STMT, context->tok); advance(context); - ast->case_stmt.expr = TRY_EXPR_OR(parse_expr(context), poisoned_ast); + ASSIGN_EXPR_ELSE(ast->case_stmt.expr, parse_expr(context), poisoned_ast); // Change type -> type.typeid if (ast->case_stmt.expr->expr_kind == EXPR_TYPEINFO) { @@ -310,7 +311,7 @@ static inline Ast *parse_case_stmt(Context *context, TokenType case_type, TokenT } TRY_CONSUME(TOKEN_COLON, "Missing ':' after case"); extend_ast_with_prev_token(context, ast); - ast->case_stmt.body = TRY_AST(parse_case_stmts(context, case_type, default_type)); + ASSIGN_AST_ELSE(ast->case_stmt.body, parse_case_stmts(context, case_type, default_type), poisoned_ast); return ast; } @@ -324,7 +325,7 @@ static inline Ast *parse_default_stmt(Context *context, TokenType case_type, Tok advance(context); TRY_CONSUME_OR(TOKEN_COLON, "Expected ':' after 'default'.", poisoned_ast); extend_ast_with_prev_token(context, ast); - ast->case_stmt.body = TRY_AST(parse_case_stmts(context, case_type, default_type)); + ASSIGN_AST_ELSE(ast->case_stmt.body, parse_case_stmts(context, case_type, default_type), poisoned_ast); ast->case_stmt.expr = NULL; return ast; } @@ -347,11 +348,11 @@ bool parse_switch_body(Context *context, Ast ***cases, TokenType case_type, Toke TokenType next = context->tok.type; if (next == case_type) { - result = TRY_AST_OR(parse_case_stmt(context, case_type, default_type), false); + ASSIGN_AST_ELSE(result, parse_case_stmt(context, case_type, default_type), false); } else if (next == default_type) { - result = TRY_AST_OR(parse_default_stmt(context, case_type, default_type), false); + ASSIGN_AST_ELSE(result, parse_default_stmt(context, case_type, default_type), false); } else { @@ -372,9 +373,9 @@ static inline Ast* parse_switch_stmt(Context *context) { Ast *switch_ast = AST_NEW_TOKEN(AST_SWITCH_STMT, context->tok); advance_and_verify(context, TOKEN_SWITCH); - switch_ast->switch_stmt.flow.label = TRY_DECL_OR(parse_optional_label(context, switch_ast), poisoned_ast); + ASSIGN_DECL_ELSE(switch_ast->switch_stmt.flow.label, parse_optional_label(context, switch_ast), poisoned_ast); CONSUME_OR(TOKEN_LPAREN, poisoned_ast); - switch_ast->switch_stmt.cond = TRY_EXPR_OR(parse_cond(context), poisoned_ast); + ASSIGN_EXPR_ELSE(switch_ast->switch_stmt.cond, parse_cond(context), poisoned_ast); CONSUME_OR(TOKEN_RPAREN, poisoned_ast); if (!parse_switch_body(context, &switch_ast->switch_stmt.cases, TOKEN_CASE, TOKEN_DEFAULT, false)) return poisoned_ast; @@ -396,12 +397,12 @@ static inline Ast* parse_for_stmt(Context *context) { Ast *ast = AST_NEW_TOKEN(AST_FOR_STMT, context->tok); advance_and_verify(context, TOKEN_FOR); - ast->for_stmt.flow.label = TRY_DECL_OR(parse_optional_label(context, ast), poisoned_ast); + ASSIGN_DECL_ELSE(ast->for_stmt.flow.label, parse_optional_label(context, ast), poisoned_ast); CONSUME_OR(TOKEN_LPAREN, poisoned_ast); if (!TOKEN_IS(TOKEN_EOS)) { - ast->for_stmt.init = TRY_EXPR_OR(parse_cond(context), poisoned_ast); + ASSIGN_EXPR_ELSE(ast->for_stmt.init, parse_cond(context), poisoned_ast); } else { @@ -412,7 +413,7 @@ static inline Ast* parse_for_stmt(Context *context) if (!TOKEN_IS(TOKEN_EOS)) { - ast->for_stmt.cond = TRY_EXPR_OR(parse_expr(context), poisoned_ast); + ASSIGN_EXPR_ELSE(ast->for_stmt.cond, parse_expr(context), poisoned_ast); } CONSUME_OR(TOKEN_EOS, poisoned_ast); @@ -425,7 +426,7 @@ static inline Ast* parse_for_stmt(Context *context) CONSUME_OR(TOKEN_RPAREN, poisoned_ast); extend_ast_with_prev_token(context, ast); - ast->for_stmt.body = TRY_AST(parse_stmt(context)); + ASSIGN_AST_ELSE(ast->for_stmt.body, parse_stmt(context), poisoned_ast); return ast; } @@ -438,7 +439,8 @@ static inline bool parse_foreach_var(Context *context, Ast *foreach) // If we don't get foreach (foo ... or foreach (*foo ... then a type is expected. if (!TOKEN_IS(TOKEN_IDENT) && !TOKEN_IS(TOKEN_AMP)) { - type = TRY_TYPE_OR(parse_type(context), false); + ASSIGN_TYPE_ELSE(type, parse_type(context), false); + failable = try_consume(context, TOKEN_BANG); // Add the failable to the type for nicer error reporting. RANGE_EXTEND_PREV(type); @@ -471,7 +473,7 @@ static inline Ast* parse_foreach_stmt(Context *context) { Ast *ast = AST_NEW_TOKEN(AST_FOREACH_STMT, context->tok); advance_and_verify(context, TOKEN_FOREACH); - ast->foreach_stmt.flow.label = TRY_DECL_OR(parse_optional_label(context, ast), poisoned_ast); + ASSIGN_DECL_ELSE(ast->foreach_stmt.flow.label, parse_optional_label(context, ast), poisoned_ast); CONSUME_OR(TOKEN_LPAREN, poisoned_ast); // Parse the first variable. @@ -491,12 +493,12 @@ static inline Ast* parse_foreach_stmt(Context *context) CONSUME_OR(TOKEN_COLON, poisoned_ast); - ast->foreach_stmt.enumeration = TRY_EXPR_OR(parse_initializer(context), poisoned_ast); + ASSIGN_EXPR_ELSE(ast->foreach_stmt.enumeration, parse_initializer(context), poisoned_ast); CONSUME_OR(TOKEN_RPAREN, poisoned_ast); extend_ast_with_prev_token(context, ast); - ast->foreach_stmt.body = TRY_AST(parse_stmt(context)); + ASSIGN_AST_ELSE(ast->foreach_stmt.body, parse_stmt(context), poisoned_ast); return ast; } @@ -567,7 +569,7 @@ static inline Ast* parse_break(Context *context) static inline Ast *parse_expr_stmt(Context *context) { Ast *stmt = AST_NEW_TOKEN(AST_EXPR_STMT, context->tok); - stmt->expr_stmt = TRY_EXPR_OR(parse_expr(context), poisoned_ast); + ASSIGN_EXPR_ELSE(stmt->expr_stmt, parse_expr(context), poisoned_ast); TRY_CONSUME_EOS(); return stmt; } @@ -576,7 +578,7 @@ static inline Ast *parse_expr_stmt(Context *context) static inline Ast *parse_decl_or_expr_stmt(Context *context) { - Expr *expr = TRY_EXPR_OR(parse_expr(context), poisoned_ast); + ASSIGN_EXPR_ELSE(Expr *expr, parse_expr(context), poisoned_ast); Ast *ast = ast_calloc(); ast->span = expr->span; bool failable = false; @@ -590,7 +592,7 @@ static inline Ast *parse_decl_or_expr_stmt(Context *context) if (expr->expr_kind == EXPR_TYPEINFO) { ast->ast_kind = AST_DECLARE_STMT; - ast->declare_stmt = TRY_DECL_OR(parse_decl_after_type(context, expr->type_expr), poisoned_ast); + ASSIGN_DECL_ELSE(ast->declare_stmt, parse_decl_after_type(context, expr->type_expr), poisoned_ast); ast->declare_stmt->var.failable = failable; } else @@ -621,7 +623,7 @@ static inline Ast *parse_var_stmt(Context *context) advance(context); if (try_consume(context, TOKEN_EQ)) { - decl->var.init_expr = TRY_EXPR_OR(parse_expr(context), poisoned_ast); + ASSIGN_EXPR_ELSE(decl->var.init_expr, parse_expr(context), poisoned_ast); } break; case TOKEN_CT_TYPE_IDENT: @@ -629,7 +631,7 @@ static inline Ast *parse_var_stmt(Context *context) advance(context); if (try_consume(context, TOKEN_EQ)) { - decl->var.type_info = TRY_TYPE_OR(parse_type(context), poisoned_ast); + ASSIGN_TYPE_ELSE(decl->var.type_info, parse_type(context), poisoned_ast); } break; default: @@ -651,7 +653,7 @@ static inline Ast* parse_ct_compound_stmt(Context *context) { TokenType token = context->tok.type; if (token == TOKEN_CT_ELSE || token == TOKEN_CT_ELIF || token == TOKEN_CT_ENDIF) break; - Ast *stmt = TRY_AST(parse_stmt(context)); + ASSIGN_AST_ELSE(Ast *stmt, parse_stmt(context), poisoned_ast); vec_add(stmts->ct_compound_stmt, stmt); RANGE_EXTEND_PREV(stmts); } @@ -667,7 +669,7 @@ static inline Ast* parse_ct_else_stmt(Context *context) Ast *ast = AST_NEW_TOKEN(AST_CT_ELSE_STMT, context->tok); advance_and_verify(context, TOKEN_CT_ELSE); TRY_CONSUME(TOKEN_COLON, "$else needs a ':', did you forget it?"); - ast->ct_else_stmt = TRY_AST(parse_ct_compound_stmt(context)); + ASSIGN_AST_ELSE(ast->ct_else_stmt, parse_ct_compound_stmt(context), poisoned_ast); return ast; } @@ -679,16 +681,17 @@ static inline Ast *parse_ct_elif_stmt(Context *context) { Ast *ast = AST_NEW_TOKEN(AST_CT_ELIF_STMT, context->tok); advance_and_verify(context, TOKEN_CT_ELIF); - ast->ct_elif_stmt.expr = TRY_EXPR_OR(parse_const_paren_expr(context), poisoned_ast); + ASSIGN_EXPR_ELSE(ast->ct_elif_stmt.expr, parse_const_paren_expr(context), poisoned_ast); TRY_CONSUME(TOKEN_COLON, "$elif needs a ':' after the expression, did you forget it?"); - ast->ct_elif_stmt.then = TRY_AST(parse_ct_compound_stmt(context)); + ASSIGN_AST_ELSE(ast->ct_elif_stmt.then, parse_ct_compound_stmt(context), poisoned_ast); + if (TOKEN_IS(TOKEN_CT_ELIF)) { - ast->ct_elif_stmt.elif = TRY_AST(parse_ct_elif_stmt(context)); + ASSIGN_AST_ELSE(ast->ct_elif_stmt.elif, parse_ct_elif_stmt(context), poisoned_ast); } else if (TOKEN_IS(TOKEN_CT_ELSE)) { - ast->ct_elif_stmt.elif = TRY_AST(parse_ct_else_stmt(context)); + ASSIGN_AST_ELSE(ast->ct_elif_stmt.elif, parse_ct_else_stmt(context), poisoned_ast); } return ast; } @@ -702,16 +705,17 @@ static inline Ast* parse_ct_if_stmt(Context *context) { Ast *ast = AST_NEW_TOKEN(AST_CT_IF_STMT, context->tok); advance_and_verify(context, TOKEN_CT_IF); - ast->ct_if_stmt.expr = TRY_EXPR_OR(parse_const_paren_expr(context), poisoned_ast); + ASSIGN_EXPR_ELSE(ast->ct_if_stmt.expr, parse_const_paren_expr(context), poisoned_ast); TRY_CONSUME(TOKEN_COLON, "$if needs a ':' after the expression, did you forget it?"); - ast->ct_if_stmt.then = TRY_AST(parse_ct_compound_stmt(context)); + ASSIGN_AST_ELSE(ast->ct_if_stmt.then, parse_ct_compound_stmt(context), poisoned_ast); + if (TOKEN_IS(TOKEN_CT_ELIF)) { - ast->ct_if_stmt.elif = TRY_AST(parse_ct_elif_stmt(context)); + ASSIGN_AST_ELSE(ast->ct_if_stmt.elif, parse_ct_elif_stmt(context), poisoned_ast); } else if (TOKEN_IS(TOKEN_CT_ELSE)) { - ast->ct_if_stmt.elif = TRY_AST(parse_ct_else_stmt(context)); + ASSIGN_AST_ELSE(ast->ct_if_stmt.elif, parse_ct_else_stmt(context), poisoned_ast); } advance_and_verify(context, TOKEN_CT_ENDIF); RANGE_EXTEND_PREV(ast); @@ -734,7 +738,7 @@ static inline Ast *parse_return(Context *context) ast->return_stmt.defer = 0; if (!TOKEN_IS(TOKEN_EOS)) { - ast->return_stmt.expr = TRY_EXPR_OR(parse_expr(context), poisoned_ast); + ASSIGN_EXPR_ELSE(ast->return_stmt.expr, parse_expr(context), poisoned_ast); } return ast; } @@ -748,7 +752,7 @@ static inline Ast *parse_return(Context *context) static Ast *parse_volatile_stmt(Context *context) { Ast *ast = AST_NEW_TOKEN(AST_VOLATILE_STMT, context->tok); - ast->volatile_stmt = TRY_AST_OR(parse_compound_stmt(context), poisoned_ast); + ASSIGN_AST_ELSE(ast->volatile_stmt, parse_compound_stmt(context), poisoned_ast); return ast; } @@ -777,9 +781,10 @@ static inline Ast* parse_ct_for_stmt(Context *context) ast->ct_for_stmt.value = context->tok.id; TRY_CONSUME_OR(TOKEN_CT_IDENT, "Expected a compile time variable", poisoned_ast); TRY_CONSUME_OR(TOKEN_COLON, "Expected ':'.", poisoned_ast); - ast->ct_for_stmt.expr = TRY_EXPR_OR(parse_expr(context), poisoned_ast); + ASSIGN_EXPR_ELSE(ast->ct_for_stmt.expr, parse_expr(context), poisoned_ast); CONSUME_OR(TOKEN_RPAREN, poisoned_ast); - ast->ct_for_stmt.body = TRY_AST(parse_stmt(context)); + ASSIGN_AST_ELSE(ast->ct_for_stmt.body, parse_stmt(context), poisoned_ast); + return ast; } @@ -802,7 +807,7 @@ static inline Ast* parse_ct_switch_stmt(Context *context) { Ast *ast = AST_NEW_TOKEN(AST_CT_SWITCH_STMT, context->tok); advance_and_verify(context, TOKEN_CT_SWITCH); - ast->ct_switch_stmt.cond = TRY_EXPR_OR(parse_const_paren_expr(context), poisoned_ast); + ASSIGN_EXPR_ELSE(ast->ct_switch_stmt.cond, parse_const_paren_expr(context), poisoned_ast); TRY_CONSUME(TOKEN_COLON, "Expected ':' after $switch expression, did you forget it?"); Ast **cases = NULL; while (!try_consume(context, TOKEN_CT_ENDSWITCH)) @@ -811,11 +816,11 @@ static inline Ast* parse_ct_switch_stmt(Context *context) TokenType next = context->tok.type; if (next == TOKEN_CT_CASE) { - result = TRY_AST_OR(parse_case_stmt(context, TOKEN_CT_CASE, TOKEN_CT_DEFAULT), poisoned_ast); + ASSIGN_AST_ELSE(result, parse_case_stmt(context, TOKEN_CT_CASE, TOKEN_CT_DEFAULT), poisoned_ast); } else if (next == TOKEN_CT_DEFAULT) { - result = TRY_AST_OR(parse_default_stmt(context, TOKEN_CT_CASE, TOKEN_CT_DEFAULT), poisoned_ast); + ASSIGN_AST_ELSE(result, parse_default_stmt(context, TOKEN_CT_CASE, TOKEN_CT_DEFAULT), poisoned_ast); } else { @@ -834,10 +839,11 @@ static inline Ast *parse_assert_stmt(Context *context) Ast *ast = AST_NEW_TOKEN(AST_ASSERT_STMT, context->tok); advance_and_verify(context, TOKEN_ASSERT); TRY_CONSUME_OR(TOKEN_LPAREN, "'assert' needs a '(' here, did you forget it?", poisoned_ast); - ast->assert_stmt.expr = TRY_EXPR_OR(parse_assert_expr(context), poisoned_ast); + ASSIGN_EXPR_ELSE(ast->assert_stmt.expr, parse_assert_expr(context), poisoned_ast); + if (try_consume(context, TOKEN_COMMA)) { - ast->assert_stmt.message = TRY_EXPR_OR(parse_expr(context), poisoned_ast); + ASSIGN_EXPR_ELSE(ast->assert_stmt.message, parse_expr(context), poisoned_ast); } TRY_CONSUME_OR(TOKEN_RPAREN, "The ending ')' was expected here.", poisoned_ast); TRY_CONSUME_EOS(); @@ -856,10 +862,11 @@ Ast *parse_ct_assert_stmt(Context *context) Ast *ast = AST_NEW_TOKEN(AST_CT_ASSERT, context->tok); advance_and_verify(context, TOKEN_CT_ASSERT); TRY_CONSUME_OR(TOKEN_LPAREN, "'$assert' needs a '(' here, did you forget it?", poisoned_ast); - ast->ct_assert_stmt.expr = TRY_EXPR_OR(parse_constant_expr(context), poisoned_ast); + ASSIGN_EXPR_ELSE(ast->ct_assert_stmt.expr, parse_constant_expr(context), poisoned_ast); + if (try_consume(context, TOKEN_COMMA)) { - ast->ct_assert_stmt.message = TRY_EXPR_OR(parse_constant_expr(context), poisoned_ast); + ASSIGN_EXPR_ELSE(ast->ct_assert_stmt.message, parse_constant_expr(context), poisoned_ast); } TRY_CONSUME_OR(TOKEN_RPAREN, "The ending ')' was expected here.", poisoned_ast); TRY_CONSUME_EOS(); @@ -892,7 +899,7 @@ Ast *parse_stmt(Context *context) return parse_expr_stmt(context); case TOKEN_RETURN: { - Ast *ast = TRY_AST(parse_return(context)); + ASSIGN_AST_ELSE(Ast *ast, parse_return(context), poisoned_ast); RETURN_AFTER_EOS(ast); } case TOKEN_IF: @@ -911,7 +918,7 @@ Ast *parse_stmt(Context *context) return parse_foreach_stmt(context); case TOKEN_CONTINUE: { - Ast *ast = TRY_AST(parse_continue(context)); + ASSIGN_AST_ELSE(Ast *ast, parse_continue(context), poisoned_ast); RETURN_AFTER_EOS(ast); } case TOKEN_CASE: @@ -920,12 +927,12 @@ Ast *parse_stmt(Context *context) return poisoned_ast; case TOKEN_BREAK: { - Ast *ast = TRY_AST(parse_break(context)); + ASSIGN_AST_ELSE(Ast *ast, parse_break(context), poisoned_ast); RETURN_AFTER_EOS(ast); } case TOKEN_NEXTCASE: { - Ast *ast = TRY_AST(parse_next(context)); + ASSIGN_AST_ELSE(Ast *ast, parse_next(context), poisoned_ast); RETURN_AFTER_EOS(ast); } case TOKEN_ASM: @@ -1117,7 +1124,7 @@ Ast* parse_compound_stmt(Context *context) Ast *ast = AST_NEW_TOKEN(AST_COMPOUND_STMT, context->tok); while (!try_consume(context, TOKEN_RBRACE)) { - Ast *stmt = TRY_AST(parse_stmt(context)); + ASSIGN_AST_ELSE(Ast *stmt, parse_stmt(context), poisoned_ast); vec_add(ast->compound_stmt.stmts, stmt); } return ast; diff --git a/src/compiler/parser_internal.h b/src/compiler/parser_internal.h index 5f7a724f3..7b1a9fad8 100644 --- a/src/compiler/parser_internal.h +++ b/src/compiler/parser_internal.h @@ -15,7 +15,6 @@ #define TRY_CONSUME_EOS() TRY_CONSUME_EOS_OR(poisoned_ast) #define RETURN_AFTER_EOS(_ast) extend_ast_with_prev_token(context, ast); TRY_CONSUME_EOS_OR(poisoned_ast); return _ast -#define TRY_AST(_ast_stmt) TRY_AST_OR(_ast_stmt, poisoned_ast) #define CHECK_EXPR(_expr) do { if (!expr_ok(_expr)) return _expr; } while(0) @@ -122,7 +121,7 @@ static inline bool expect_ident(Context *context, const char* name) static inline Expr *parse_const_paren_expr(Context *context) { CONSUME_OR(TOKEN_LPAREN, poisoned_expr); - Expr *expr = TRY_EXPR_OR(parse_constant_expr(context), poisoned_expr); + ASSIGN_EXPR_ELSE(Expr *expr, parse_constant_expr(context), poisoned_expr); CONSUME_OR(TOKEN_RPAREN, poisoned_expr); return expr; } diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 9e2405818..0d91dd372 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -5461,7 +5461,7 @@ static inline bool sema_analyse_identifier_path_string(Context *context, SourceS } else { - decl = TRY_DECL_OR(sema_resolve_string_symbol(context, symbol, expr->span, path, report_missing), report_missing); + ASSIGN_DECL_ELSE(decl, sema_resolve_string_symbol(context, symbol, expr->span, path, report_missing), false); if (!decl) return true; if (!sema_analyse_decl(context, decl)) return false; if (decl->decl_kind == DECL_TYPEDEF) @@ -5775,8 +5775,10 @@ static inline bool sema_expr_resolve_maybe_identifier(Context *c, Expr *expr, De { case EXPR_CONST_IDENTIFIER: case EXPR_IDENTIFIER: - *decl_ref = TRY_DECL_OR(sema_resolve_normal_symbol(c, expr->identifier_expr.identifier, expr->identifier_expr.path, false), false); + { + ASSIGN_DECL_ELSE(*decl_ref, sema_resolve_normal_symbol(c, expr->identifier_expr.identifier, expr->identifier_expr.path, false), false); return true; + } case EXPR_TYPEINFO: if (expr->resolve_status == RESOLVE_DONE) { @@ -5788,10 +5790,8 @@ static inline bool sema_expr_resolve_maybe_identifier(Context *c, Expr *expr, De SEMA_ERROR(expr, "Expected a plain type name here."); return false; } - *decl_ref = TRY_DECL_OR(sema_resolve_normal_symbol(c, - expr->type_expr->unresolved.name_loc, - expr->type_expr->unresolved.path, - false), false); + ASSIGN_DECL_ELSE(*decl_ref, sema_resolve_normal_symbol(c, expr->type_expr->unresolved.name_loc, + expr->type_expr->unresolved.path, false), false); return true; case EXPR_CONST: switch (expr->const_expr.const_kind)