diff --git a/resources/testfragments/super_simple.c3 b/resources/testfragments/super_simple.c3 index 7655192e6..9f8d45982 100644 --- a/resources/testfragments/super_simple.c3 +++ b/resources/testfragments/super_simple.c3 @@ -117,6 +117,12 @@ union SimpleUnion double f; } +func void testPointer() +{ + int i = 0; + int *x = &i; + int y = x[2]; +} func void testUnion() { int wdw = 123; @@ -130,6 +136,12 @@ func void testUnion() s = { f = 1.0 }; TestUnion tu = { e = TestStruct2 { c = 1 } }; tu.e = TestStruct2 { c = 1 }; + + + SimpleUnion y = s = { 2 }; + double yval = SimpleUnion{ f = 3.333 }.f; + printf("Union y: %d\n", y.a); + printf("Union simple: %f\n", yval); } func TestStruct2 structTest(int i) @@ -308,7 +320,8 @@ struct AnonStruct func AnonStruct sendAnonStruct() { - AnonStruct foo = Foo { a = 1 }; + AnonStruct foo = AnonStruct { a = 1 }; + // Foo { a = 1 } foo.b2 = 123; return foo; } @@ -677,6 +690,7 @@ func int main(int x) testArray(); testAnonStruct(); testSimpleStruct(0); + testUnion(); int efd = 9; uint fefoek = 1; printf("Helo: %d\n", efd + cast(fefoek, int)); diff --git a/src/compiler/ast.c b/src/compiler/ast.c index 151a4fc7a..8ef766360 100644 --- a/src/compiler/ast.c +++ b/src/compiler/ast.c @@ -18,9 +18,10 @@ Decl *decl_new(DeclKind decl_kind, Token name, Visibility visibility) } -Type poisoned_type = { .type_kind = TYPE_POISONED }; - -TypeInfo poisoned_type_info = { .kind = TYPE_INFO_POISON }; +static Type poison_type = { .type_kind = TYPE_POISONED }; +static TypeInfo poison_type_info = { .kind = TYPE_INFO_POISON }; +Type *poisoned_type = &poison_type; +TypeInfo *poisoned_type_info = &poison_type_info; void decl_set_external_name(Decl *decl) { @@ -100,7 +101,8 @@ const char *decl_var_to_string(VarDeclKind kind) UNREACHABLE } -Decl poisoned_decl = { .decl_kind = DECL_POISONED, .resolve_status = RESOLVE_DONE }; +static Decl poison_decl = { .decl_kind = DECL_POISONED, .resolve_status = RESOLVE_DONE }; +Decl *poisoned_decl = &poison_decl; Decl *decl_new_var(Token name, TypeInfo *type, VarDeclKind kind, Visibility visibility) { @@ -132,7 +134,7 @@ Decl *struct_find_name(Decl *decl, const char* name) Ast *ast_from_expr(Expr *expr) { - if (!expr_ok(expr)) return &poisoned_ast; + if (!expr_ok(expr)) return poisoned_ast; Ast *ast = AST_NEW(AST_EXPR_STMT, expr->span); ast->expr_stmt = expr; return ast; @@ -147,9 +149,8 @@ Expr *expr_new(ExprKind kind, SourceRange start) return expr; } -Expr poisoned_expr = { .expr_kind = EXPR_POISONED, .resolve_status = RESOLVE_DONE }; - - +static Expr poison_expr = { .expr_kind = EXPR_POISONED, .resolve_status = RESOLVE_DONE }; +Expr *poisoned_expr = &poison_expr; Type* type_int_max_type(bool is_signed) { @@ -303,7 +304,8 @@ TokenType postunaryop_to_token(PostUnaryOp type) return TOKEN_INVALID_TOKEN; } -Ast poisoned_ast = { .ast_kind = AST_POISONED }; +static Ast poison_ast = { .ast_kind = AST_POISONED }; +Ast *poisoned_ast = &poison_ast; void fprint_indent(FILE *file, int indent) { diff --git a/src/compiler/compiler.c b/src/compiler/compiler.c index 02304d28c..b90c9d4f5 100644 --- a/src/compiler/compiler.c +++ b/src/compiler/compiler.c @@ -219,7 +219,7 @@ void compiler_register_public_symbol(Decl *decl) { Decl *prev = stable_get(&compiler.global_symbols, decl->name); // If the previous symbol was already declared globally, remove it. - stable_set(&compiler.global_symbols, decl->name, prev ? &poisoned_decl : decl); + stable_set(&compiler.global_symbols, decl->name, prev ? poisoned_decl : decl); STable *sub_module_space = stable_get(&compiler.qualified_symbols, decl->module->name->module); if (!sub_module_space) { @@ -228,5 +228,5 @@ void compiler_register_public_symbol(Decl *decl) stable_set(&compiler.qualified_symbols, decl->module->name->module, sub_module_space); } prev = stable_get(sub_module_space, decl->name); - stable_set(sub_module_space, decl->name, prev ? &poisoned_decl : decl); + stable_set(sub_module_space, decl->name, prev ? poisoned_decl : decl); } diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index 46f494ab8..66ba84f89 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -553,6 +553,12 @@ typedef struct Expr** initializer_expr; } ExprInitializer; +typedef struct +{ + Expr *initializer; + TypeInfo *type_info; +} ExprCompoundLiteral; + typedef struct { DesignatedPath *path; @@ -585,6 +591,7 @@ struct _Expr ExprIdentifier identifier_expr; ExprType type_expr; ExprInitializer expr_initializer; + ExprCompoundLiteral expr_compound_literal; Expr** expression_list; ExprScope expr_scope; ExprFuncBlock expr_block; @@ -931,11 +938,11 @@ typedef struct } Compiler; extern Compiler compiler; -extern Ast poisoned_ast; -extern Decl poisoned_decl; -extern Expr poisoned_expr; -extern Type poisoned_type; -extern TypeInfo poisoned_type_info; +extern Ast *poisoned_ast; +extern Decl *poisoned_decl; +extern Expr *poisoned_expr; +extern Type *poisoned_type; +extern TypeInfo *poisoned_type_info; extern Module poisoned_module; extern Diagnostics diagnostics; @@ -1260,7 +1267,7 @@ static inline bool type_is_unsigned_integer(Type *type) static inline bool type_info_poison(TypeInfo *type) { - type->type = &poisoned_type; + type->type = poisoned_type; type->resolve_status = RESOLVE_DONE; return false; } diff --git a/src/compiler/enums.h b/src/compiler/enums.h index 18ed3794f..31d5a660a 100644 --- a/src/compiler/enums.h +++ b/src/compiler/enums.h @@ -232,6 +232,7 @@ typedef enum EXPR_EXPR_BLOCK, EXPR_RANGE, EXPR_DESIGNATED_INITIALIZER, + EXPR_COMPOUND_LITERAL, } ExprKind; diff --git a/src/compiler/llvm_codegen_expr.c b/src/compiler/llvm_codegen_expr.c index 0f19e8231..98a925b6f 100644 --- a/src/compiler/llvm_codegen_expr.c +++ b/src/compiler/llvm_codegen_expr.c @@ -71,51 +71,20 @@ static inline LLVMValueRef gencontext_emit_sub_int(GenContext *context, Type *ty ? LLVMBuildNUWSub(context->builder, left, right, "usub") : LLVMBuildNSWSub(context->builder, left, right, "sub"); } -static inline LLVMValueRef gencontext_emit_subscript_addr_from_value(GenContext *context, LLVMValueRef parent, Type *parent_type, Expr *index_expr) -{ - assert(parent_type->canonical == parent_type); - LLVMValueRef index = gencontext_emit_expr(context, index_expr); - switch (parent_type->type_kind) - { - case TYPE_POINTER: - return LLVMBuildGEP2(context->builder, - llvm_type(parent_type->pointer), - parent, &index, 1, "[]"); - case TYPE_ARRAY: - // TODO insert trap on overflow. - { - LLVMValueRef zero = LLVMConstInt(llvm_type(type_int), 0, false); - LLVMValueRef indices[2] = { - zero, - index, - }; - return LLVMBuildInBoundsGEP2(context->builder, - llvm_type(parent_type), - parent, indices, 2, "[x]"); - - } - case TYPE_VARARRAY: - case TYPE_SUBARRAY: - case TYPE_STRING: - TODO - default: - UNREACHABLE - } - -} static inline LLVMValueRef gencontext_emit_subscript_addr(GenContext *context, Expr *expr) { Expr *parent = expr->subscript_expr.expr; Expr *index = expr->subscript_expr.index; LLVMValueRef index_value = gencontext_emit_expr(context, index); LLVMValueRef parent_value; - switch (parent->type->canonical->type_kind) + Type *type = parent->type->canonical; + switch (type->type_kind) { case TYPE_POINTER: parent_value = gencontext_emit_expr(context, expr->subscript_expr.expr); - return LLVMBuildGEP2(context->builder, - llvm_type(parent->type->canonical), - parent_value, &index_value, 1, "[]"); + return LLVMBuildInBoundsGEP2(context->builder, + llvm_type(type->pointer), + parent_value, &index_value, 1, "ptridx"); case TYPE_ARRAY: { // TODO insert trap on overflow. @@ -126,8 +95,8 @@ static inline LLVMValueRef gencontext_emit_subscript_addr(GenContext *context, E }; parent_value = gencontext_emit_address(context, expr->subscript_expr.expr); return LLVMBuildInBoundsGEP2(context->builder, - llvm_type(parent->type), - parent_value, indices, 2, "[x]"); + llvm_type(type), + parent_value, indices, 2, "arridx"); } case TYPE_VARARRAY: case TYPE_SUBARRAY: @@ -190,6 +159,8 @@ LLVMValueRef gencontext_emit_scoped_expr_address(GenContext *context, Expr *expr return value; } +static inline LLVMValueRef gencontext_emit_initializer_list_expr_addr(GenContext *context, Expr *expr, LLVMValueRef optional_ref); + LLVMValueRef gencontext_emit_address(GenContext *context, Expr *expr) { switch (expr->expr_kind) @@ -206,6 +177,8 @@ LLVMValueRef gencontext_emit_address(GenContext *context, Expr *expr) case EXPR_UNARY: assert(expr->unary_expr.operator == UNARYOP_DEREF); return gencontext_emit_expr(context, expr->unary_expr.expr); + case EXPR_COMPOUND_LITERAL: + return gencontext_emit_initializer_list_expr_addr(context, expr->expr_compound_literal.initializer, NULL); case EXPR_ACCESS: return gencontext_emit_access_addr(context, expr); case EXPR_SUBSCRIPT: @@ -308,7 +281,7 @@ static inline LLVMValueRef gencontext_emit_cast_expr(GenContext *context, Expr * * Improve: Direct assign in the case where this is assigning to a variable. * Improve: Create constant initializer for the constant case and do a memcopy */ -static inline LLVMValueRef gencontext_emit_initializer_list_expr(GenContext *context, Expr *expr, LLVMValueRef optional_ref) +static inline LLVMValueRef gencontext_emit_initializer_list_expr_addr(GenContext *context, Expr *expr, LLVMValueRef optional_ref) { LLVMTypeRef type = llvm_type(expr->type); LLVMValueRef ref = optional_ref ?: gencontext_emit_alloca(context, type, "literal"); @@ -321,7 +294,7 @@ static inline LLVMValueRef gencontext_emit_initializer_list_expr(GenContext *co if (expr->expr_initializer.init_type == INITIALIZER_ZERO) { - return LLVMBuildLoad2(context->builder, type, ref, ""); + return ref; } Expr **elements = expr->expr_initializer.initializer_expr; @@ -335,7 +308,7 @@ static inline LLVMValueRef gencontext_emit_initializer_list_expr(GenContext *co LLVMValueRef init_value = gencontext_emit_expr(context, elements[0]); LLVMValueRef u = LLVMBuildBitCast(context->builder, ref, LLVMPointerType(llvm_type(elements[0]->type->canonical), 0), ""); LLVMBuildStore(context->builder, init_value, u); - return LLVMBuildLoad2(context->builder, type, ref, ""); + return ref; } VECEACH(elements, i) { @@ -344,7 +317,7 @@ static inline LLVMValueRef gencontext_emit_initializer_list_expr(GenContext *co LLVMValueRef subref = LLVMBuildStructGEP2(context->builder, type, ref, i, ""); LLVMBuildStore(context->builder, init_value, subref); } - return LLVMBuildLoad2(context->builder, type, ref, ""); + return ref; } VECEACH(elements, i) @@ -379,7 +352,7 @@ static inline LLVMValueRef gencontext_emit_initializer_list_expr(GenContext *co }; sub_ref = LLVMBuildInBoundsGEP2(context->builder, llvm_type(parent_type), - sub_ref, indices, 2, "[x]"); + sub_ref, indices, 2, "arrsub"); break; } default: @@ -391,19 +364,20 @@ static inline LLVMValueRef gencontext_emit_initializer_list_expr(GenContext *co } LLVMBuildStore(context->builder, sub_value, sub_ref); } - return LLVMBuildLoad2(context->builder, type, ref, ""); + return ref; } static inline LLVMValueRef gencontext_emit_inc_dec_change(GenContext *context, bool use_mod, LLVMValueRef current_value, Expr *expr, int diff) { Type *type = type_reduced_from_expr(expr); - LLVMTypeRef llvm_type = llvm_type(type); + if (type->type_kind == TYPE_POINTER) { LLVMValueRef add = LLVMConstInt(diff < 0 ? llvm_type(type_isize) : llvm_type(type_usize), diff, diff < 0); - return LLVMBuildGEP2(context->builder, llvm_type, current_value, &add, 1, "ptrincdec"); + return LLVMBuildGEP2(context->builder, llvm_type(type->pointer), current_value, &add, 1, "ptrincdec"); } + LLVMTypeRef llvm_type = llvm_type(type); if (type_is_float(type)) { @@ -420,7 +394,7 @@ static inline LLVMValueRef gencontext_emit_inc_dec_change(GenContext *context, b static inline LLVMValueRef gencontext_emit_pre_inc_dec(GenContext *context, Expr *expr, int diff, bool use_mod) { LLVMValueRef addr = gencontext_emit_address(context, expr); - LLVMValueRef value = LLVMBuildLoad2(context->builder, llvm_type(expr->type), addr, ""); + LLVMValueRef value = gencontext_emit_load(context, expr->type, addr); LLVMValueRef result = gencontext_emit_inc_dec_change(context, use_mod, value, expr, diff); LLVMBuildStore(context->builder, result, addr); return result; @@ -429,7 +403,7 @@ static inline LLVMValueRef gencontext_emit_pre_inc_dec(GenContext *context, Expr static inline LLVMValueRef gencontext_emit_post_inc_dec(GenContext *context, Expr *expr, int diff, bool use_mod) { LLVMValueRef addr = gencontext_emit_address(context, expr); - LLVMValueRef value = LLVMBuildLoad2(context->builder, llvm_type(expr->type), addr, ""); + LLVMValueRef value = gencontext_emit_load(context, expr->type, addr); LLVMValueRef result = gencontext_emit_inc_dec_change(context, use_mod, value, expr, diff); LLVMBuildStore(context->builder, result, addr); return value; @@ -473,7 +447,7 @@ LLVMValueRef gencontext_emit_unary_expr(GenContext *context, Expr *expr) case UNARYOP_ADDR: return gencontext_emit_address(context, expr->unary_expr.expr); case UNARYOP_DEREF: - return LLVMBuildLoad2(context->builder, llvm_type(type), gencontext_emit_expr(context, expr->unary_expr.expr), "deref"); + return gencontext_emit_load(context, expr->type, gencontext_emit_expr(context, expr->unary_expr.expr)); case UNARYOP_INC: return gencontext_emit_pre_inc_dec(context, expr->unary_expr.expr, 1, false); case UNARYOP_DEC: @@ -523,18 +497,6 @@ static LLVMValueRef gencontext_emit_logical_and_or(GenContext *context, Expr *ex return phi; } -static inline LLVMValueRef gencontext_emit_initialization_from_expr(GenContext *context, LLVMValueRef strukt, Expr *expr) -{ - assert(expr->expr_kind == EXPR_INITIALIZER_LIST); - // TODO - return strukt; -} - -static inline LLVMValueRef gencontext_emit_struct_value_expr(GenContext *context, Expr *expr) -{ - LLVMValueRef temp_alloc = gencontext_emit_alloca(context, llvm_type(expr->type), "temp"); - return gencontext_emit_initialization_from_expr(context, temp_alloc, expr->struct_value_expr.init_expr); -} static LLVMValueRef gencontext_emit_int_comparison(GenContext *context, Type *lhs_type, Type *rhs_type, LLVMValueRef lhs_value, LLVMValueRef rhs_value, BinaryOp binary_op) @@ -674,7 +636,7 @@ static LLVMValueRef gencontext_emit_binary(GenContext *context, Expr *expr, LLVM LLVMValueRef rhs_value; if (lhs_addr) { - lhs_value = LLVMBuildLoad2(context->builder, llvm_type(lhs->type), lhs_addr, ""); + lhs_value = gencontext_emit_load(context, lhs->type, lhs_addr); } else { @@ -729,7 +691,7 @@ static LLVMValueRef gencontext_emit_binary(GenContext *context, Expr *expr, LLVM { if (lhs->type->canonical == rhs->type->canonical) return LLVMBuildPtrDiff(context->builder, lhs_value, rhs_value, "ptrdiff"); rhs_value = LLVMBuildNeg(context->builder, rhs_value, ""); - return LLVMBuildGEP2(context->builder, llvm_type(lhs->type), lhs_value, &rhs_value, 1, "ptrsub"); + return LLVMBuildGEP2(context->builder, llvm_type(lhs_type->canonical->pointer), lhs_value, &rhs_value, 1, "ptrsub"); } if (is_float) return LLVMBuildFSub(context->builder, lhs_value, rhs_value, "fsub"); return gencontext_emit_sub_int(context, lhs->type->canonical, binary_op == BINARYOP_SUB_MOD, lhs_value, rhs_value); @@ -738,7 +700,7 @@ static LLVMValueRef gencontext_emit_binary(GenContext *context, Expr *expr, LLVM if (lhs_type->type_kind == TYPE_POINTER) { assert(type_is_integer(rhs->type->canonical)); - return LLVMBuildGEP2(context->builder, llvm_type(lhs_type), lhs_value, &rhs_value, 1, "ptradd"); + return LLVMBuildGEP2(context->builder, llvm_type(lhs_type->canonical->pointer), lhs_value, &rhs_value, 1, "ptradd"); } if (is_float) return LLVMBuildFAdd(context->builder, lhs_value, rhs_value, "fadd"); return gencontext_emit_add_int(context, lhs_type, binary_op == BINARYOP_ADD_MOD, lhs_value, rhs_value); @@ -826,7 +788,7 @@ LLVMValueRef gencontext_emit_try_expr(GenContext *context, Expr *expr) LLVMBuildStore(context->builder, catch_value, res); gencontext_emit_br(context, after_catch); gencontext_emit_block(context, after_catch); - return LLVMBuildLoad2(context->builder, llvm_type(expr->try_expr.else_expr->type), res, ""); + return gencontext_emit_load(context, expr->try_expr.else_expr->type, res); } TODO } @@ -1013,7 +975,7 @@ LLVMValueRef gencontext_emit_call_expr(GenContext *context, Expr *expr) { if (error_param) { - LLVMValueRef maybe_error = LLVMBuildLoad2(context->builder, llvm_type(type_error_union), error_param, ""); + LLVMValueRef maybe_error = gencontext_emit_load(context, type_error_union, error_param); TODO // Incorrect, must get subset if this is 128 bits gencontext_emit_throw_branch(context, maybe_error); } @@ -1025,7 +987,7 @@ LLVMValueRef gencontext_emit_call_expr(GenContext *context, Expr *expr) // If we used a return param, then load that info here. if (return_param) { - call = LLVMBuildLoad2(context->builder, llvm_type(signature->rtype->type), return_param, ""); + call = gencontext_emit_load(context, signature->rtype->type, return_param); } /* if (function->func.function_signature.convention) @@ -1093,7 +1055,9 @@ LLVMValueRef gencontext_emit_assign_expr(GenContext *context, LLVMValueRef ref, switch (expr->expr_kind) { case EXPR_INITIALIZER_LIST: - return gencontext_emit_initializer_list_expr(context, expr, ref); + return gencontext_emit_load(context, + expr->type, + gencontext_emit_initializer_list_expr_addr(context, expr, ref)); default: break; } @@ -1114,6 +1078,12 @@ LLVMValueRef gencontext_emit_expr(GenContext *context, Expr *expr) case EXPR_DESIGNATED_INITIALIZER: // Should only appear when generating designated initializers. UNREACHABLE + case EXPR_COMPOUND_LITERAL: + return gencontext_emit_load(context, + expr->type, + gencontext_emit_initializer_list_expr_addr(context, + expr->expr_compound_literal.initializer, + NULL)); case EXPR_EXPR_BLOCK: return gencontext_emit_expr_block(context, expr); case EXPR_SCOPED_EXPR: @@ -1139,13 +1109,15 @@ LLVMValueRef gencontext_emit_expr(GenContext *context, Expr *expr) case EXPR_IDENTIFIER: case EXPR_SUBSCRIPT: case EXPR_ACCESS: - return gencontext_load_expr(context, gencontext_emit_address(context, expr)); + return gencontext_emit_load(context, expr->type, gencontext_emit_address(context, expr)); case EXPR_CALL: return gencontext_emit_call_expr(context, expr); case EXPR_GROUP: return gencontext_emit_expr(context, expr->group_expr); case EXPR_INITIALIZER_LIST: - return gencontext_emit_initializer_list_expr(context, expr, NULL); + return gencontext_emit_load(context, + expr->type, + gencontext_emit_initializer_list_expr_addr(context, expr, NULL)); case EXPR_EXPRESSION_LIST: return gencontext_emit_expression_list_expr(context, expr); case EXPR_CAST: diff --git a/src/compiler/llvm_codegen_internal.h b/src/compiler/llvm_codegen_internal.h index 5a3171ae3..a8cc9d058 100644 --- a/src/compiler/llvm_codegen_internal.h +++ b/src/compiler/llvm_codegen_internal.h @@ -139,11 +139,13 @@ void gencontext_emit_implicit_return(GenContext *context); void gencontext_emit_function_decl(GenContext *context, Decl *decl); void gencontext_emit_extern_decl(GenContext *context, Decl *decl); LLVMValueRef gencontext_emit_address(GenContext *context, Expr *expr); -static inline LLVMValueRef gencontext_load_expr(GenContext *context, LLVMValueRef value) -{ - return LLVMBuildLoad(context->builder, value, ""); -} LLVMTypeRef gencontext_get_llvm_type(GenContext *context, Type *type); +static inline LLVMValueRef gencontext_emit_load(GenContext *context, Type *type, LLVMValueRef value) +{ + assert(gencontext_get_llvm_type(context, type) == LLVMGetElementType(LLVMTypeOf(value))); + return LLVMBuildLoad2(context->builder, gencontext_get_llvm_type(context, type), value, ""); +} + LLVMValueRef gencontext_emit_cast(GenContext *context, CastKind cast_kind, LLVMValueRef value, Type *type, Type *target_type); static inline bool gencontext_func_pass_return_by_param(GenContext *context, Type *first_param_type) { return false; }; static inline bool gencontext_func_pass_param_by_reference(GenContext *context, Type *param_type) { return false; } diff --git a/src/compiler/llvm_codegen_stmt.c b/src/compiler/llvm_codegen_stmt.c index c08b152f2..6a3df4b2e 100644 --- a/src/compiler/llvm_codegen_stmt.c +++ b/src/compiler/llvm_codegen_stmt.c @@ -77,7 +77,7 @@ LLVMValueRef gencontext_emit_decl_expr_list(GenContext *context, Ast *ast, bool break; case AST_DECLARE_STMT: type = last->declare_stmt->var.type_info->type; - result = gencontext_load_expr(context, gencontext_emit_decl(context, last)); + result = gencontext_emit_load(context, type, gencontext_emit_decl(context, last)); break; default: UNREACHABLE @@ -539,7 +539,7 @@ void gencontext_emit_defer(GenContext *context, Ast *defer_start, Ast *defer_end LLVMBasicBlockRef exit_block = LLVMCreateBasicBlockInContext(context->context, "skip.defer"); LLVMBasicBlockRef defer_block = LLVMCreateBasicBlockInContext(context->context, "do.defer"); - LLVMValueRef value = LLVMBuildLoad2(context->builder, llvm_type(type_bool), gencontext_get_defer_bool(context, defer), "will.defer"); + LLVMValueRef value = gencontext_emit_load(context, type_bool, gencontext_get_defer_bool(context, defer)); gencontext_emit_cond_br(context, value, defer_block, exit_block); diff --git a/src/compiler/llvm_codegen_type.c b/src/compiler/llvm_codegen_type.c index 3f2aa4bbf..1b7e8c1f3 100644 --- a/src/compiler/llvm_codegen_type.c +++ b/src/compiler/llvm_codegen_type.c @@ -168,11 +168,12 @@ LLVMTypeRef llvm_get_type(LLVMContextRef context, Type *type) { case TYPE_POISONED: case TYPE_META_TYPE: - case TYPE_ENUM: case TYPE_ERROR: UNREACHABLE; case TYPE_TYPEDEF: return type->backend_type = llvm_get_type(context, type->canonical); + case TYPE_ENUM: + return type->backend_type = llvm_get_type(context, type->decl->enums.type_info->type->canonical); case TYPE_ERROR_UNION: { LLVMTypeRef types[2]; diff --git a/src/compiler/parse_expr.c b/src/compiler/parse_expr.c index f617a0af0..9042a4b00 100644 --- a/src/compiler/parse_expr.c +++ b/src/compiler/parse_expr.c @@ -37,7 +37,7 @@ static Expr *parse_precedence(Context *context, Precedence precedence) if (prefix_rule == NULL) { SEMA_TOKEN_ERROR(context->tok, "An expression was expected."); - return &poisoned_expr; + return poisoned_expr; } Expr *left_side = prefix_rule(context, NULL); @@ -113,7 +113,7 @@ static Expr *parse_macro_expr(Context *context, Expr *left) assert(!left && "Unexpected left hand side"); Expr *macro_expr = EXPR_NEW_TOKEN(EXPR_MACRO_EXPR, context->tok); advance_and_verify(context, TOKEN_AT); - macro_expr->macro_expr = TRY_EXPR_OR(parse_precedence(context, PREC_UNARY + 1), &poisoned_expr); + macro_expr->macro_expr = TRY_EXPR_OR(parse_precedence(context, PREC_UNARY + 1), poisoned_expr); return macro_expr; } @@ -133,7 +133,7 @@ static inline Expr* parse_non_assign_expr(Context *context) Expr *parse_expression_list(Context *context) { Expr *expr_list = EXPR_NEW_TOKEN(EXPR_EXPRESSION_LIST, context->tok); - if (!parse_param_list(context, &expr_list->expression_list, false)) return &poisoned_expr; + if (!parse_param_list(context, &expr_list->expression_list, false)) return poisoned_expr; return expr_list; } @@ -151,11 +151,11 @@ static Expr *parse_cast_expr(Context *context, Expr *left) assert(!left && "Unexpected left hand side"); Expr *expr = EXPR_NEW_TOKEN(EXPR_CAST, context->tok); advance_and_verify(context, TOKEN_CAST); - CONSUME_OR(TOKEN_LPAREN, &poisoned_expr); - expr->cast_expr.expr = TRY_EXPR_OR(parse_expr(context), &poisoned_expr); - CONSUME_OR(TOKEN_COMMA, &poisoned_expr); - expr->cast_expr.type_info = TRY_TYPE_OR(parse_type_expression(context), &poisoned_expr); - CONSUME_OR(TOKEN_RPAREN, &poisoned_expr); + CONSUME_OR(TOKEN_LPAREN, poisoned_expr); + expr->cast_expr.expr = TRY_EXPR_OR(parse_expr(context), poisoned_expr); + CONSUME_OR(TOKEN_COMMA, poisoned_expr); + expr->cast_expr.type_info = TRY_TYPE_OR(parse_type_expression(context), poisoned_expr); + CONSUME_OR(TOKEN_RPAREN, poisoned_expr); return expr; } @@ -203,12 +203,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); + Expr *true_expr = TRY_EXPR_OR(parse_precedence(context, PREC_TERNARY + 1), poisoned_expr); expr_ternary->ternary_expr.then_expr = true_expr; - CONSUME_OR(TOKEN_COLON, &poisoned_expr); + CONSUME_OR(TOKEN_COLON, poisoned_expr); } - Expr *false_expr = TRY_EXPR_OR(parse_precedence(context, PREC_TERNARY + 1), &poisoned_expr); + Expr *false_expr = TRY_EXPR_OR(parse_precedence(context, PREC_TERNARY + 1), poisoned_expr); expr_ternary->ternary_expr.else_expr = false_expr; return expr_ternary; } @@ -223,8 +223,8 @@ static Expr *parse_grouping_expr(Context *context, Expr *left) assert(!left && "Unexpected left hand side"); Expr *expr = expr_new(EXPR_GROUP, context->tok.span); advance_and_verify(context, TOKEN_LPAREN); - expr->group_expr = TRY_EXPR_OR(parse_expr(context), &poisoned_expr); - CONSUME_OR(TOKEN_RPAREN, &poisoned_expr); + expr->group_expr = TRY_EXPR_OR(parse_expr(context), poisoned_expr); + CONSUME_OR(TOKEN_RPAREN, poisoned_expr); RANGE_EXTEND_PREV(expr); return expr; } @@ -265,11 +265,11 @@ Expr *parse_initializer_list(Context *context) { Expr *initializer_list = EXPR_NEW_TOKEN(EXPR_INITIALIZER_LIST, context->tok); initializer_list->expr_initializer.init_type = INITIALIZER_UNKNOWN; - CONSUME_OR(TOKEN_LBRACE, &poisoned_expr); + CONSUME_OR(TOKEN_LBRACE, poisoned_expr); if (!try_consume(context, TOKEN_RBRACE)) { - if (!parse_param_list(context, &initializer_list->expr_initializer.initializer_expr, false)) return &poisoned_expr; - CONSUME_OR(TOKEN_RBRACE, &poisoned_expr); + if (!parse_param_list(context, &initializer_list->expr_initializer.initializer_expr, false)) return poisoned_expr; + CONSUME_OR(TOKEN_RBRACE, poisoned_expr); } return initializer_list; } @@ -286,11 +286,11 @@ static Expr *parse_binary(Context *context, Expr *left_side) Expr *right_side; if (context->tok.type == TOKEN_LBRACE && operator_type == TOKEN_EQ) { - right_side = TRY_EXPR_OR(parse_initializer_list(context), &poisoned_expr); + right_side = TRY_EXPR_OR(parse_initializer_list(context), poisoned_expr); } else { - right_side = TRY_EXPR_OR(parse_precedence(context, rules[operator_type].precedence + 1), &poisoned_expr); + right_side = TRY_EXPR_OR(parse_precedence(context, rules[operator_type].precedence + 1), poisoned_expr); } Expr *expr = EXPR_NEW_EXPR(EXPR_BINARY, left_side); @@ -309,9 +309,9 @@ static Expr *parse_call_expr(Context *context, Expr *left) advance_and_verify(context, TOKEN_LPAREN); if (context->tok.type != TOKEN_RPAREN) { - if (!parse_param_list(context, ¶ms, 0)) return &poisoned_expr; + if (!parse_param_list(context, ¶ms, 0)) return poisoned_expr; } - TRY_CONSUME_OR(TOKEN_RPAREN, "Expected the ending ')' here", &poisoned_expr); + TRY_CONSUME_OR(TOKEN_RPAREN, "Expected the ending ')' here", poisoned_expr); Expr *call = EXPR_NEW_EXPR(EXPR_CALL, left); call->call_expr.function = left; @@ -326,8 +326,8 @@ static Expr *parse_subscript_expr(Context *context, Expr *left) assert(left && expr_ok(left)); advance_and_verify(context, TOKEN_LBRACKET); - Expr *index = TRY_EXPR_OR(parse_expr(context), &poisoned_expr); - CONSUME_OR(TOKEN_RBRACKET, &poisoned_expr); + Expr *index = TRY_EXPR_OR(parse_expr(context), poisoned_expr); + CONSUME_OR(TOKEN_RBRACKET, poisoned_expr); Expr *subscript_ast = EXPR_NEW_EXPR(EXPR_SUBSCRIPT, left); subscript_ast->subscript_expr.expr = left; subscript_ast->subscript_expr.index = index; @@ -343,7 +343,7 @@ static Expr *parse_access_expr(Context *context, Expr *left) Expr *access_expr = EXPR_NEW_EXPR(EXPR_ACCESS, left); access_expr->access_expr.parent = left; access_expr->access_expr.sub_element = context->tok; - TRY_CONSUME_OR(TOKEN_IDENT, "Expected identifier", &poisoned_expr); + TRY_CONSUME_OR(TOKEN_IDENT, "Expected identifier", poisoned_expr); access_expr->span = left->span; access_expr->span.end_loc = access_expr->access_expr.sub_element.span.end_loc; return access_expr; @@ -370,9 +370,9 @@ static Expr *parse_type_expr(Context *context, Expr *left) assert(!left && "Unexpected left hand side"); Expr *expr = EXPR_NEW_TOKEN(EXPR_TYPE, context->tok); advance_and_verify(context, TOKEN_TYPE); - CONSUME_OR(TOKEN_LPAREN, &poisoned_expr); - TypeInfo *type = TRY_TYPE_OR(parse_type_expression(context), &poisoned_expr); - CONSUME_OR(TOKEN_RPAREN, &poisoned_expr); + CONSUME_OR(TOKEN_LPAREN, poisoned_expr); + TypeInfo *type = TRY_TYPE_OR(parse_type_expression(context), poisoned_expr); + CONSUME_OR(TOKEN_RPAREN, poisoned_expr); expr->type_expr.type = type; return expr; } @@ -391,7 +391,7 @@ static Expr *parse_maybe_scope(Context *context, Expr *left) return parse_type_identifier_with_path(context, path); default: SEMA_TOKEN_ERROR(context->tok, "Expected a type, function or constant."); - return &poisoned_expr; + return poisoned_expr; } } @@ -400,10 +400,10 @@ static Expr *parse_try_expr(Context *context, Expr *left) assert(!left && "Unexpected left hand side"); Expr *try_expr = EXPR_NEW_TOKEN(EXPR_TRY, context->tok); advance_and_verify(context, TOKEN_TRY); - try_expr->try_expr.expr = TRY_EXPR_OR(parse_precedence(context, PREC_TRY + 1), &poisoned_expr); + try_expr->try_expr.expr = TRY_EXPR_OR(parse_precedence(context, PREC_TRY + 1), poisoned_expr); if (try_consume(context, TOKEN_ELSE)) { - try_expr->try_expr.else_expr = TRY_EXPR_OR(parse_precedence(context, PREC_ASSIGNMENT), &poisoned_expr); + try_expr->try_expr.else_expr = TRY_EXPR_OR(parse_precedence(context, PREC_ASSIGNMENT), poisoned_expr); } return try_expr; } @@ -562,7 +562,7 @@ static Expr *parse_double(Context *context, Expr *left) if (end != source_range_len(context->tok.span) + context->tok.start) { SEMA_TOKEN_ERROR(context->tok, "Invalid float value"); - return &poisoned_expr; + return poisoned_expr; } advance(context); number->const_expr.f = fval; @@ -733,7 +733,7 @@ static Expr* parse_expr_block(Context *context, Expr *left) while (!try_consume(context, TOKEN_RPARBRA)) { Ast *stmt = parse_stmt(context); - if (!ast_ok(stmt)) return &poisoned_expr; + if (!ast_ok(stmt)) return poisoned_expr; vec_add(expr->expr_block.stmts, stmt); } return expr; diff --git a/src/compiler/parse_stmt.c b/src/compiler/parse_stmt.c index 3a364a74f..1b968c070 100644 --- a/src/compiler/parse_stmt.c +++ b/src/compiler/parse_stmt.c @@ -16,8 +16,8 @@ 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); - CONSUME_OR(TOKEN_EOS, &poisoned_ast); + decl_stmt->declare_stmt = TRY_DECL_OR(parse_decl(context), poisoned_ast); + CONSUME_OR(TOKEN_EOS, poisoned_ast); return decl_stmt; } @@ -48,7 +48,7 @@ static inline Ast* parse_asm_stmt(Context *context) { // TODO SEMA_TOKEN_ERROR(context->tok, "ASM not supported yet."); - return &poisoned_ast; + return poisoned_ast; } /** @@ -63,13 +63,13 @@ static inline Ast* parse_do_stmt(Context *context) do_ast->do_stmt.body = TRY_AST(parse_stmt(context)); - CONSUME_OR(TOKEN_WHILE, &poisoned_ast); + CONSUME_OR(TOKEN_WHILE, poisoned_ast); - CONSUME_OR(TOKEN_LPAREN, &poisoned_ast); - do_ast->do_stmt.expr = TRY_EXPR_OR(parse_expr(context), &poisoned_ast); - CONSUME_OR(TOKEN_RPAREN, &poisoned_ast); + CONSUME_OR(TOKEN_LPAREN, poisoned_ast); + do_ast->do_stmt.expr = TRY_EXPR_OR(parse_expr(context), poisoned_ast); + CONSUME_OR(TOKEN_RPAREN, poisoned_ast); - CONSUME_OR(TOKEN_EOS, &poisoned_ast); + CONSUME_OR(TOKEN_EOS, poisoned_ast); return do_ast; } @@ -86,18 +86,18 @@ static inline Ast* parse_catch_stmt(Context *context) Ast *catch_stmt = AST_NEW_TOKEN(AST_CATCH_STMT, context->tok); advance_and_verify(context, TOKEN_CATCH); - CONSUME_OR(TOKEN_LPAREN, &poisoned_ast); + CONSUME_OR(TOKEN_LPAREN, poisoned_ast); TypeInfo *type = NULL; if (!try_consume(context, TOKEN_ERROR_TYPE)) { - type = TRY_TYPE_OR(parse_type_expression(context), &poisoned_ast); + type = TRY_TYPE_OR(parse_type_expression(context), poisoned_ast); } - EXPECT_IDENT_FOR_OR("error parameter", &poisoned_ast); + EXPECT_IDENT_FOR_OR("error parameter", poisoned_ast); Decl *decl = decl_new_var(context->tok, type, VARDECL_PARAM, VISIBLE_LOCAL); catch_stmt->catch_stmt.error_param = decl; - CONSUME_OR(TOKEN_RPAREN, &poisoned_ast); + CONSUME_OR(TOKEN_RPAREN, poisoned_ast); catch_stmt->catch_stmt.body = TRY_AST(parse_stmt(context)); return catch_stmt; } @@ -123,9 +123,9 @@ 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); - CONSUME_OR(TOKEN_LPAREN, &poisoned_ast); - if (!parse_control_expression(context, &while_ast->while_stmt.decl, &while_ast->while_stmt.cond)) return &poisoned_ast; - CONSUME_OR(TOKEN_RPAREN, &poisoned_ast); + CONSUME_OR(TOKEN_LPAREN, poisoned_ast); + if (!parse_control_expression(context, &while_ast->while_stmt.decl, &while_ast->while_stmt.cond)) return poisoned_ast; + CONSUME_OR(TOKEN_RPAREN, poisoned_ast); while_ast->while_stmt.body = TRY_AST(parse_stmt(context)); return while_ast; } @@ -140,9 +140,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); - CONSUME_OR(TOKEN_LPAREN, &poisoned_ast); - if (!parse_control_expression(context, &if_ast->if_stmt.decl, &if_ast->if_stmt.cond)) return &poisoned_ast; - CONSUME_OR(TOKEN_RPAREN, &poisoned_ast); + CONSUME_OR(TOKEN_LPAREN, poisoned_ast); + if (!parse_control_expression(context, &if_ast->if_stmt.decl, &if_ast->if_stmt.cond)) return poisoned_ast; + CONSUME_OR(TOKEN_RPAREN, poisoned_ast); Ast *stmt = TRY_AST(parse_stmt(context)); if_ast->if_stmt.then_body = stmt; if (!try_consume(context, TOKEN_ELSE)) @@ -178,7 +178,7 @@ static inline Ast* parse_case_stmt(Context *context) { Ast *ast = AST_NEW_TOKEN(AST_CASE_STMT, context->tok); advance(context); - Expr *expr = TRY_EXPR_OR(parse_constant_expr(context), &poisoned_ast); + Expr *expr = TRY_EXPR_OR(parse_constant_expr(context), poisoned_ast); ast->case_stmt.expr = expr; TRY_CONSUME(TOKEN_COLON, "Missing ':' after case"); extend_ast_with_prev_token(context, ast); @@ -194,7 +194,7 @@ static inline Ast *parse_default_stmt(Context *context) { Ast *ast = AST_NEW_TOKEN(AST_DEFAULT_STMT, context->tok); advance_and_verify(context, TOKEN_DEFAULT); - TRY_CONSUME_OR(TOKEN_COLON, "Expected ':' after 'default'.", &poisoned_ast); + 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)); ast->case_stmt.expr = NULL; @@ -237,13 +237,13 @@ 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); - CONSUME_OR(TOKEN_LPAREN, &poisoned_ast); - if (!parse_control_expression(context, &switch_ast->switch_stmt.decl, &switch_ast->switch_stmt.cond)) return &poisoned_ast; - CONSUME_OR(TOKEN_RPAREN, &poisoned_ast); - CONSUME_OR(TOKEN_LBRACE, &poisoned_ast); + CONSUME_OR(TOKEN_LPAREN, poisoned_ast); + if (!parse_control_expression(context, &switch_ast->switch_stmt.decl, &switch_ast->switch_stmt.cond)) return poisoned_ast; + CONSUME_OR(TOKEN_RPAREN, poisoned_ast); + CONSUME_OR(TOKEN_LBRACE, poisoned_ast); while (!try_consume(context, TOKEN_RBRACE)) { - if (!parse_switch_body(context, switch_ast)) return &poisoned_ast; + if (!parse_switch_body(context, switch_ast)) return poisoned_ast; } return switch_ast; } @@ -262,7 +262,7 @@ static inline Ast* parse_for_stmt(Context *context) { Ast *ast = AST_NEW_TOKEN(AST_FOR_STMT, context->tok); advance_and_verify(context, TOKEN_FOR); - CONSUME_OR(TOKEN_LPAREN, &poisoned_ast); + CONSUME_OR(TOKEN_LPAREN, poisoned_ast); if (context->tok.type != TOKEN_EOS) { @@ -273,21 +273,21 @@ static inline Ast* parse_for_stmt(Context *context) ast->for_stmt.init = NULL; } - CONSUME_OR(TOKEN_EOS, &poisoned_ast); + CONSUME_OR(TOKEN_EOS, poisoned_ast); if (context->tok.type != TOKEN_EOS) { - ast->for_stmt.cond = TRY_EXPR_OR(parse_expr(context), &poisoned_ast); + ast->for_stmt.cond = TRY_EXPR_OR(parse_expr(context), poisoned_ast); } - CONSUME_OR(TOKEN_EOS, &poisoned_ast); + CONSUME_OR(TOKEN_EOS, poisoned_ast); if (context->tok.type != TOKEN_RPAREN) { ast->for_stmt.incr = parse_expression_list(context); } - CONSUME_OR(TOKEN_RPAREN, &poisoned_ast); + CONSUME_OR(TOKEN_RPAREN, poisoned_ast); extend_ast_with_prev_token(context, ast); ast->for_stmt.body = TRY_AST(parse_stmt(context)); @@ -304,7 +304,7 @@ static inline Ast* parse_goto_stmt(Context *context) Ast *ast = AST_NEW_TOKEN(AST_GOTO_STMT, context->tok); advance_and_verify(context, TOKEN_GOTO); ast->goto_stmt.label_name = context->tok.string; - if (!consume_const_name(context, "label")) return &poisoned_ast; + if (!consume_const_name(context, "label")) return poisoned_ast; RETURN_AFTER_EOS(ast); } @@ -348,7 +348,7 @@ static inline Ast* parse_break_stmt(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); + stmt->expr_stmt = TRY_EXPR_OR(parse_expr(context), poisoned_ast); TRY_CONSUME_EOS(); return stmt; } @@ -374,7 +374,7 @@ 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_paren_expr(context), &poisoned_ast); + ast->ct_elif_stmt.expr = TRY_EXPR_OR(parse_paren_expr(context), poisoned_ast); ast->ct_elif_stmt.then = TRY_AST(parse_compound_stmt(context)); @@ -399,7 +399,7 @@ 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_paren_expr(context), &poisoned_ast); + ast->ct_if_stmt.expr = TRY_EXPR_OR(parse_paren_expr(context), poisoned_ast); ast->ct_if_stmt.then = TRY_AST(parse_compound_stmt(context)); if (context->tok.type == TOKEN_CT_ELIF) { @@ -442,7 +442,7 @@ static inline Ast *parse_return_stmt(Context *context) ast->return_stmt.expr = NULL; return ast; } - ast->return_stmt.expr = TRY_EXPR_OR(parse_expr(context), &poisoned_ast); + ast->return_stmt.expr = TRY_EXPR_OR(parse_expr(context), poisoned_ast); RETURN_AFTER_EOS(ast); } @@ -454,7 +454,7 @@ static inline Ast *parse_throw_stmt(Context *context) { Ast *ast = AST_NEW_TOKEN(AST_THROW_STMT, context->tok); advance_and_verify(context, TOKEN_THROW); - ast->throw_stmt.throw_value = TRY_EXPR_OR(parse_expr(context), &poisoned_ast); + ast->throw_stmt.throw_value = TRY_EXPR_OR(parse_expr(context), poisoned_ast); RETURN_AFTER_EOS(ast); } @@ -465,7 +465,7 @@ static inline Ast *parse_throw_stmt(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); + ast->volatile_stmt = TRY_AST_OR(parse_compound_stmt(context), poisoned_ast); return ast; } @@ -490,7 +490,7 @@ static inline Ast *parse_decl_or_expr_stmt(Context *context) Expr *expr = NULL; TypeInfo *type = NULL; - if (!parse_type_or_expr(context, &expr, &type)) return &poisoned_ast; + if (!parse_type_or_expr(context, &expr, &type)) return poisoned_ast; Ast *ast; if (expr) @@ -500,11 +500,11 @@ static inline Ast *parse_decl_or_expr_stmt(Context *context) } else { - Decl *decl = TRY_DECL_OR(parse_decl_after_type(context, false, type), &poisoned_ast); + Decl *decl = TRY_DECL_OR(parse_decl_after_type(context, false, type), poisoned_ast); ast = AST_NEW(AST_DECLARE_STMT, decl->span); ast->declare_stmt = decl; } - CONSUME_OR(TOKEN_EOS, &poisoned_ast); + CONSUME_OR(TOKEN_EOS, poisoned_ast); return ast; } @@ -520,18 +520,18 @@ static inline Ast* parse_ct_for_stmt(Context *context) { Ast *ast = AST_NEW_TOKEN(AST_CT_FOR_STMT, context->tok); advance_and_verify(context, TOKEN_CT_FOR); - CONSUME_OR(TOKEN_LPAREN, &poisoned_ast); + CONSUME_OR(TOKEN_LPAREN, poisoned_ast); if (context->next_tok.type == TOKEN_COMMA) { ast->ct_for_stmt.index = context->tok; - TRY_CONSUME_OR(TOKEN_CT_IDENT, "Expected a compile time index variable", &poisoned_ast); + TRY_CONSUME_OR(TOKEN_CT_IDENT, "Expected a compile time index variable", poisoned_ast); advance_and_verify(context, TOKEN_COMMA); } ast->ct_for_stmt.value = context->tok; - TRY_CONSUME_OR(TOKEN_CT_IDENT, "Expected a compile time variable", &poisoned_ast); - TRY_CONSUME_OR(TOKEN_IN, "Expected 'in'.", &poisoned_ast); - ast->ct_for_stmt.expr = TRY_EXPR_OR(parse_expr(context), &poisoned_ast); - CONSUME_OR(TOKEN_RPAREN, &poisoned_ast); + TRY_CONSUME_OR(TOKEN_CT_IDENT, "Expected a compile time variable", poisoned_ast); + TRY_CONSUME_OR(TOKEN_IN, "Expected 'in'.", poisoned_ast); + ast->ct_for_stmt.expr = TRY_EXPR_OR(parse_expr(context), poisoned_ast); + CONSUME_OR(TOKEN_RPAREN, poisoned_ast); ast->ct_for_stmt.body = TRY_AST(parse_stmt(context)); return ast; } @@ -555,10 +555,10 @@ 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_paren_expr(context), &poisoned_ast); - CONSUME_OR(TOKEN_LBRACE, &poisoned_ast); + ast->ct_switch_stmt.cond = TRY_EXPR_OR(parse_paren_expr(context), poisoned_ast); + CONSUME_OR(TOKEN_LBRACE, poisoned_ast); Ast **switch_statements = NULL; - Ast *stmt = &poisoned_ast; + Ast *stmt = poisoned_ast; while (stmt) { switch (context->tok.type) @@ -568,19 +568,19 @@ static inline Ast* parse_ct_switch_stmt(Context *context) advance(context); while (1) { - TypeInfo *type = TRY_TYPE_OR(parse_type_expression(context), &poisoned_ast); + TypeInfo *type = TRY_TYPE_OR(parse_type_expression(context), poisoned_ast); vec_add(stmt->ct_case_stmt.types, type); if (!try_consume(context, TOKEN_COMMA)) break; } - CONSUME_OR(TOKEN_COLON, &poisoned_ast); - stmt->ct_case_stmt.body = TRY_AST_OR(parse_stmt(context), &poisoned_ast); + CONSUME_OR(TOKEN_COLON, poisoned_ast); + stmt->ct_case_stmt.body = TRY_AST_OR(parse_stmt(context), poisoned_ast); vec_add(switch_statements, stmt); break; case TOKEN_CT_DEFAULT: stmt = AST_NEW_TOKEN(AST_CT_CASE_STMT, context->tok); advance(context); - CONSUME_OR(TOKEN_COLON, &poisoned_ast); - stmt->ct_default_stmt = TRY_AST_OR(parse_stmt(context), &poisoned_ast); + CONSUME_OR(TOKEN_COLON, poisoned_ast); + stmt->ct_default_stmt = TRY_AST_OR(parse_stmt(context), poisoned_ast); vec_add(switch_statements, stmt); break; case TOKEN_RBRACE: @@ -588,10 +588,10 @@ static inline Ast* parse_ct_switch_stmt(Context *context) break; default: SEMA_TOKEN_ERROR(context->tok, "Expected $case or $default."); - return &poisoned_ast; + return poisoned_ast; } } - CONSUME_OR(TOKEN_RBRACE, &poisoned_ast); + CONSUME_OR(TOKEN_RBRACE, poisoned_ast); ast->ct_switch_stmt.body = switch_statements; return ast; } @@ -608,7 +608,7 @@ Ast *parse_stmt(Context *context) case TOKEN_QUAD: SEMA_TOKEN_ERROR(context->next_tok, "Type is unsupported by platform."); advance(context); - return &poisoned_ast; + return poisoned_ast; case TOKEN_VOID: case TOKEN_BYTE: case TOKEN_BOOL: @@ -690,7 +690,7 @@ Ast *parse_stmt(Context *context) case TOKEN_CASE: SEMA_TOKEN_ERROR(context->tok, "'case' was found outside of 'switch', did you mismatch a '{ }' pair?"); advance(context); - return &poisoned_ast; + return poisoned_ast; case TOKEN_BREAK: return parse_break_stmt(context); case TOKEN_NEXT: @@ -700,7 +700,7 @@ Ast *parse_stmt(Context *context) case TOKEN_DEFAULT: SEMA_TOKEN_ERROR(context->tok, "'default' was found outside of 'switch', did you mismatch a '{ }' pair?"); advance(context); - return &poisoned_ast; + return poisoned_ast; case TOKEN_CT_IF: return parse_ct_if_stmt(context); case TOKEN_CT_SWITCH: @@ -736,7 +736,7 @@ Ast *parse_stmt(Context *context) return parse_expr_stmt(context); case TOKEN_INVALID_TOKEN: advance(context); - return &poisoned_ast; + return poisoned_ast; case TOKEN_COLON: case TOKEN_COMMA: case TOKEN_EQ: @@ -810,20 +810,20 @@ Ast *parse_stmt(Context *context) case TOKEN_IN: SEMA_TOKEN_ERROR(context->tok, "Unexpected '%s' found when expecting a statement.", token_type_to_string(context->tok.type)); advance(context); - return &poisoned_ast; + return poisoned_ast; break; case TOKEN_RPAREN: case TOKEN_RBRACE: case TOKEN_RBRACKET: SEMA_TOKEN_ERROR(context->tok, "Mismatched '%s' found.", token_type_to_string(context->tok.type)); advance(context); - return &poisoned_ast; + return poisoned_ast; case TOKEN_EOS: advance(context); return AST_NEW_TOKEN(AST_NOP_STMT, context->tok); case TOKEN_EOF: sema_error_at(context->tok.span.loc - 1, "Reached the end of the file when expecting a statement."); - return &poisoned_ast; + return poisoned_ast; } } @@ -844,7 +844,7 @@ Ast *parse_stmt(Context *context) */ Ast* parse_compound_stmt(Context *context) { - CONSUME_OR(TOKEN_LBRACE, &poisoned_ast); + CONSUME_OR(TOKEN_LBRACE, poisoned_ast); Ast *ast = AST_NEW_TOKEN(AST_COMPOUND_STMT, context->tok); while (!try_consume(context, TOKEN_RBRACE)) { diff --git a/src/compiler/parser.c b/src/compiler/parser.c index 4ab8f352b..b30e6929b 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -319,7 +319,7 @@ static inline TypeInfo *parse_base_type(Context *context) TypeInfo *type_info = type_info_new(TYPE_INFO_IDENTIFIER, range); type_info->unresolved.path = path; type_info->unresolved.name_loc = context->tok; - if (!consume_type_name(context, "types")) return &poisoned_type_info; + if (!consume_type_name(context, "types")) return poisoned_type_info; RANGE_EXTEND_PREV(type_info); return type_info; } @@ -335,10 +335,10 @@ static inline TypeInfo *parse_base_type(Context *context) case TOKEN_TYPE: type_info = type_info_new(TYPE_INFO_IDENTIFIER, context->tok.span); advance_and_verify(context, TOKEN_TYPE); - CONSUME_OR(TOKEN_LPAREN, &poisoned_type_info); + CONSUME_OR(TOKEN_LPAREN, poisoned_type_info); type_info->resolve_status = RESOLVE_NOT_DONE; - type_info->unresolved_type_expr = TRY_EXPR_OR(parse_initializer(context), &poisoned_type_info); - EXPECT_OR(TOKEN_RPAREN, &poisoned_type_info); + type_info->unresolved_type_expr = TRY_EXPR_OR(parse_initializer(context), poisoned_type_info); + EXPECT_OR(TOKEN_RPAREN, poisoned_type_info); RANGE_EXTEND_PREV(type_info); break; case TOKEN_VOID: @@ -409,7 +409,7 @@ static inline TypeInfo *parse_base_type(Context *context) break; default: SEMA_TOKEN_ERROR(context->tok, "A type name was expected here."); - return &poisoned_type_info; + return poisoned_type_info; } if (type_found) { @@ -440,7 +440,7 @@ static inline TypeInfo *parse_array_type_index(Context *context, TypeInfo *type) advance_and_verify(context, TOKEN_LBRACKET); if (try_consume(context, TOKEN_PLUS)) { - CONSUME_OR(TOKEN_RBRACKET, &poisoned_type_info); + CONSUME_OR(TOKEN_RBRACKET, poisoned_type_info); TypeInfo *incr_array = type_info_new(TYPE_INFO_INC_ARRAY, type->span); incr_array->array.base = type; RANGE_EXTEND_PREV(incr_array); @@ -456,8 +456,8 @@ 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); - CONSUME_OR(TOKEN_RBRACKET, &poisoned_type_info); + array->array.len = TRY_EXPR_OR(parse_expr(context), poisoned_type_info); + CONSUME_OR(TOKEN_RBRACKET, poisoned_type_info); RANGE_EXTEND_PREV(array); return array; } @@ -512,10 +512,10 @@ Decl *parse_decl_after_type(Context *context, bool local, TypeInfo *type) if (context->tok.type == TOKEN_LPAREN) { SEMA_TOKEN_ERROR(context->tok, "Expected '{'."); - return &poisoned_decl; + return poisoned_decl; } - EXPECT_IDENT_FOR_OR("variable_name", &poisoned_decl); + EXPECT_IDENT_FOR_OR("variable_name", poisoned_decl); Token name = context->tok; advance(context); @@ -528,10 +528,10 @@ Decl *parse_decl_after_type(Context *context, bool local, TypeInfo *type) if (!decl) { SEMA_TOKEN_ERROR(context->tok, "Expected an identifier before '='."); - return &poisoned_decl; + return poisoned_decl; } advance_and_verify(context, TOKEN_EQ); - decl->var.init_expr = TRY_EXPR_OR(parse_initializer(context), &poisoned_decl); + decl->var.init_expr = TRY_EXPR_OR(parse_initializer(context), poisoned_decl); } return decl; @@ -549,9 +549,9 @@ Decl *parse_decl(Context *context) if (local || constant) advance(context); TypeInfo *type_info = parse_type_expression(context); - TypeInfo *type = TRY_TYPE_OR(type_info, &poisoned_decl); + TypeInfo *type = TRY_TYPE_OR(type_info, poisoned_decl); - Decl *decl = TRY_DECL_OR(parse_decl_after_type(context, local, type), &poisoned_decl); + Decl *decl = TRY_DECL_OR(parse_decl_after_type(context, local, type), poisoned_decl); if (constant) decl->var.kind = VARDECL_CONST; @@ -576,20 +576,20 @@ static inline Decl *parse_const_declaration(Context *context, Visibility visibil if (!is_all_upper(context->tok.string)) { SEMA_TOKEN_ERROR(context->tok, "Compile time constants must be all upper characters."); - return &poisoned_decl; + return poisoned_decl; } } else { - if (!consume_const_name(context, "constant")) return &poisoned_decl; - decl->var.type_info = TRY_TYPE_OR(parse_type_expression(context), &poisoned_decl); + if (!consume_const_name(context, "constant")) return poisoned_decl; + decl->var.type_info = TRY_TYPE_OR(parse_type_expression(context), poisoned_decl); } - CONSUME_OR(TOKEN_EQ, &poisoned_decl); + CONSUME_OR(TOKEN_EQ, poisoned_decl); - decl->var.init_expr = TRY_EXPR_OR(parse_initializer(context), &poisoned_decl); + decl->var.init_expr = TRY_EXPR_OR(parse_initializer(context), poisoned_decl); - CONSUME_OR(TOKEN_EOS, &poisoned_decl); + CONSUME_OR(TOKEN_EOS, poisoned_decl); return decl; } @@ -604,7 +604,7 @@ static inline Decl *parse_const_declaration(Context *context, Visibility visibil */ static inline Decl *parse_global_declaration(Context *context, Visibility visibility) { - TypeInfo *type = TRY_TYPE_OR(parse_type_expression(context), &poisoned_decl); + TypeInfo *type = TRY_TYPE_OR(parse_type_expression(context), poisoned_decl); Decl *decl = decl_new_var(context->tok, type, VARDECL_GLOBAL, visibility); @@ -615,13 +615,13 @@ static inline Decl *parse_global_declaration(Context *context, Visibility visibi return false; } - if (!consume_ident(context, "global variable")) return &poisoned_decl; + if (!consume_ident(context, "global variable")) return poisoned_decl; if (try_consume(context, TOKEN_EQ)) { - decl->var.init_expr = TRY_EXPR_OR(parse_initializer(context), &poisoned_decl); + decl->var.init_expr = TRY_EXPR_OR(parse_initializer(context), poisoned_decl); } - TRY_CONSUME_EOS_OR(&poisoned_decl); + TRY_CONSUME_EOS_OR(poisoned_decl); return decl; } @@ -630,9 +630,9 @@ static inline Decl *parse_incremental_array(Context *context) Token name = context->tok; advance_and_verify(context, TOKEN_IDENT); - CONSUME_OR(TOKEN_PLUS_ASSIGN, &poisoned_decl); + CONSUME_OR(TOKEN_PLUS_ASSIGN, poisoned_decl); Decl *decl = decl_new(DECL_ARRAY_VALUE, name, VISIBLE_LOCAL); - decl->incr_array_decl = TRY_EXPR_OR(parse_initializer(context), &poisoned_decl); + decl->incr_array_decl = TRY_EXPR_OR(parse_initializer(context), poisoned_decl); return decl; } @@ -665,7 +665,7 @@ Ast *parse_decl_expr_list(Context *context) } else { - Decl *decl = TRY_DECL_OR(parse_decl_after_type(context, false, type), &poisoned_ast); + Decl *decl = TRY_DECL_OR(parse_decl_after_type(context, false, type), poisoned_ast); Ast *stmt = AST_NEW(AST_DECLARE_STMT, decl->span); stmt->declare_stmt = decl; vec_add(decl_expr->decl_expr_stmt, stmt); @@ -1065,17 +1065,17 @@ static inline Decl *parse_struct_declaration(Context *context, Visibility visibi Token name = context->tok; - if (!consume_type_name(context, type_name)) return &poisoned_decl; + if (!consume_type_name(context, type_name)) return poisoned_decl; Decl *decl = decl_new_with_type(name, decl_from_token(type), visibility); if (!parse_attributes(context, decl)) { - return &poisoned_decl; + return poisoned_decl; } if (!parse_struct_body(context, decl, decl)) { - return &poisoned_decl; + return poisoned_decl; } DEBUG_LOG("Parsed %s %s completely.", type_name, name.string); return decl; @@ -1089,7 +1089,7 @@ static inline Ast *parse_generics_statements(Context *context) Ast *ast = AST_NEW_TOKEN(AST_COMPOUND_STMT, context->tok); while (context->tok.type != TOKEN_RBRACE && context->tok.type != TOKEN_CASE && context->tok.type != TOKEN_DEFAULT) { - Ast *stmt = TRY_AST_OR(parse_stmt(context), &poisoned_ast); + Ast *stmt = TRY_AST_OR(parse_stmt(context), poisoned_ast); ast->compound_stmt.stmts = VECADD(ast->compound_stmt.stmts, stmt); } return ast; @@ -1116,15 +1116,15 @@ static inline Decl *parse_generics_declaration(Context *context, Visibility visi TypeInfo *rtype = NULL; if (context->tok.type != TOKEN_IDENT) { - rtype = TRY_TYPE_OR(parse_type_expression(context), &poisoned_decl); + rtype = TRY_TYPE_OR(parse_type_expression(context), poisoned_decl); } Path *path = parse_path_prefix(context); Decl *decl = decl_new(DECL_GENERIC, context->tok, visibility); decl->generic_decl.path = path; - if (!consume_ident(context, "generic function name")) return &poisoned_decl; + if (!consume_ident(context, "generic function name")) return poisoned_decl; decl->generic_decl.rtype = rtype; Token *parameters = NULL; - CONSUME_OR(TOKEN_LPAREN, &poisoned_decl); + CONSUME_OR(TOKEN_LPAREN, poisoned_decl); while (!try_consume(context, TOKEN_RPAREN)) { if (context->tok.type != TOKEN_IDENT) @@ -1134,9 +1134,9 @@ static inline Decl *parse_generics_declaration(Context *context, Visibility visi } parameters = VECADD(parameters, context->tok); advance(context); - COMMA_RPAREN_OR(&poisoned_decl); + COMMA_RPAREN_OR(poisoned_decl); } - CONSUME_OR(TOKEN_LBRACE, &poisoned_decl); + CONSUME_OR(TOKEN_LBRACE, poisoned_decl); Ast **cases = NULL; while (!try_consume(context, TOKEN_RBRACE)) { @@ -1147,16 +1147,16 @@ static inline Decl *parse_generics_declaration(Context *context, Visibility visi TypeInfo **types = NULL; while (!try_consume(context, TOKEN_COLON)) { - TypeInfo *type = TRY_TYPE_OR(parse_type_expression(context), &poisoned_decl); + TypeInfo *type = TRY_TYPE_OR(parse_type_expression(context), poisoned_decl); types = VECADD(types, type); if (!try_consume(context, TOKEN_COMMA) && context->tok.type != TOKEN_COLON) { SEMA_TOKEN_ERROR(context->tok, "Expected ',' or ':'."); - return &poisoned_decl; + return poisoned_decl; } } generic_case->generic_case_stmt.types = types; - generic_case->generic_case_stmt.body = TRY_AST_OR(parse_generics_statements(context), &poisoned_decl); + generic_case->generic_case_stmt.body = TRY_AST_OR(parse_generics_statements(context), poisoned_decl); cases = VECADD(cases, generic_case); continue; } @@ -1164,13 +1164,13 @@ static inline Decl *parse_generics_declaration(Context *context, Visibility visi { Ast *generic_case = AST_NEW_TOKEN(AST_GENERIC_DEFAULT_STMT, context->tok); advance_and_verify(context, TOKEN_DEFAULT); - CONSUME_OR(TOKEN_COLON, &poisoned_decl); - generic_case->generic_default_stmt = TRY_AST_OR(parse_generics_statements(context), &poisoned_decl); + CONSUME_OR(TOKEN_COLON, poisoned_decl); + generic_case->generic_default_stmt = TRY_AST_OR(parse_generics_statements(context), poisoned_decl); cases = VECADD(cases, generic_case); continue; } SEMA_TOKEN_ERROR(context->tok, "Expected 'case' or 'default'."); - return &poisoned_decl; + return poisoned_decl; } decl->generic_decl.cases = cases; decl->generic_decl.parameters = parameters; @@ -1234,14 +1234,14 @@ static inline Decl *parse_attribute_declaration(Context *context, Visibility vis last_domain = TOKEN_TO_ATTR[context->tok.type]; } Decl *decl = decl_new(DECL_ATTRIBUTE, context->tok, visibility); - TRY_CONSUME_OR(TOKEN_IDENT, "Expected an attribute name.", &poisoned_decl); + TRY_CONSUME_OR(TOKEN_IDENT, "Expected an attribute name.", poisoned_decl); if (last_domain == 0) { SEMA_TOKEN_ERROR(context->tok, "Expected at least one domain for attribute '%s'.", decl->name); return false; } - if (!parse_opt_parameter_type_list(context, visibility, &decl->attr.attr_signature, false)) return &poisoned_decl; - TRY_CONSUME_EOS_OR(&poisoned_decl); + if (!parse_opt_parameter_type_list(context, visibility, &decl->attr.attr_signature, false)) return poisoned_decl; + TRY_CONSUME_EOS_OR(poisoned_decl); return decl; } @@ -1274,19 +1274,19 @@ static inline Decl *parse_typedef_declaration(Context *context, Visibility visib Decl *decl = decl_new_with_type(context->tok, DECL_TYPEDEF, visibility); if (context->tok.type == TOKEN_FUNC) { - if (!parse_func_typedef(context, decl, visibility)) return &poisoned_decl; + if (!parse_func_typedef(context, decl, visibility)) return poisoned_decl; } else { - decl->typedef_decl.type_info = TRY_TYPE_OR(parse_type_expression(context), &poisoned_decl); + decl->typedef_decl.type_info = TRY_TYPE_OR(parse_type_expression(context), poisoned_decl); decl->typedef_decl.is_func = false; } - CONSUME_OR(TOKEN_AS, &poisoned_decl); + CONSUME_OR(TOKEN_AS, poisoned_decl); decl->name = context->tok.string; decl->name_span = context->tok.span; decl->type->name = context->tok.string; - if (!consume_type_name(context, "typedef")) return &poisoned_decl; - CONSUME_OR(TOKEN_EOS, &poisoned_decl); + if (!consume_type_name(context, "typedef")) return poisoned_decl; + CONSUME_OR(TOKEN_EOS, poisoned_decl); return decl; } @@ -1297,14 +1297,14 @@ static inline Decl *parse_macro_declaration(Context *context, Visibility visibil TypeInfo *rtype = NULL; if (context->tok.type != TOKEN_IDENT) { - rtype = TRY_TYPE_OR(parse_type_expression(context), &poisoned_decl); + rtype = TRY_TYPE_OR(parse_type_expression(context), poisoned_decl); } Decl *decl = decl_new(DECL_MACRO, context->tok, visibility); decl->macro_decl.rtype = rtype; - TRY_CONSUME_OR(TOKEN_IDENT, "Expected a macro name here", &poisoned_decl); + TRY_CONSUME_OR(TOKEN_IDENT, "Expected a macro name here", poisoned_decl); - CONSUME_OR(TOKEN_LPAREN, &poisoned_decl); + CONSUME_OR(TOKEN_LPAREN, poisoned_decl); Decl **params = NULL; while (!try_consume(context, TOKEN_RPAREN)) { @@ -1320,18 +1320,18 @@ static inline Decl *parse_macro_declaration(Context *context, Visibility visibil if (parm_type) { SEMA_TOKEN_ERROR(context->tok, "Expected a macro parameter"); - return &poisoned_decl; + return poisoned_decl; } - parm_type = TRY_TYPE_OR(parse_type_expression(context), &poisoned_decl); + parm_type = TRY_TYPE_OR(parse_type_expression(context), poisoned_decl); goto TEST_TYPE; } Decl *param = decl_new_var(context->tok, parm_type, VARDECL_PARAM, visibility); advance(context); params = VECADD(params, param); - COMMA_RPAREN_OR(&poisoned_decl); + COMMA_RPAREN_OR(poisoned_decl); } decl->macro_decl.parameters = params; - decl->macro_decl.body = TRY_AST_OR(parse_stmt(context), &poisoned_decl); + decl->macro_decl.body = TRY_AST_OR(parse_stmt(context), poisoned_decl); return decl; } @@ -1348,9 +1348,9 @@ static inline Decl *parse_error_declaration(Context *context, Visibility visibil Decl *error_decl = decl_new_with_type(context->tok, DECL_ERROR, visibility); - if (!consume_type_name(context, "error type")) return &poisoned_decl; + if (!consume_type_name(context, "error type")) return poisoned_decl; - CONSUME_OR(TOKEN_LBRACE, &poisoned_decl); + CONSUME_OR(TOKEN_LBRACE, poisoned_decl); while (context->tok.type == TOKEN_CONST_IDENT) { @@ -1376,9 +1376,9 @@ static inline Decl *parse_error_declaration(Context *context, Visibility visibil if (context->tok.type == TOKEN_TYPE_IDENT || context->tok.type == TOKEN_IDENT) { SEMA_TOKEN_ERROR(context->tok, "Errors must be all upper case."); - return &poisoned_decl; + return poisoned_decl; } - CONSUME_OR(TOKEN_RBRACE, &poisoned_decl); + CONSUME_OR(TOKEN_RBRACE, poisoned_decl); return error_decl; } @@ -1431,12 +1431,12 @@ static inline Decl *parse_enum_declaration(Context *context, Visibility visibili Decl *decl = decl_new_with_type(context->tok, DECL_ENUM, visibility); - if (!consume_type_name(context, "enum")) return &poisoned_decl; + if (!consume_type_name(context, "enum")) return poisoned_decl; TypeInfo *type = NULL; if (try_consume(context, TOKEN_COLON)) { - if (!parse_enum_spec(context, &type, &decl->enums.parameters, visibility)) return &poisoned_decl; + if (!parse_enum_spec(context, &type, &decl->enums.parameters, visibility)) return poisoned_decl; } CONSUME_OR(TOKEN_LBRACE, false); @@ -1458,24 +1458,24 @@ static inline Decl *parse_enum_declaration(Context *context, Visibility visibili } if (!consume_const_name(context, "enum constant")) { - return &poisoned_decl; + return poisoned_decl; } if (try_consume(context, TOKEN_LPAREN)) { Expr **result = NULL; - if (!parse_param_list(context, &result, true)) return &poisoned_decl; + if (!parse_param_list(context, &result, true)) return poisoned_decl; enum_const->enum_constant.args = result; - CONSUME_OR(TOKEN_RPAREN, &poisoned_decl); + CONSUME_OR(TOKEN_RPAREN, poisoned_decl); } if (try_consume(context, TOKEN_EQ)) { - enum_const->enum_constant.expr = TRY_EXPR_OR(parse_expr(context), &poisoned_decl); + enum_const->enum_constant.expr = TRY_EXPR_OR(parse_expr(context), poisoned_decl); } vec_add(decl->enums.values, enum_const); // Allow trailing ',' if (!try_consume(context, TOKEN_COMMA)) { - EXPECT_OR(TOKEN_RBRACE, &poisoned_decl); + EXPECT_OR(TOKEN_RBRACE, poisoned_decl); } } return decl; @@ -1511,7 +1511,7 @@ static inline Decl *parse_func_definition(Context *context, Visibility visibilit { advance_and_verify(context, TOKEN_FUNC); - TypeInfo *return_type = TRY_TYPE_OR(parse_type_expression(context), false); + TypeInfo *return_type = TRY_TYPE_OR(parse_type_expression(context), poisoned_decl); Decl *func = decl_new(DECL_FUNC, context->tok, visibility); func->func.function_signature.rtype = return_type; @@ -1521,7 +1521,7 @@ static inline Decl *parse_func_definition(Context *context, Visibility visibilit if (path || context->tok.type == TOKEN_TYPE_IDENT) { // Special case, actually an extension - TRY_EXPECT_OR(TOKEN_TYPE_IDENT, "A type was expected after '::'.", &poisoned_decl); + TRY_EXPECT_OR(TOKEN_TYPE_IDENT, "A type was expected after '::'.", poisoned_decl); // TODO span is incorrect TypeInfo *type = type_info_new(TYPE_INFO_IDENTIFIER, start); type->unresolved.path = path; @@ -1529,17 +1529,17 @@ static inline Decl *parse_func_definition(Context *context, Visibility visibilit func->func.type_parent = type; advance_and_verify(context, TOKEN_TYPE_IDENT); - TRY_CONSUME_OR(TOKEN_DOT, "Expected '.' after the type in a method function.", &poisoned_decl); + TRY_CONSUME_OR(TOKEN_DOT, "Expected '.' after the type in a method function.", poisoned_decl); } - EXPECT_IDENT_FOR_OR("function name", &poisoned_decl); + EXPECT_IDENT_FOR_OR("function name", poisoned_decl); func->name = context->tok.string; func->name_span = context->tok.span; advance_and_verify(context, TOKEN_IDENT); - if (!parse_opt_parameter_type_list(context, visibility, &(func->func.function_signature), is_interface)) return &poisoned_decl; + if (!parse_opt_parameter_type_list(context, visibility, &(func->func.function_signature), is_interface)) return poisoned_decl; - if (!parse_opt_throw_declaration(context, visibility, &(func->func.function_signature))) return &poisoned_decl; + if (!parse_opt_throw_declaration(context, visibility, &(func->func.function_signature))) return poisoned_decl; // TODO remove is_interface = context->tok.type == TOKEN_EOS; @@ -1549,15 +1549,15 @@ static inline Decl *parse_func_definition(Context *context, Visibility visibilit if (context->tok.type == TOKEN_LBRACE) { SEMA_TOKEN_ERROR(context->next_tok, "Functions bodies are not allowed in interface files."); - return &poisoned_decl; + return poisoned_decl; } - TRY_CONSUME_OR(TOKEN_EOS, "Expected ';' after function declaration.", &poisoned_decl); + TRY_CONSUME_OR(TOKEN_EOS, "Expected ';' after function declaration.", poisoned_decl); return func; } - TRY_EXPECT_OR(TOKEN_LBRACE, "Expected the beginning of a block with '{'", &poisoned_decl); + TRY_EXPECT_OR(TOKEN_LBRACE, "Expected the beginning of a block with '{'", poisoned_decl); - func->func.body = TRY_AST_OR(parse_compound_stmt(context), &poisoned_decl); + func->func.body = TRY_AST_OR(parse_compound_stmt(context), poisoned_decl); DEBUG_LOG("Finished parsing function %s", func->name); return func; @@ -1590,17 +1590,17 @@ static inline Decl *parse_ct_if_top_level(Context *context) { Decl *ct = decl_new(DECL_CT_IF, context->tok, VISIBLE_LOCAL); advance_and_verify(context, TOKEN_CT_IF); - ct->ct_if_decl.expr = TRY_EXPR_OR(parse_paren_expr(context), &poisoned_decl); + ct->ct_if_decl.expr = TRY_EXPR_OR(parse_paren_expr(context), poisoned_decl); - if (!parse_conditional_top_level(context, &ct->ct_if_decl.then)) return &poisoned_decl; + if (!parse_conditional_top_level(context, &ct->ct_if_decl.then)) return poisoned_decl; CtIfDecl *ct_if_decl = &ct->ct_if_decl; while (context->tok.type == TOKEN_CT_ELIF) { advance_and_verify(context, TOKEN_CT_ELIF); Decl *ct_elif = decl_new(DECL_CT_ELIF, context->tok, VISIBLE_LOCAL); - ct_elif->ct_elif_decl.expr = TRY_EXPR_OR(parse_paren_expr(context), &poisoned_decl); - if (!parse_conditional_top_level(context, &ct_elif->ct_elif_decl.then)) return &poisoned_decl; + ct_elif->ct_elif_decl.expr = TRY_EXPR_OR(parse_paren_expr(context), poisoned_decl); + if (!parse_conditional_top_level(context, &ct_elif->ct_elif_decl.then)) return poisoned_decl; ct_if_decl->elif = ct_elif; ct_if_decl = &ct_elif->ct_elif_decl; } @@ -1609,7 +1609,7 @@ static inline Decl *parse_ct_if_top_level(Context *context) advance_and_verify(context, TOKEN_CT_ELSE); Decl *ct_else = decl_new(DECL_CT_ELSE, context->tok, VISIBLE_LOCAL); ct_if_decl->elif = ct_else; - if (!parse_conditional_top_level(context, &ct_else->ct_else_decl)) return &poisoned_decl; + if (!parse_conditional_top_level(context, &ct_else->ct_else_decl)) return poisoned_decl; } return ct; } @@ -1705,7 +1705,7 @@ static inline Decl *parse_top_level(Context *context) case TOKEN_EOF: assert(visibility != VISIBLE_MODULE); sema_error_at(context->tok.span.loc - 1, "Expected a top level declaration'."); - return &poisoned_decl; + return poisoned_decl; default: // We could have included all fundamental types above, but do it here instead. if (token_is_type(context->tok.type)) @@ -1713,7 +1713,7 @@ static inline Decl *parse_top_level(Context *context) return parse_global_declaration(context, visibility); } error_at_current(context, "Unexpected token found"); - return &poisoned_decl; + return poisoned_decl; } } @@ -1976,7 +1976,7 @@ static Expr *parse_type_access(Context *context, TypeInfo *type) return expr; default: SEMA_TOKEN_ERROR(context->tok, "Expected a function name, macro, or constant."); - return &poisoned_expr; + return poisoned_expr; } } @@ -1999,9 +1999,13 @@ Expr *parse_type_identifier_with_path(Context *context, Path *path) RANGE_EXTEND_PREV(type); if (context->tok.type == TOKEN_LBRACE) { - return TRY_EXPR_OR(parse_initializer_list(context), &poisoned_expr); + Expr *expr = expr_new(EXPR_COMPOUND_LITERAL, type->span); + expr->expr_compound_literal.type_info = type; + expr->expr_compound_literal.initializer = TRY_EXPR_OR(parse_initializer_list(context), poisoned_expr); + RANGE_EXTEND_PREV(expr); + return expr; } - EXPECT_OR(TOKEN_DOT, &poisoned_expr); + EXPECT_OR(TOKEN_DOT, poisoned_expr); return parse_type_access(context, type); } diff --git a/src/compiler/parser_internal.h b/src/compiler/parser_internal.h index ea1e2ec06..cd19cf51e 100644 --- a/src/compiler/parser_internal.h +++ b/src/compiler/parser_internal.h @@ -9,14 +9,14 @@ #define CONSUME_OR(_tok, _res) do { if (!expect(context, _tok)) return _res; advance(context); } while(0) #define TRY_EXPECT_OR(_tok, _message, _type) do { if (context->tok.type != _tok) { SEMA_TOKEN_ERROR(context->tok, _message); return _type; } } while(0) #define TRY_CONSUME_OR(_tok, _message, _type) do { if (!consume(context, _tok, _message)) return _type; } while(0) -#define TRY_CONSUME(_tok, _message) TRY_CONSUME_OR(_tok, _message, &poisoned_ast) +#define TRY_CONSUME(_tok, _message) TRY_CONSUME_OR(_tok, _message, poisoned_ast) #define TRY_CONSUME_EOS_OR(_res) TRY_CONSUME_OR(TOKEN_EOS, "Expected ';'", _res) -#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_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_CONSUME_LBRACE() TRY_CONSUME(TOKEN_LBRACE, "Expected '{'") #define TRY_AST_OR(_ast_stmt, _res) ({ Ast* _ast = (_ast_stmt); if (!ast_ok(_ast)) return _res; _ast; }) -#define TRY_AST(_ast_stmt) TRY_AST_OR(_ast_stmt, &poisoned_ast) +#define TRY_AST(_ast_stmt) TRY_AST_OR(_ast_stmt, poisoned_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_DECL_OR(_decl_stmt, _res) ({ Decl* _decl = (_decl_stmt); if (!decl_ok(_decl)) return _res; _decl; }) @@ -78,8 +78,8 @@ static inline bool expect_ident(Context *context, const char* name) static inline Expr *parse_paren_expr(Context *context) { - CONSUME_OR(TOKEN_LPAREN, &poisoned_expr); - Expr *expr = TRY_EXPR_OR(parse_expr(context), &poisoned_expr); - CONSUME_OR(TOKEN_RPAREN, &poisoned_expr); + CONSUME_OR(TOKEN_LPAREN, poisoned_expr); + Expr *expr = TRY_EXPR_OR(parse_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 231a14ba3..f0e83a8c2 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -927,6 +927,7 @@ static inline bool sema_expr_analyse_initializer_list(Context *context, Type *to default: break; } + // Fix error on compound literals SEMA_ERROR(expr, "Cannot assign expression to '%s'.", type_to_error_string(to)); return false; } @@ -2275,6 +2276,10 @@ static Expr *expr_copy_from_macro(Context *context, Expr *macro, Expr *source_ex Expr *expr = expr_shallow_copy(source_expr); switch (source_expr->expr_kind) { + case EXPR_COMPOUND_LITERAL: + EXPR_COPY(expr->expr_compound_literal.initializer); + expr->expr_compound_literal.type_info = type_info_copy_from_macro(context, macro, expr->expr_compound_literal.type_info); + return expr; case EXPR_DESIGNATED_INITIALIZER: // Created during semantic analysis UNREACHABLE @@ -2342,7 +2347,7 @@ static Expr *expr_copy_from_macro(Context *context, Expr *macro, Expr *source_ex return expr; case EXPR_CAST: EXPR_COPY(expr->cast_expr.expr); - expr->cast_expr.type_info = expr->cast_expr.type_info = type_info_copy_from_macro(context, macro, expr->cast_expr.type_info); + expr->cast_expr.type_info = type_info_copy_from_macro(context, macro, expr->cast_expr.type_info); return expr; case EXPR_SCOPED_EXPR: EXPR_COPY(expr->expr_scope.expr); @@ -2733,6 +2738,14 @@ static inline bool sema_expr_analyse_range(Context *context, Type *to, Expr *exp { TODO } +static inline bool sema_expr_analyse_compound_literal(Context *context, Type *to, Expr *expr) +{ + if (!sema_resolve_type_info(context, expr->expr_compound_literal.type_info)) return false; + Type *type = expr->expr_compound_literal.type_info->type; + if (!sema_expr_analyse_initializer_list(context, type, expr->expr_compound_literal.initializer)) return false; + expr->type = type; + return true; +} static inline bool sema_analyse_expr_dispatch(Context *context, Type *to, Expr *expr) { @@ -2745,6 +2758,8 @@ static inline bool sema_analyse_expr_dispatch(Context *context, Type *to, Expr * UNREACHABLE case EXPR_SCOPED_EXPR: UNREACHABLE + case EXPR_COMPOUND_LITERAL: + return sema_expr_analyse_compound_literal(context, to, expr); case EXPR_EXPR_BLOCK: return sema_expr_analyse_expr_block(context, to, expr); case EXPR_MACRO_EXPR: diff --git a/src/compiler/sema_name_resolution.c b/src/compiler/sema_name_resolution.c index 923985c6c..fd2533ad2 100644 --- a/src/compiler/sema_name_resolution.c +++ b/src/compiler/sema_name_resolution.c @@ -55,7 +55,7 @@ static Decl *sema_resolve_path_symbol(Context *context, const char *symbol, Path if (!path_found) { SEMA_ERROR(path, "Unknown module %.*s.", path->len, path->module); - return &poisoned_decl; + return poisoned_decl; } return NULL; }