From: Brendan Hansen Date: Wed, 23 Jun 2021 00:59:34 +0000 (-0500) Subject: first class-ish types X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=a7efdef822829cf9a29a5299781adbd905477d45;p=onyx.git first class-ish types --- diff --git a/bin/onyx b/bin/onyx index 410ed5f9..14477b46 100755 Binary files a/bin/onyx and b/bin/onyx differ diff --git a/core/type_info.onyx b/core/type_info.onyx index bad1026e..ea094e7e 100644 --- a/core/type_info.onyx +++ b/core/type_info.onyx @@ -57,6 +57,8 @@ Type_Info_Basic :: struct { F32X4 :: 0x13; F64X2 :: 0x14; V128 :: 0x15; + + Type_Index :: 0x16; } basic_kind: Kind; diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index 5213bcae..a762abba 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -693,10 +693,12 @@ struct AstSwitch { u32 flags; \ OnyxToken* token; \ struct Entity* entity; \ - char* name + char* name; \ + void* __unused; \ + Type* type struct AstType { AstType_base; }; -struct AstBasicType { AstType_base; Type* type; }; +struct AstBasicType { AstType_base; Type* basic_type; }; struct AstPointerType { AstType_base; AstType* elem; }; struct AstFunctionType { AstType_base; AstType* return_type; u64 param_count; AstType* params[]; }; struct AstArrayType { AstType_base; AstType* elem; AstTyped *count_expr; }; diff --git a/include/onyxtypes.h b/include/onyxtypes.h index 9bacca84..6113fead 100644 --- a/include/onyxtypes.h +++ b/include/onyxtypes.h @@ -32,6 +32,8 @@ enum BasicKind { Basic_Kind_F64X2, Basic_Kind_V128, + Basic_Kind_Type_Index, + Basic_Kind_Count, }; @@ -44,8 +46,11 @@ enum BasicFlag { Basic_Flag_SIMD = BH_BIT(5), + Basic_Flag_Type_Index = BH_BIT(6), + Basic_Flag_Numeric = Basic_Flag_Integer | Basic_Flag_Float, Basic_Flag_Ordered = Basic_Flag_Integer | Basic_Flag_Float | Basic_Flag_Pointer, + Basic_Flag_Equality = Basic_Flag_Ordered | Basic_Flag_Type_Index, Basic_Flag_Constant_Type = Basic_Flag_Boolean | Basic_Flag_Numeric | Basic_Flag_Pointer, Basic_Flag_Numeric_Ordered = Basic_Flag_Numeric | Basic_Flag_Ordered, }; diff --git a/src/onyxbuiltins.c b/src/onyxbuiltins.c index 404e4199..745209a5 100644 --- a/src/onyxbuiltins.c +++ b/src/onyxbuiltins.c @@ -3,32 +3,32 @@ #include "onyxerrors.h" #include "onyxutils.h" -AstBasicType basic_type_void = { Ast_Kind_Basic_Type, 0, NULL, NULL, "void" , &basic_types[Basic_Kind_Void] }; -AstBasicType basic_type_bool = { Ast_Kind_Basic_Type, 0, NULL, NULL, "bool" , &basic_types[Basic_Kind_Bool] }; -AstBasicType basic_type_i8 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "i8" , &basic_types[Basic_Kind_I8] }; -AstBasicType basic_type_u8 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "u8" , &basic_types[Basic_Kind_U8] }; -AstBasicType basic_type_i16 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "i16" , &basic_types[Basic_Kind_I16] }; -AstBasicType basic_type_u16 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "u16" , &basic_types[Basic_Kind_U16] }; -AstBasicType basic_type_i32 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "i32" , &basic_types[Basic_Kind_I32] }; -AstBasicType basic_type_u32 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "u32" , &basic_types[Basic_Kind_U32] }; -AstBasicType basic_type_i64 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "i64" , &basic_types[Basic_Kind_I64] }; -AstBasicType basic_type_u64 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "u64" , &basic_types[Basic_Kind_U64] }; -AstBasicType basic_type_f32 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "f32" , &basic_types[Basic_Kind_F32] }; -AstBasicType basic_type_f64 = { Ast_Kind_Basic_Type, 0, NULL, NULL, "f64" , &basic_types[Basic_Kind_F64] }; -AstBasicType basic_type_rawptr = { Ast_Kind_Basic_Type, 0, NULL, NULL, "rawptr", &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] }; // NOTE: Types used for numeric literals -AstBasicType basic_type_int_unsized = { Ast_Kind_Basic_Type, 0, NULL, NULL, "unsized_int", &basic_types[Basic_Kind_Int_Unsized] }; -AstBasicType basic_type_float_unsized = { Ast_Kind_Basic_Type, 0, NULL, NULL, "unsized_float", &basic_types[Basic_Kind_Float_Unsized] }; +AstBasicType basic_type_int_unsized = { Ast_Kind_Basic_Type, 0, NULL, NULL, "unsized_int", NULL, NULL, &basic_types[Basic_Kind_Int_Unsized] }; +AstBasicType basic_type_float_unsized = { Ast_Kind_Basic_Type, 0, NULL, NULL, "unsized_float", NULL, NULL, &basic_types[Basic_Kind_Float_Unsized] }; static OnyxToken simd_token = { Token_Type_Symbol, 0, "", { 0 } }; -AstBasicType basic_type_i8x16 = { Ast_Kind_Basic_Type, 0, &simd_token, NULL, "i8x16", &basic_types[Basic_Kind_I8X16] }; -AstBasicType basic_type_i16x8 = { Ast_Kind_Basic_Type, 0, &simd_token, NULL, "i16x8", &basic_types[Basic_Kind_I16X8] }; -AstBasicType basic_type_i32x4 = { Ast_Kind_Basic_Type, 0, &simd_token, NULL, "i32x4", &basic_types[Basic_Kind_I32X4] }; -AstBasicType basic_type_i64x2 = { Ast_Kind_Basic_Type, 0, &simd_token, NULL, "i64x2", &basic_types[Basic_Kind_I64X2] }; -AstBasicType basic_type_f32x4 = { Ast_Kind_Basic_Type, 0, &simd_token, NULL, "f32x4", &basic_types[Basic_Kind_F32X4] }; -AstBasicType basic_type_f64x2 = { Ast_Kind_Basic_Type, 0, &simd_token, NULL, "f64x2", &basic_types[Basic_Kind_F64X2] }; -AstBasicType basic_type_v128 = { Ast_Kind_Basic_Type, 0, &simd_token, NULL, "v128", &basic_types[Basic_Kind_V128] }; +AstBasicType basic_type_i8x16 = { Ast_Kind_Basic_Type, 0, &simd_token, NULL, "i8x16", NULL, NULL, &basic_types[Basic_Kind_I8X16] }; +AstBasicType basic_type_i16x8 = { Ast_Kind_Basic_Type, 0, &simd_token, NULL, "i16x8", NULL, NULL, &basic_types[Basic_Kind_I16X8] }; +AstBasicType basic_type_i32x4 = { Ast_Kind_Basic_Type, 0, &simd_token, NULL, "i32x4", NULL, NULL, &basic_types[Basic_Kind_I32X4] }; +AstBasicType basic_type_i64x2 = { Ast_Kind_Basic_Type, 0, &simd_token, NULL, "i64x2", NULL, NULL, &basic_types[Basic_Kind_I64X2] }; +AstBasicType basic_type_f32x4 = { Ast_Kind_Basic_Type, 0, &simd_token, NULL, "f32x4", NULL, NULL, &basic_types[Basic_Kind_F32X4] }; +AstBasicType basic_type_f64x2 = { Ast_Kind_Basic_Type, 0, &simd_token, NULL, "f64x2", NULL, NULL, &basic_types[Basic_Kind_F64X2] }; +AstBasicType basic_type_v128 = { Ast_Kind_Basic_Type, 0, &simd_token, NULL, "v128", NULL, NULL, &basic_types[Basic_Kind_V128] }; OnyxToken builtin_package_token = { Token_Type_Symbol, 7, "builtin ", { 0 } }; diff --git a/src/onyxchecker.c b/src/onyxchecker.c index 6f316f06..9ff489ec 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -747,6 +747,60 @@ CheckStatus check_binaryop_assignment(AstBinaryOp* binop, b32 assignment_is_ok) return Check_Success; } +static b32 binary_op_is_allowed(BinaryOp operation, Type* type) { + static const u8 binop_allowed[Binary_Op_Count] = { + /* Add */ Basic_Flag_Numeric | Basic_Flag_Pointer, + /* Minus */ Basic_Flag_Numeric | Basic_Flag_Pointer, + /* Multiply */ Basic_Flag_Numeric, + /* Divide */ Basic_Flag_Numeric, + /* Modulus */ Basic_Flag_Integer, + + /* Equal */ Basic_Flag_Equality, + /* Not_Equal */ Basic_Flag_Equality, + /* Less */ Basic_Flag_Ordered, + /* Less_Equal */ Basic_Flag_Ordered, + /* Greater */ Basic_Flag_Ordered, + /* Greater_Equal */ Basic_Flag_Ordered, + + /* And */ Basic_Flag_Integer, + /* Or */ Basic_Flag_Integer, + /* Xor */ Basic_Flag_Integer, + /* Shl */ Basic_Flag_Integer, + /* Shr */ Basic_Flag_Integer, + /* Sar */ Basic_Flag_Integer, + + /* Bool_And */ Basic_Flag_Boolean, + /* Bool_Or */ Basic_Flag_Boolean, + + /* Assign_Start */ 0, + /* Assign */ 0, + /* Assign_Add */ 0, + /* Assign_Minus */ 0, + /* Assign_Multiply */ 0, + /* Assign_Divide */ 0, + /* Assign_Modulus */ 0, + /* Assign_And */ 0, + /* Assign_Or */ 0, + /* Assign_Xor */ 0, + /* Assign_Shl */ 0, + /* Assign_Shr */ 0, + /* Assign_Sar */ 0, + /* Assign_End */ 0, + + /* Pipe */ 0, + /* Range */ 0, + }; + + 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; + } + + return (binop_allowed[binop->operation] & effective_flags) == 0; +} + CheckStatus check_binaryop_compare(AstBinaryOp** pbinop) { AstBinaryOp* binop = *pbinop; @@ -934,59 +988,8 @@ CheckStatus check_binaryop(AstBinaryOp** pbinop, b32 assignment_is_ok) { } } - static const u8 binop_allowed[Binary_Op_Count] = { - /* Add */ Basic_Flag_Numeric | Basic_Flag_Pointer, - /* Minus */ Basic_Flag_Numeric | Basic_Flag_Pointer, - /* Multiply */ Basic_Flag_Numeric, - /* Divide */ Basic_Flag_Numeric, - /* Modulus */ Basic_Flag_Integer, - - /* Equal */ Basic_Flag_Ordered, - /* Not_Equal */ Basic_Flag_Ordered, - /* Less */ Basic_Flag_Ordered, - /* Less_Equal */ Basic_Flag_Ordered, - /* Greater */ Basic_Flag_Ordered, - /* Greater_Equal */ Basic_Flag_Ordered, - - /* And */ Basic_Flag_Integer, - /* Or */ Basic_Flag_Integer, - /* Xor */ Basic_Flag_Integer, - /* Shl */ Basic_Flag_Integer, - /* Shr */ Basic_Flag_Integer, - /* Sar */ Basic_Flag_Integer, - - /* Bool_And */ Basic_Flag_Boolean, - /* Bool_Or */ Basic_Flag_Boolean, - - /* Assign_Start */ 0, - /* Assign */ 0, - /* Assign_Add */ 0, - /* Assign_Minus */ 0, - /* Assign_Multiply */ 0, - /* Assign_Divide */ 0, - /* Assign_Modulus */ 0, - /* Assign_And */ 0, - /* Assign_Or */ 0, - /* Assign_Xor */ 0, - /* Assign_Shl */ 0, - /* Assign_Shr */ 0, - /* Assign_Sar */ 0, - /* Assign_End */ 0, - - /* Pipe */ 0, - /* Range */ 0, - }; - binop->type = binop->left->type; - - enum BasicFlag effective_flags = 0; - switch (binop->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; - } - - if ((binop_allowed[binop->operation] & effective_flags) == 0) goto bad_binaryop; + if (!binary_op_is_allowed(binop->operation, binop->type)) goto bad_binaryop; // NOTE: Enum flags with '&' result in a boolean value if (binop->type->kind == Type_Kind_Enum && binop->type->Enum.is_flags && binop->operation == Binary_Op_And) { @@ -1274,7 +1277,7 @@ CheckStatus check_dereference(AstDereference* deref) { return Check_Error; } - if (deref->expr->type == basic_type_rawptr.type) { + if (deref->expr->type == basic_type_rawptr.basic_type) { onyx_report_error(deref->token->pos, "Cannot dereference 'rawptr'. Cast to another pointer type first."); return Check_Error; } @@ -1483,6 +1486,7 @@ 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) { + expr->type = &basic_types[Basic_Kind_Type_Index]; return Check_Success; } diff --git a/src/onyxtypes.c b/src/onyxtypes.c index 90fccfd1..e3ecd503 100644 --- a/src/onyxtypes.c +++ b/src/onyxtypes.c @@ -35,6 +35,8 @@ Type basic_types[] = { { Type_Kind_Basic, 0, 0, (AstType *) &basic_type_f32x4, { Basic_Kind_F32X4, Basic_Flag_SIMD, 16, 16, "f32x4" } }, { 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" } }, }; // TODO: Document this!! @@ -463,7 +465,7 @@ Type* type_build_from_ast(bh_allocator alloc, AstType* type_node) { } case Ast_Kind_Basic_Type: { - return ((AstBasicType *) type_node)->type; + return ((AstBasicType *) type_node)->basic_type; } case Ast_Kind_Type_Alias: diff --git a/src/onyxwasm.c b/src/onyxwasm.c index bb910401..2eac1ec9 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -2259,6 +2259,14 @@ EMIT_FUNC(location, AstTyped* expr) { EMIT_FUNC(expression, AstTyped* expr) { bh_arr(WasmInstruction) code = *pcode; + if (node_is_type((AstNode *) expr)) { + Type* type = type_build_from_ast(context.ast_alloc, (AstType *) expr); + WID(WI_I32_CONST, type->id); + + *pcode = code; + return; + } + switch (expr->kind) { case Ast_Kind_Param: { AstLocal* param = (AstLocal *) expr; diff --git a/src/onyxwasm_type_table.c b/src/onyxwasm_type_table.c index 0d89b347..059a3018 100644 --- a/src/onyxwasm_type_table.c +++ b/src/onyxwasm_type_table.c @@ -138,6 +138,7 @@ u64 build_type_table(OnyxWasmModule* module) { bh_buffer_write_u64(&table_buffer, 0); // TODO: Add member info here. Also, Patching bh_buffer_write_u64(&table_buffer, 0); bh_buffer_write_u32(&table_buffer, type->Enum.is_flags ? 1 : 0); + break; } case Type_Kind_Struct: {