From: Brendan Hansen Date: Wed, 23 Jun 2021 02:40:17 +0000 (-0500) Subject: types are even more first class X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=91b4aa6207f5e72e90dcf9927bf31292a69312fb;p=onyx.git types are even more first class --- diff --git a/bin/onyx b/bin/onyx index 14477b46..2bcf731c 100755 Binary files a/bin/onyx and b/bin/onyx differ diff --git a/core/type_info.onyx b/core/type_info.onyx index ea094e7e..c62ab36b 100644 --- a/core/type_info.onyx +++ b/core/type_info.onyx @@ -3,7 +3,6 @@ package core.type_info -Type_Index :: #type u32 type_table : [] ^Type_Info; Type_Info :: struct { @@ -68,14 +67,14 @@ Type_Info_Pointer :: struct { use base : Type_Info; @Rename - to: Type_Index; + to: type_expr; } Type_Info_Function :: struct { use base : Type_Info; - return_type: Type_Index; - parameter_types: [] Type_Index; + return_type: type_expr; + parameter_types: [] type_expr; is_variadic: bool; } @@ -84,7 +83,7 @@ Type_Info_Array :: struct { use base : Type_Info; @Rename - of: Type_Index; + of: type_expr; count: u32; } @@ -92,21 +91,21 @@ Type_Info_Slice :: struct { use base : Type_Info; @Rename - of: Type_Index; + of: type_expr; } Type_Info_Dynamic_Array :: struct { use base : Type_Info; @Rename - of: Type_Index; + of: type_expr; } Type_Info_Variadic_Argument :: struct { use base : Type_Info; @Rename - of: Type_Index; + of: type_expr; } Type_Info_Enum :: struct { @@ -118,7 +117,7 @@ Type_Info_Enum :: struct { } // This is first for better alignment - backing_type: Type_Index; + backing_type: type_expr; name: str; members: [] Member; @@ -131,7 +130,7 @@ Type_Info_Struct :: struct { Member :: struct { name: str; offset: u32; - type_index: Type_Index; + type_index: type_expr; used: bool; has_default: bool; @@ -144,11 +143,11 @@ Type_Info_Struct :: struct { Type_Info_Compound :: struct { use base : Type_Info; - components : [] Type_Index; + components : [] type_expr; } -get_type_info :: (t: Type_Index) -> ^Type_Info { - if t < 0 || t >= type_table.count do return null; +get_type_info :: (t: type_expr) -> ^Type_Info { + if t < ~~0 || t >= ~~type_table.count do return null; - return type_table[t]; + return type_table[cast(i32) t]; } \ No newline at end of file diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index a762abba..fb6c3943 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -1178,6 +1178,7 @@ extern AstBasicType basic_type_u64; extern AstBasicType basic_type_f32; extern AstBasicType basic_type_f64; extern AstBasicType basic_type_rawptr; +extern AstBasicType basic_type_type_expr; // :TypeExprHack extern AstBasicType basic_type_int_unsized; extern AstBasicType basic_type_float_unsized; @@ -1191,9 +1192,6 @@ extern AstBasicType basic_type_f64x2; extern AstBasicType basic_type_v128; -// :TypeExprHack -extern AstNode type_expr_symbol; - extern OnyxToken builtin_package_token; extern AstNumLit builtin_heap_start; extern AstGlobal builtin_stack_top; diff --git a/src/onyxastnodes.c b/src/onyxastnodes.c index abb5752a..15793918 100644 --- a/src/onyxastnodes.c +++ b/src/onyxastnodes.c @@ -430,7 +430,7 @@ b32 type_check_or_auto_cast(AstTyped** pnode, Type* type) { if (type == NULL) return 0; if (node == NULL) return 0; - if (node_is_type((AstNode *) node)) return 0; + // if (node_is_type((AstNode *) node)) return 0; if (node->kind == Ast_Kind_Struct_Literal && node->type_node == NULL) { if (type->kind == Type_Kind_VarArgs) type = type->VarArgs.ptr_to_data->Pointer.elem; @@ -531,7 +531,7 @@ Type* resolve_expression_type(AstTyped* node) { } if (node_is_type((AstNode *) node)) { - return NULL; + return &basic_types[Basic_Kind_Type_Index]; } if (node->type == NULL) @@ -571,21 +571,27 @@ i64 get_expression_integer_value(AstTyped* node) { return ((AstAlignOf *) node)->alignment; } + if (node_is_type((AstNode*) node)) { + Type* type = type_build_from_ast(context.ast_alloc, (AstType *) node); + return type->id; + } + return 0; } -static const b32 cast_legality[][11] = { - /* I8 */ { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 }, - /* U8 */ { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 }, - /* I16 */ { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 }, - /* U16 */ { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 }, - /* I32 */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, - /* U32 */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, - /* I64 */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, - /* U64 */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, - /* F32 */ { 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0 }, - /* F64 */ { 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0 }, - /* PTR */ { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1 }, +static const b32 cast_legality[][12] = { + /* I8 */ { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 }, + /* U8 */ { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 }, + /* I16 */ { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 }, + /* U16 */ { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 }, + /* I32 */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + /* U32 */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + /* I64 */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 }, + /* U64 */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 }, + /* F32 */ { 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0 }, + /* F64 */ { 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0 }, + /* PTR */ { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0 }, + /* TYP */ { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1,} }; b32 cast_is_legal(Type* from_, Type* to_, char** err_msg) { @@ -650,6 +656,9 @@ b32 cast_is_legal(Type* from_, Type* to_, char** err_msg) { else if (from->Basic.flags & Basic_Flag_Boolean) { fromidx = 0; } + else if (from->Basic.flags & Basic_Flag_Type_Index) { + fromidx = 11; + } if (to->Basic.flags & Basic_Flag_Pointer || to->kind == Type_Kind_Array) { toidx = 10; @@ -666,6 +675,9 @@ b32 cast_is_legal(Type* from_, Type* to_, char** err_msg) { else if (to->Basic.flags & Basic_Flag_Boolean) { toidx = 0; } + else if (to->Basic.flags & Basic_Flag_Type_Index) { + toidx = 11; + } if (fromidx != -1 && toidx != -1) { if (!cast_legality[fromidx][toidx]) { diff --git a/src/onyxbuiltins.c b/src/onyxbuiltins.c index 745209a5..d3282244 100644 --- a/src/onyxbuiltins.c +++ b/src/onyxbuiltins.c @@ -3,19 +3,20 @@ #include "onyxerrors.h" #include "onyxutils.h" -AstBasicType basic_type_void = { Ast_Kind_Basic_Type, 0, NULL, NULL, "void" , NULL, NULL, &basic_types[Basic_Kind_Void] }; -AstBasicType basic_type_bool = { Ast_Kind_Basic_Type, 0, NULL, NULL, "bool" , NULL, NULL, &basic_types[Basic_Kind_Bool] }; -AstBasicType basic_type_i8 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "i8" , NULL, NULL, &basic_types[Basic_Kind_I8] }; -AstBasicType basic_type_u8 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "u8" , NULL, NULL, &basic_types[Basic_Kind_U8] }; -AstBasicType basic_type_i16 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "i16" , NULL, NULL, &basic_types[Basic_Kind_I16] }; -AstBasicType basic_type_u16 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "u16" , NULL, NULL, &basic_types[Basic_Kind_U16] }; -AstBasicType basic_type_i32 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "i32" , NULL, NULL, &basic_types[Basic_Kind_I32] }; -AstBasicType basic_type_u32 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "u32" , NULL, NULL, &basic_types[Basic_Kind_U32] }; -AstBasicType basic_type_i64 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "i64" , NULL, NULL, &basic_types[Basic_Kind_I64] }; -AstBasicType basic_type_u64 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "u64" , NULL, NULL, &basic_types[Basic_Kind_U64] }; -AstBasicType basic_type_f32 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "f32" , NULL, NULL, &basic_types[Basic_Kind_F32] }; -AstBasicType basic_type_f64 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "f64" , NULL, NULL, &basic_types[Basic_Kind_F64] }; -AstBasicType basic_type_rawptr = { Ast_Kind_Basic_Type, 0, NULL, NULL, "rawptr", NULL, NULL, &basic_types[Basic_Kind_Rawptr] }; +AstBasicType basic_type_void = { Ast_Kind_Basic_Type, 0, NULL, NULL, "void" , NULL, NULL, &basic_types[Basic_Kind_Void] }; +AstBasicType basic_type_bool = { Ast_Kind_Basic_Type, 0, NULL, NULL, "bool" , NULL, NULL, &basic_types[Basic_Kind_Bool] }; +AstBasicType basic_type_i8 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "i8" , NULL, NULL, &basic_types[Basic_Kind_I8] }; +AstBasicType basic_type_u8 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "u8" , NULL, NULL, &basic_types[Basic_Kind_U8] }; +AstBasicType basic_type_i16 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "i16" , NULL, NULL, &basic_types[Basic_Kind_I16] }; +AstBasicType basic_type_u16 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "u16" , NULL, NULL, &basic_types[Basic_Kind_U16] }; +AstBasicType basic_type_i32 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "i32" , NULL, NULL, &basic_types[Basic_Kind_I32] }; +AstBasicType basic_type_u32 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "u32" , NULL, NULL, &basic_types[Basic_Kind_U32] }; +AstBasicType basic_type_i64 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "i64" , NULL, NULL, &basic_types[Basic_Kind_I64] }; +AstBasicType basic_type_u64 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "u64" , NULL, NULL, &basic_types[Basic_Kind_U64] }; +AstBasicType basic_type_f32 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "f32" , NULL, NULL, &basic_types[Basic_Kind_F32] }; +AstBasicType basic_type_f64 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "f64" , NULL, NULL, &basic_types[Basic_Kind_F64] }; +AstBasicType basic_type_rawptr = { Ast_Kind_Basic_Type, 0, NULL, NULL, "rawptr", NULL, NULL, &basic_types[Basic_Kind_Rawptr] }; +AstBasicType basic_type_type_expr = { Ast_Kind_Basic_Type, 0, NULL, NULL, "type_expr", NULL, NULL, &basic_types[Basic_Kind_Type_Index] }; // NOTE: Types used for numeric literals AstBasicType basic_type_int_unsized = { Ast_Kind_Basic_Type, 0, NULL, NULL, "unsized_int", NULL, NULL, &basic_types[Basic_Kind_Int_Unsized] }; @@ -37,10 +38,6 @@ static OnyxToken builtin_stack_top_token = { Token_Type_Symbol, 11, "__stack_to AstNumLit builtin_heap_start = { Ast_Kind_NumLit, Ast_Flag_Const, &builtin_heap_start_token, NULL, NULL, (AstType *) &basic_type_rawptr, NULL, 0 }; AstGlobal builtin_stack_top = { Ast_Kind_Global, Ast_Flag_Const | Ast_Flag_Global_Stack_Top, &builtin_stack_top_token, NULL, NULL, (AstType *) &basic_type_rawptr, NULL }; -// :TypeExprHack -static OnyxToken type_expr_token = { Token_Type_Symbol, 9, "type_expr", { 0 } }; -AstNode type_expr_symbol = { Ast_Kind_Error, 0, &type_expr_token, NULL, NULL }; - AstType *builtin_string_type; AstType *builtin_range_type; Type *builtin_range_type_type; @@ -67,7 +64,7 @@ const BuiltinSymbol builtin_symbols[] = { { NULL, "f32", (AstNode *) &basic_type_f32 }, { NULL, "f64", (AstNode *) &basic_type_f64 }, { NULL, "rawptr", (AstNode *) &basic_type_rawptr }, - { NULL, "type_expr", (AstNode *) &type_expr_symbol }, + { NULL, "type_expr", (AstNode *) &basic_type_type_expr }, { "simd", "i8x16", (AstNode *) &basic_type_i8x16 }, { "simd", "i16x8", (AstNode *) &basic_type_i16x8 }, diff --git a/src/onyxchecker.c b/src/onyxchecker.c index 9ff489ec..9f953de9 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -286,10 +286,12 @@ CheckStatus check_switch(AstSwitch* switchnode) { return Check_Error; } + // LEAK if this has to be yielded bh_imap_init(&switchnode->case_map, global_heap_allocator, bh_arr_length(switchnode->cases) * 2); switchnode->min_case = 0xffffffffffffffff; + // Umm, this doesn't check the type of the case expression to the type of the expression bh_arr_each(AstSwitchCase, sc, switchnode->cases) { CHECK(block, sc->block); @@ -297,10 +299,7 @@ CheckStatus check_switch(AstSwitch* switchnode) { CHECK(expression, value); // :UnaryFieldAccessIsGross - if ((*value)->kind == Ast_Kind_Unary_Field_Access) { - type_check_or_auto_cast(value, resolved_expr_type); - } - + // if ((*value)->kind == Ast_Kind_Unary_Field_Access) { if ((*value)->kind == Ast_Kind_Range_Literal) { AstRangeLiteral* rl = (AstRangeLiteral *) (*value); resolve_expression_type(rl->low); @@ -326,6 +325,25 @@ CheckStatus check_switch(AstSwitch* switchnode) { continue; } + if (!type_check_or_auto_cast(value, resolved_expr_type)) { + OnyxToken* tkn = sc->block->token; + if ((*value)->token) tkn = (*value)->token; + + onyx_report_error(tkn->pos, "Mismatched types in switch-case. Expected '%s', got '%s'.", + type_get_name(resolved_expr_type), type_get_name((*value)->type)); + + return Check_Error; + } + + if (node_is_type((AstNode*) (*value))) { + Type* type = type_build_from_ast(context.ast_alloc, (AstType*) (*value)); + + if (add_case_to_switch_statement(switchnode, type->id, sc->block, sc->block->token->pos)) + return Check_Error; + + continue; + } + if ((*value)->kind == Ast_Kind_Enum_Value) { (*value) = (AstTyped *) ((AstEnumValue *) (*value))->value; } @@ -793,12 +811,12 @@ static b32 binary_op_is_allowed(BinaryOp operation, Type* type) { enum BasicFlag effective_flags = 0; switch (type->kind) { - case Type_Kind_Basic: effective_flags = binop->type->Basic.flags; break; - case Type_Kind_Pointer: effective_flags = Basic_Flag_Pointer; break; - case Type_Kind_Enum: effective_flags = Basic_Flag_Integer; break; + case Type_Kind_Basic: effective_flags = type->Basic.flags; break; + case Type_Kind_Pointer: effective_flags = Basic_Flag_Pointer; break; + case Type_Kind_Enum: effective_flags = Basic_Flag_Integer; break; } - return (binop_allowed[binop->operation] & effective_flags) == 0; + return (binop_allowed[operation] & effective_flags) != 0; } CheckStatus check_binaryop_compare(AstBinaryOp** pbinop) { @@ -1486,6 +1504,13 @@ CheckStatus check_align_of(AstAlignOf* ao) { CheckStatus check_expression(AstTyped** pexpr) { AstTyped* expr = *pexpr; if (expr->kind > Ast_Kind_Type_Start && expr->kind < Ast_Kind_Type_End) { + // This is to ensure that the type will exist when compiling. For example, a poly-call type + // would have to wait for the entity to pass through, which the code generation does not know + // about. + if (type_build_from_ast(context.ast_alloc, (AstType*) expr) == NULL) { + return Check_Yield_Macro; + } + expr->type = &basic_types[Basic_Kind_Type_Index]; return Check_Success; } diff --git a/src/onyxtypes.c b/src/onyxtypes.c index e3ecd503..36fc57bf 100644 --- a/src/onyxtypes.c +++ b/src/onyxtypes.c @@ -36,7 +36,7 @@ Type basic_types[] = { { Type_Kind_Basic, 0, 0, (AstType *) &basic_type_f64x2, { Basic_Kind_F64X2, Basic_Flag_SIMD, 16, 16, "f64x2" } }, { Type_Kind_Basic, 0, 0, (AstType *) &basic_type_v128, { Basic_Kind_V128, Basic_Flag_SIMD, 16, 16, "v128" } }, - { Type_Kind_Basic, 0, 0, NULL, { Basic_Kind_Type_Index, Basic_Flag_Type_Index, 4, 4, "Type_Index" } }, + { Type_Kind_Basic, 0, 0, NULL, { Basic_Kind_Type_Index, Basic_Flag_Type_Index, 4, 4, "type_expr" } }, }; // TODO: Document this!! @@ -1092,7 +1092,8 @@ b32 type_is_small_integer(Type* type) { b32 type_is_integer(Type* type) { if (type->kind != Type_Kind_Basic) return 0; - return type->Basic.kind >= Basic_Kind_I8 && type->Basic.kind <= Basic_Kind_U64; + return (type->Basic.kind >= Basic_Kind_I8 && type->Basic.kind <= Basic_Kind_U64) + || type->Basic.kind == Basic_Kind_Type_Index; } b32 type_is_numeric(Type* type) { diff --git a/src/onyxutils.c b/src/onyxutils.c index e737e804..5864662f 100644 --- a/src/onyxutils.c +++ b/src/onyxutils.c @@ -686,7 +686,7 @@ static void solve_for_polymorphic_param_value(PolySolveResult* resolved, AstPoly value = ((AstArgument *) value)->value; } - if (param->type_expr == (AstType *) &type_expr_symbol) { + if (param->type_expr == (AstType *) &basic_type_type_expr) { if (!node_is_type((AstNode *) value)) { if (err_msg) *err_msg = "Expected type expression."; return; @@ -1233,7 +1233,7 @@ AstStructType* polymorphic_struct_lookup(AstPolyStructType* ps_type, bh_arr(AstP sln->poly_sym = (AstNode *) &ps_type->poly_params[i]; PolySolutionKind expected_kind = PSK_Undefined; - if ((AstNode *) ps_type->poly_params[i].type_node == &type_expr_symbol) { + if ((AstNode *) ps_type->poly_params[i].type_node == (AstNode *) &basic_type_type_expr) { expected_kind = PSK_Type; } else { expected_kind = PSK_Value; diff --git a/src/onyxwasm.c b/src/onyxwasm.c index 2eac1ec9..a8823798 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -64,6 +64,7 @@ static WasmType onyx_type_to_wasm_type(Type* type) { if (basic->size == 8) return WASM_TYPE_FLOAT64; } if (basic->flags & Basic_Flag_SIMD) return WASM_TYPE_VAR128; + if (basic->flags & Basic_Flag_Type_Index) return WASM_TYPE_INT32; if (basic->size == 0) return WASM_TYPE_VOID; } @@ -578,7 +579,9 @@ EMIT_FUNC(store_instruction, Type* type, u32 offset) { if (is_basic && (type->Basic.flags & Basic_Flag_Pointer)) { WID(WI_I32_STORE, ((WasmInstructionData) { 2, offset })); - } else if (is_basic && ((type->Basic.flags & Basic_Flag_Integer) || (type->Basic.flags & Basic_Flag_Boolean))) { + } else if (is_basic && ((type->Basic.flags & Basic_Flag_Integer) + || (type->Basic.flags & Basic_Flag_Boolean) + || (type->Basic.flags & Basic_Flag_Type_Index))) { if (store_size == 1) WID(WI_I32_STORE_8, ((WasmInstructionData) { alignment, offset })); else if (store_size == 2) WID(WI_I32_STORE_16, ((WasmInstructionData) { alignment, offset })); else if (store_size == 4) WID(WI_I32_STORE, ((WasmInstructionData) { alignment, offset })); @@ -628,7 +631,9 @@ EMIT_FUNC(load_instruction, Type* type, u32 offset) { instr = WI_I32_LOAD; alignment = 2; } - else if (is_basic && ((type->Basic.flags & Basic_Flag_Integer) || (type->Basic.flags & Basic_Flag_Boolean))) { + else if (is_basic && ((type->Basic.flags & Basic_Flag_Integer) + || (type->Basic.flags & Basic_Flag_Boolean) + || (type->Basic.flags & Basic_Flag_Type_Index))) { if (load_size == 1) instr = WI_I32_LOAD_8_S; else if (load_size == 2) instr = WI_I32_LOAD_16_S; else if (load_size == 4) instr = WI_I32_LOAD; @@ -2566,19 +2571,20 @@ EMIT_FUNC(expression, AstTyped* expr) { *pcode = code; } -static const WasmInstructionType cast_map[][11] = { +static const WasmInstructionType cast_map[][12] = { // I8 U8 I16 U16 I32 U32 I64 U64 F32 F64 PTR - /* I8 */ { WI_NOP, WI_NOP, WI_I32_EXTEND_8_S, WI_NOP, WI_I32_EXTEND_8_S, WI_NOP, WI_I64_FROM_I32_S, WI_I64_FROM_I32_S, WI_UNREACHABLE, WI_UNREACHABLE, WI_UNREACHABLE }, - /* U8 */ { WI_NOP, WI_NOP, WI_NOP, WI_NOP, WI_NOP, WI_NOP, WI_I64_FROM_I32_U, WI_I64_FROM_I32_U, WI_UNREACHABLE, WI_UNREACHABLE, WI_UNREACHABLE }, - /* I16 */ { WI_NOP, WI_NOP, WI_NOP, WI_NOP, WI_I32_EXTEND_16_S, WI_NOP, WI_I64_FROM_I32_S, WI_I64_FROM_I32_S, WI_UNREACHABLE, WI_UNREACHABLE, WI_UNREACHABLE }, - /* U16 */ { WI_NOP, WI_NOP, WI_NOP, WI_NOP, WI_NOP, WI_NOP, WI_I64_FROM_I32_U, WI_I64_FROM_I32_U, WI_UNREACHABLE, WI_UNREACHABLE, WI_UNREACHABLE }, - /* I32 */ { WI_NOP, WI_NOP, WI_NOP, WI_NOP, WI_NOP, WI_NOP, WI_I64_FROM_I32_S, WI_I64_FROM_I32_S, WI_F32_FROM_I32_S, WI_F64_FROM_I32_S, WI_NOP }, - /* U32 */ { WI_NOP, WI_NOP, WI_NOP, WI_NOP, WI_NOP, WI_NOP, WI_I64_FROM_I32_U, WI_I64_FROM_I32_U, WI_F32_FROM_I32_U, WI_F64_FROM_I32_U, WI_NOP }, - /* I64 */ { WI_NOP, WI_I32_FROM_I64, WI_I32_FROM_I64, WI_I32_FROM_I64, WI_I32_FROM_I64, WI_I32_FROM_I64, WI_NOP, WI_NOP, WI_F32_FROM_I64_S, WI_F64_FROM_I64_S, WI_I32_FROM_I64 }, - /* U64 */ { WI_NOP, WI_I32_FROM_I64, WI_I32_FROM_I64, WI_I32_FROM_I64, WI_I32_FROM_I64, WI_I32_FROM_I64, WI_NOP, WI_NOP, WI_F32_FROM_I64_U, WI_F64_FROM_I64_U, WI_I32_FROM_I64 }, - /* F32 */ { WI_UNREACHABLE, WI_UNREACHABLE, WI_UNREACHABLE, WI_UNREACHABLE, WI_I32_FROM_F32_S, WI_I32_FROM_F32_U, WI_I64_FROM_F32_S, WI_I64_FROM_F32_U, WI_NOP, WI_F64_FROM_F32, WI_UNREACHABLE }, - /* F64 */ { WI_UNREACHABLE, WI_UNREACHABLE, WI_UNREACHABLE, WI_UNREACHABLE, WI_I32_FROM_F64_S, WI_I32_FROM_F64_U, WI_I64_FROM_F64_S, WI_I64_FROM_F64_U, WI_F32_FROM_F64, WI_NOP, WI_UNREACHABLE }, - /* PTR */ { WI_UNREACHABLE, WI_UNREACHABLE, WI_UNREACHABLE, WI_UNREACHABLE, WI_NOP, WI_NOP, WI_I64_FROM_I32_U, WI_I64_FROM_I32_U, WI_UNREACHABLE, WI_UNREACHABLE, WI_NOP }, + /* I8 */ { WI_NOP, WI_NOP, WI_I32_EXTEND_8_S, WI_NOP, WI_I32_EXTEND_8_S, WI_NOP, WI_I64_FROM_I32_S, WI_I64_FROM_I32_S, WI_UNREACHABLE, WI_UNREACHABLE, WI_UNREACHABLE, WI_UNREACHABLE }, + /* U8 */ { WI_NOP, WI_NOP, WI_NOP, WI_NOP, WI_NOP, WI_NOP, WI_I64_FROM_I32_U, WI_I64_FROM_I32_U, WI_UNREACHABLE, WI_UNREACHABLE, WI_UNREACHABLE, WI_UNREACHABLE }, + /* I16 */ { WI_NOP, WI_NOP, WI_NOP, WI_NOP, WI_I32_EXTEND_16_S, WI_NOP, WI_I64_FROM_I32_S, WI_I64_FROM_I32_S, WI_UNREACHABLE, WI_UNREACHABLE, WI_UNREACHABLE, WI_UNREACHABLE }, + /* U16 */ { WI_NOP, WI_NOP, WI_NOP, WI_NOP, WI_NOP, WI_NOP, WI_I64_FROM_I32_U, WI_I64_FROM_I32_U, WI_UNREACHABLE, WI_UNREACHABLE, WI_UNREACHABLE, WI_UNREACHABLE }, + /* I32 */ { WI_NOP, WI_NOP, WI_NOP, WI_NOP, WI_NOP, WI_NOP, WI_I64_FROM_I32_S, WI_I64_FROM_I32_S, WI_F32_FROM_I32_S, WI_F64_FROM_I32_S, WI_NOP, WI_NOP }, + /* U32 */ { WI_NOP, WI_NOP, WI_NOP, WI_NOP, WI_NOP, WI_NOP, WI_I64_FROM_I32_U, WI_I64_FROM_I32_U, WI_F32_FROM_I32_U, WI_F64_FROM_I32_U, WI_NOP, WI_NOP }, + /* I64 */ { WI_NOP, WI_I32_FROM_I64, WI_I32_FROM_I64, WI_I32_FROM_I64, WI_I32_FROM_I64, WI_I32_FROM_I64, WI_NOP, WI_NOP, WI_F32_FROM_I64_S, WI_F64_FROM_I64_S, WI_I32_FROM_I64, WI_UNREACHABLE }, + /* U64 */ { WI_NOP, WI_I32_FROM_I64, WI_I32_FROM_I64, WI_I32_FROM_I64, WI_I32_FROM_I64, WI_I32_FROM_I64, WI_NOP, WI_NOP, WI_F32_FROM_I64_U, WI_F64_FROM_I64_U, WI_I32_FROM_I64, WI_UNREACHABLE }, + /* F32 */ { WI_UNREACHABLE, WI_UNREACHABLE, WI_UNREACHABLE, WI_UNREACHABLE, WI_I32_FROM_F32_S, WI_I32_FROM_F32_U, WI_I64_FROM_F32_S, WI_I64_FROM_F32_U, WI_NOP, WI_F64_FROM_F32, WI_UNREACHABLE, WI_UNREACHABLE }, + /* F64 */ { WI_UNREACHABLE, WI_UNREACHABLE, WI_UNREACHABLE, WI_UNREACHABLE, WI_I32_FROM_F64_S, WI_I32_FROM_F64_U, WI_I64_FROM_F64_S, WI_I64_FROM_F64_U, WI_F32_FROM_F64, WI_NOP, WI_UNREACHABLE, WI_UNREACHABLE }, + /* PTR */ { WI_UNREACHABLE, WI_UNREACHABLE, WI_UNREACHABLE, WI_UNREACHABLE, WI_NOP, WI_NOP, WI_I64_FROM_I32_U, WI_I64_FROM_I32_U, WI_UNREACHABLE, WI_UNREACHABLE, WI_NOP, WI_UNREACHABLE }, + /* TYP */ { WI_UNREACHABLE, WI_UNREACHABLE, WI_UNREACHABLE, WI_UNREACHABLE, WI_NOP, WI_NOP, WI_UNREACHABLE, WI_UNREACHABLE, WI_UNREACHABLE, WI_UNREACHABLE, WI_UNREACHABLE, WI_NOP }, }; EMIT_FUNC(cast, AstUnaryOp* cast) { @@ -2621,6 +2627,12 @@ EMIT_FUNC(cast, AstUnaryOp* cast) { if (from->Basic.size == 4) fromidx = 8; else if (from->Basic.size == 8) fromidx = 9; } + else if (from->Basic.flags & Basic_Flag_Boolean) { + fromidx = 0; + } + else if (from->Basic.flags & Basic_Flag_Type_Index) { + fromidx = 11; + } if (to->Basic.flags & Basic_Flag_Pointer || to->kind == Type_Kind_Array) { toidx = 10; @@ -2634,6 +2646,12 @@ EMIT_FUNC(cast, AstUnaryOp* cast) { if (to->Basic.size == 4) toidx = 8; else if (to->Basic.size == 8) toidx = 9; } + else if (to->Basic.flags & Basic_Flag_Boolean) { + toidx = 0; + } + else if (to->Basic.flags & Basic_Flag_Type_Index) { + toidx = 11; + } if (fromidx != -1 && toidx != -1) { WasmInstructionType cast_op = cast_map[fromidx][toidx];