diff --git a/build.bat b/build.bat index 8e18089..669a2a6 100644 --- a/build.bat +++ b/build.bat @@ -3,7 +3,8 @@ call "..\misc\compile_setup.bat" bld --dont_compile_core cd build -core_main.exe rtsgame/main.core +rem core_main.exe rtsgame/main.core +core_main.exe examples/unions.core bld --dont_compile_core --link=vendor/raylib/windows/raylibdll.lib rem build\generated_main.exe cd .. diff --git a/build/modules/Base.core b/build/modules/Base.core index 60e8f53..7f0f97a 100644 --- a/build/modules/Base.core +++ b/build/modules/Base.core @@ -30,7 +30,7 @@ QuestionMark16 :: 0x003f String32 :: struct;; str: *U32; len: int String16 :: struct;; str: *U16; len: int -Utf8ToUtf32 :: (c: *U8, max_advance: int): U32, int +Utf8ToUtf32 :: (c: *U8, max_advance: int): Two(U32, int) out_str: U32 advance: int if (c[0] & 0b10000000) == 0 @@ -60,21 +60,19 @@ Utf8ToUtf32 :: (c: *U8, max_advance: int): U32, int out_str = (c0 & 0b00001111) << 18 | (c1 & 0b00111111) << 12 | (c2 & 0b00111111) << 6 | (c3 & 0b00111111) advance = 4 - return out_str, advance + return {out_str, advance} -Utf32ToUtf16 :: (codepoint: U32): [2]U16, int - str: [2]U16 - len := 0 +Utf32ToUtf16 :: (codepoint: U32): Two([2]U16, int) + result: Two([2]U16, int) if codepoint < 0x10000 - str[0] = codepoint->U16 - len = 1 + result.a[0] = codepoint->U16 + result.b = 1 elif codepoint <= 0x10FFFF code: U32 = (codepoint - 0x10000) - str[0] = (0xD800 | (code >> 10))->U16 - str[1] = (0xDC00 | (code & 0x3FF))->U16 - len = 2 - - return str, len + result.a[0] = (0xD800 | (code >> 10))->U16 + result.a[1] = (0xDC00 | (code & 0x3FF))->U16 + result.b = 2 + return result StringToString16 :: (arena: *Arena, in: String): String16 in_str := &in[0] @@ -82,7 +80,9 @@ StringToString16 :: (arena: *Arena, in: String): String16 alloc_size := (Len(in)*2)+1 result := String16{str = PushSize(arena, alloc_size->U64)} for i := 0, i < Len(in) - s32, s32_len := Utf8ToUtf32(in_str + i, Len(in) - i) + a := Utf8ToUtf32(in_str + i, Len(in) - i) + s32 := a.a + s32_len := a.b if s32_len != 0 i += s32_len s16, s16_len := Utf32ToUtf16(s32) diff --git a/build/modules/USER32.core b/build/modules/USER32.core index 53010bc..020f940 100644 --- a/build/modules/USER32.core +++ b/build/modules/USER32.core @@ -25,7 +25,7 @@ AdjustWindowRectEx :: #foreign (lpRect: *RECT, dwStyle: DWORD, bMenu: BOOL, dwEx SetWindowPos :: #foreign (hWnd: HWND, hWndInsertAfter: HWND, X: int, Y: int, cx: int, cy: int, uFlags: UINT): BOOL GetClientRect :: #foreign (hWnd: HWND, lpRect: LPRECT): BOOL -CW_USEDEFAULT :: -2147483648//0x80000000 +CW_USEDEFAULT :: 0x80000000-1 // -2147483648 WS_CAPTION :: 0x00C00000 diff --git a/core_ast.cpp b/core_ast.cpp index c8a141b..032318a 100644 --- a/core_ast.cpp +++ b/core_ast.cpp @@ -110,11 +110,11 @@ ast_expr_index(Token *pos, Ast_Expr *expr, Ast_Expr *index) { } CORE_Static Ast_Lambda * -ast_lambda(Token *pos, Array params, Array ret, Ast_Scope *scope) { +ast_lambda(Token *pos, Array params, Ast_Expr *ret, Ast_Scope *scope) { AST_NEW(Lambda, LAMBDA_EXPR, pos, AST_EXPR); result->flags = AST_EXPR; result->args = params.tight_copy(pctx->perm); - result->ret = ret.tight_copy(pctx->perm); + result->ret = ret; result->scope = scope; if (scope) scope->parent_ast = result; @@ -171,12 +171,9 @@ ast_continue(Token *pos) { } CORE_Static Ast_Return * -ast_return(Token *pos, Array expr) { +ast_return(Token *pos, Ast_Expr *expr) { AST_NEW(Return, RETURN, pos, AST_STMT); - if (expr.len) { - For(expr) assert(is_flag_set(it->flags, AST_EXPR)); - result->expr = expr.tight_copy(pctx->perm); - } + result->expr = expr; return result; } @@ -623,14 +620,14 @@ void next(Ast_Iter *iter) { case AST_RETURN: { Ast_Return *node = (Ast_Return *)ast; if (!iter->skip_end_blocks) iter->stack.add(node); - For(node->expr) iter->stack.add(it); + if (node->expr) iter->stack.add(node->expr); } break; case AST_LAMBDA_EXPR: { Ast_Lambda *node = (Ast_Lambda *)ast; if (!iter->skip_end_blocks) iter->stack.add(node); if (node->scope) iter->stack.add(node->scope); - For(node->ret) iter->stack.add(it); + iter->stack.add(node->ret); For(node->args) iter->stack.add(it); } break; diff --git a/core_codegen_c_language.cpp b/core_codegen_c_language.cpp index 0df825d..bfd2bdb 100644 --- a/core_codegen_c_language.cpp +++ b/core_codegen_c_language.cpp @@ -72,7 +72,6 @@ get_ctype_name_for_type(Ast_Type *type) { case TYPE_U16: return "uint16_t"; case TYPE_U32: return "uint32_t"; case TYPE_U64: return "uint64_t"; - case TYPE_TUPLE: return "Tuple"; case TYPE_TYPE: return "int64_t"; case TYPE_INCOMPLETE: { @@ -105,10 +104,6 @@ string_simple_decl_prefix(Ast_Type *ast) { string = pctx->fmt("Slice%llu ", ast->type_id); return string; } break; - case TYPE_TUPLE: { - String string = pctx->fmt("Tuple%llu ", ast->type_id); - return string; - } break; case TYPE_UNION: case TYPE_STRUCT: { auto constant = (Ast_Decl *)ast->ast; @@ -189,6 +184,7 @@ get_type_postfix(Ast_Type *type) { case TYPE_U8: case TYPE_UCHAR: case TYPE_U16: + case TYPE_UINT: case TYPE_U32: return "U"_s; break; case TYPE_SHORT: @@ -585,39 +581,8 @@ gen_ast(Ast *ast) { } CASE(RETURN, Return) { - if (is_tuple(node->resolved_type)) { - Scoped_Arena scratch(pctx->scratch); - - Intern_String tuple_name = get_unique_name(); - gen_simple_decl(node->resolved_type, tuple_name); - gen(";"); - - int i = 0; - For(node->expr) { - - // We cant assign to array in C so we need a special case - if (is_array(it->resolved_type)) { - genln("MemoryCopy(&%Q.m%d, ", tuple_name, i); - gen_expr(it); - gen(", sizeof(%Q.m%d));", tuple_name, i); - } - - else { - genln("%Q.m%d = ", tuple_name, i); - gen_expr(it); - gen(";"); - } - - i += 1; - } - gen_line(node); - genln("return %Q;", tuple_name); - return; - } - - assert(node->expr.len <= 1); gen("return "); - For(node->expr) gen_expr(it); + gen_expr(node->expr); gen(";"); BREAK(); } @@ -814,10 +779,10 @@ gen_ast(Ast *ast) { } CASE(VAR_UNPACK, Var_Unpack) { - For(node->vars) + Ast_Type *t = node->resolved_type; + For(node->vars) { gen_ast(it); - - Scoped_Arena scratch(pctx->scratch); + } Intern_String var_name = get_unique_name(); gen_simple_decl(node->resolved_type, var_name); @@ -827,7 +792,12 @@ gen_ast(Ast *ast) { int i = 0; For(node->vars) { - gen("MemoryCopy((void *)&%Q, (void *)&%Q.m%d, sizeof(%Q));", it->name, var_name, i++, it->name); + Ast_Resolved_Member &m = t->agg.members[i]; + char *p = "&"; + if (is_array(m.type)) p = ""; + + gen("MemoryCopy((void *)%s%Q, (void *)%s%Q.%Q, sizeof(%Q));", p, it->name, p, var_name, m.name, it->name); + i = +1; } BREAK(); } @@ -926,10 +896,8 @@ int printf(const char *format, ...); } } - // Generate slice and tuple types + // Generate slice types For2(pctx->all_types, type) { - Scoped_Arena scratch(pctx->scratch); - if (type->kind == TYPE_SLICE) { genln("typedef struct Slice%llu{", type->type_id); global_indent++; @@ -940,20 +908,6 @@ int printf(const char *format, ...); global_indent--; genln("} Slice%llu;", type->type_id); } - - else if (type->kind == TYPE_TUPLE) { - genln("typedef struct Tuple%llu{", type->type_id); - global_indent++; - For(type->agg.members) { - genln(""); - // @todo remove intern from gen - Intern_String name = pctx->internf("m%llu", type->agg.members.get_index(it)); - gen_simple_decl(it.type, name); - gen(";"); - } - global_indent--; - genln("} Tuple%llu;", type->type_id); - } } Intern_String intern_main = pctx->intern("main"_s); @@ -994,12 +948,15 @@ int printf(const char *format, ...); } // Generate type info - genln("int64_t type_infos_len = %d;", length(&pctx->all_types)); + genln("int type_infos_len = %d;", length(&pctx->all_types)); genln("Type_Info *type_infos = (Type_Info[]){"); global_indent++; + int i = 0; For2(pctx->all_types, t) { if (t->kind == TYPE_POLYMORPH) continue; - // if (t->kind == TYPE_VARGS) continue; + if (i++ != t->type_id) { + compiler_error(0, "Internal compiler error: type info array is inconsistent"); + } genln("{/*%Q*/", typestring(t)); global_indent += 1; @@ -1042,9 +999,11 @@ int printf(const char *format, ...); global_indent -= 1; genln("}"); } break; + case AST_ENUM: { + // todo; + } break; default: { } - // invalid_default_case; } end_of_switch:; global_indent -= 1; diff --git a/core_compiler.cpp b/core_compiler.cpp index 6c9dbab..082ddfc 100644 --- a/core_compiler.cpp +++ b/core_compiler.cpp @@ -335,7 +335,11 @@ Any :: struct String :: struct data: *U8 - len: S64 + len: int + +Two :: struct($A: Type, $B: Type) + a: A + b: B Type_Info_Kind :: enum S64 // FIRST_NUMERIC @@ -366,26 +370,26 @@ Type_Info_Kind :: enum Type_Info_Struct_Member :: struct name: String type: Type - offset: S64 + offset: int Type_Info :: struct kind: Type_Info_Kind - size: S64 - align: S64 + size: int + align: int is_unsigned: bool type: Type base_type: Type - array_size: S64 + array_size: int struct_members: []Type_Info_Struct_Member lambda_arguments: []Type_Info lambda_return: Type -type_infos_len: S64 #foreign +type_infos_len: int #foreign type_infos : *Type_Info #foreign GetTypeInfo :: (type: Type): *Type_Info - id := type->S64 + id := type->int if id >= type_infos_len return 0 return type_infos + id diff --git a/core_compiler_interface.hpp b/core_compiler_interface.hpp index b1cbdd9..a6d9aaf 100644 --- a/core_compiler_interface.hpp +++ b/core_compiler_interface.hpp @@ -218,7 +218,6 @@ enum Ast_Type_Kind { TYPE_ENUM, TYPE_TYPE, TYPE_SLICE, - TYPE_TUPLE, TYPE_COMPLETING, TYPE_INCOMPLETE, @@ -509,7 +508,7 @@ struct Ast_Builtin : Ast_Expr { struct Ast_Return : Ast { Ast_Type *resolved_type; - Array expr; + Ast_Expr *expr; }; struct Ast_If_Node : Ast { @@ -538,16 +537,7 @@ struct Ast_For : Ast { struct Ast_Lambda : Ast_Expr { Array args; - - // :Multiple arguments - // @todo: maybe disallow multiple arguments in current form - // and use polimorphism. Then we could make var unpacking, - // unpack structs making it more powerful - - // @cleanup @refactor: return value shouldn't be a array of expressions. - // It should be a single expression. So probably need a special type - // for that. - Array ret; + Ast_Expr *ret; Ast_Scope *scope; }; diff --git a/core_parsing.cpp b/core_parsing.cpp index 2f584c6..c0c6e83 100644 --- a/core_parsing.cpp +++ b/core_parsing.cpp @@ -284,13 +284,8 @@ parse_stmt_scope(Ast_Scope *scope_defined_outside = 0) { Token *token = token_get(); if (token_match_keyword(pctx->keyword_return)) { - Array expr = {scratch.arena}; - if (!token_is_scope()) { - do { - Ast_Expr *subexpr = parse_expr(); - expr.add(subexpr); - } while (token_match(TK_Comma)); - } + Ast_Expr *expr = 0; + if (!token_is_scope()) expr = parse_expr(); scope->stmts.add(ast_return(token, expr)); } @@ -518,17 +513,7 @@ parse_lambda(Token *token) { Scoped_Arena scratch(pctx->scratch); Array params = parse_parameter_list(scratch.arena); - Array ret = {scratch.arena}; - if (token_match(TK_Colon)) { - do { - Ast_Expr *typespec = parse_expr(); - set_flag_typespec(typespec); - - ret.add(typespec); - } while (token_match(TK_Comma)); - } - else ret.add(ast_ident(token, pctx->intern_void)); - + Ast_Expr *ret = parse_optional_type(); Ast_Scope *scope = token_is(OPEN_SCOPE) ? parse_stmt_scope() : 0; Ast_Lambda *result = ast_lambda(token, params, ret, scope); return result; diff --git a/core_polymorph.cpp b/core_polymorph.cpp index fbb236b..44dc370 100644 --- a/core_polymorph.cpp +++ b/core_polymorph.cpp @@ -19,7 +19,6 @@ Ast_Expr *create_typespec_from_type(Token *pos, Ast_Scope *parent_scope, Ast_Typ Ast_Expr *result = 0; switch (type->kind) { case TYPE_NONE: - case TYPE_TUPLE: case TYPE_COMPLETING: case TYPE_INCOMPLETE: case TYPE_POLYMORPH: @@ -394,11 +393,7 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope, Array *repl) Ast_Return *src = (Ast_Return *)ast; Ast_Return *dst = ast_create_copy(parent_scope, Ast_Return, ast); - dst->expr.init(pctx->perm, src->expr.len); - For(src->expr) { - auto copy = (Ast_Expr *)ast_copy(it, parent_scope, repl); - dst->expr.add(copy); - } + dst->expr = (Ast_Expr *)ast_copy(src->expr, parent_scope, repl); result = dst; } break; @@ -413,11 +408,7 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope, Array *repl) dst->args.add(copy); } - dst->ret.init(pctx->perm, src->ret.len); - For(src->ret) { - auto copy = (Ast_Expr *)ast_copy(it, parent_scope, repl); - dst->ret.add(copy); - } + dst->ret = (Ast_Expr *)ast_copy(src->ret, parent_scope, repl); dst->scope = (Ast_Scope *)ast_copy(src->scope, parent_scope, repl); result = dst; } break; diff --git a/core_printer.cpp b/core_printer.cpp index 1c0ce95..4898dab 100644 --- a/core_printer.cpp +++ b/core_printer.cpp @@ -77,9 +77,6 @@ core_type_to_string(Ast_Type *type) { String base = core_type_to_string(type->base); return pctx->fmt("[]%Q", base); } break; - case TYPE_TUPLE: { - invalid_codepath; - } break; case TYPE_TYPE: return "Type"_s; break; case TYPE_UNTYPED_BOOL: return "UntypedBool"_s; break; @@ -342,10 +339,7 @@ void core__stringify(Ast *ast) { case AST_RETURN: { Ast_Return *n = (Ast_Return *)ast; gen("return "); - For(n->expr) { - core__stringify(it); - if (!n->expr.is_last(it)) gen(", "); - } + core__stringify(n->expr); } break; case AST_LAMBDA_EXPR: { @@ -358,12 +352,8 @@ void core__stringify(Ast *ast) { } gen(")"); - if (n->ret.len) gen(": "); - For(n->ret) { - core__stringify(it); - if (!n->ret.is_last(it)) gen(", "); - } - + if (n->ret) gen(": "); + core__stringify(n->ret); core__stringify(n->scope); } break; diff --git a/core_typechecking.cpp b/core_typechecking.cpp index 623977a..b6c678d 100644 --- a/core_typechecking.cpp +++ b/core_typechecking.cpp @@ -723,48 +723,25 @@ require_const_int(Ast_Expr *expr, Resolve_Flag flags) { return op; } -// @note: Ret is return value of CORE_Static passed down the stack -// to check if type matches -CORE_Static void -resolve_stmt(Ast *ast, Ast_Type *ret) { +// ret is return value passed down the stack to check if type matches +CORE_Static void resolve_stmt(Ast *ast, Ast_Type *ret) { if (!ast) return; assert(ast->parent_scope->kind == AST_SCOPE); if (ast->flags & AST_COMPILER_BREAKPOINT) Breakpoint; switch (ast->kind) { CASE(RETURN, Return) { // @todo: need to check if all paths return a value - Scoped_Arena scratch(pctx->scratch); - Array types = {scratch.arena}; - - int i = 0; - For(node->expr) { - Operand op; - if (is_tuple(ret)) { - Ast_Type *sub_type = ret->agg.members[i].type; - op = resolve_expr(it, AST_CAN_BE_NULL, sub_type, 0); - } - else { - op = resolve_expr(it, AST_CAN_BE_NULL, ret, 0); - convert_untyped_to_typed(node->pos, &op.value, ret); - } - - types.add(op.type); - i += 1; + Ast_Type *value_type = pctx->type_void; + if (node->expr) { + Operand op = resolve_expr(node->expr, AST_CAN_BE_NULL, ret, 0); + convert_untyped_to_typed(node->pos, &op.value, ret); + value_type = op.type; } - Ast_Type *type = type_try_tupling(types, node); - if (type && type != ret) - compiler_error(node->pos, "Return statement has different type then returned value, expecting: %Q got instead %Q", typestring(ret), typestring(type)); - node->resolved_type = type; + if (value_type != ret) compiler_error(node->pos, "Return statement has different type then returned value, expecting: %Q got instead %Q", typestring(ret), typestring(value_type)); + node->resolved_type = ret; - i = 0; - For(node->expr) { - Ast_Type *sub_type = type; - if (is_tuple(type)) sub_type = type->agg.members[i].type; - - try_propagating_resolved_type_to_untyped_literals(it, sub_type); - i += 1; - } + if (node->expr) try_propagating_resolved_type_to_untyped_literals(node->expr, ret); BREAK(); } @@ -877,8 +854,8 @@ resolve_stmt(Ast *ast, Ast_Type *ret) { CASE(VAR_UNPACK, Var_Unpack) { Operand expr_op = resolve_expr(node->expr, AST_CANT_BE_NULL, 0, 0); - if (!is_tuple(expr_op.type)) - compiler_error(node->pos, "Expected expression to be of type [Tuple]"); + if (!is_struct_union(expr_op.type)) + compiler_error(node->pos, "Expected expression to have either [Struct] or [Union] type"); if (expr_op.type->agg.members.len != node->vars.len) compiler_error(node->pos, "Different count of return values and assigning values"); node->resolved_type = expr_op.type; @@ -907,11 +884,8 @@ CORE_Static Ast_Type * resolve_lambda_type(Ast_Lambda *lambda) { Scoped_Arena scratch(pctx->scratch); Array args = {scratch.arena}; - Array ret = {scratch.arena}; - For(lambda->ret) { - Ast_Type *type = resolve_typespec(it, AST_CANT_BE_NULL); - ret.add(type); - } + Ast_Type *ret = resolve_typespec(lambda->ret, AST_CAN_BE_NULL); + if (!ret) ret = pctx->type_void; For(lambda->args) { if (it->name == pctx->intern("..."_s)) { @@ -1343,7 +1317,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_and_const_str if (is_pointer(type)) type = type->base; type_complete(type); - bool is_dottable_type = type->kind == TYPE_STRUCT || type->kind == TYPE_UNION; + bool is_dottable_type = type->kind == TYPE_ENUM || type->kind == TYPE_STRUCT || type->kind == TYPE_UNION; if (is_dottable_type == false) compiler_error(node->pos, "Type %Q doesn't have anything to access using '.' operator", typestring(type)); scope = ((Ast_Decl *)type->ast)->scope; @@ -1377,10 +1351,6 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_and_const_str if (operator_overload) { proceed_to_default_operator_handler = false; - if (operator_overload->lambda->ret.len != 1) { - compiler_error(operator_overload->pos, "Operator overload is required to have exactly 1 return value"); - } - left.value = left_copy; right.value = right_copy; // @warning: might be buggy, added after a long break @@ -1468,10 +1438,6 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_and_const_str Ast_Decl *operator_overload = resolve_operator_overload(node->parent_scope, value.type, 0, node->pos, node->op, hash); if (operator_overload) { proceed_to_default_operator_handler = false; - if (operator_overload->lambda->ret.len != 1) { - compiler_error(operator_overload->pos, "Operator overload is required to have exactly 1 return value"); - } - node->resolved_type = operator_overload->type->func.ret; node->resolved_operator_overload = operator_overload; } diff --git a/core_types.cpp b/core_types.cpp index e478eef..87fecc4 100644 --- a/core_types.cpp +++ b/core_types.cpp @@ -26,7 +26,6 @@ get_name_of_type(Ast_Type *type) { case TYPE_U16: return "U16"; case TYPE_U32: return "U32"; case TYPE_U64: return "U64"; - case TYPE_TUPLE: return "Tuple"; case TYPE_TYPE: return "Type"; case TYPE_POLYMORPH: @@ -42,10 +41,10 @@ get_name_of_type(Ast_Type *type) { force_inline B32 is_any(Ast_Type *a) { return a == pctx->type_any; } force_inline B32 is_struct(Ast_Type *a) { return a->kind == TYPE_STRUCT; } force_inline B32 is_union(Ast_Type *a) { return a->kind == TYPE_UNION; } +force_inline B32 is_struct_union(Ast_Type *a) { return a->kind == TYPE_UNION || a->kind == TYPE_STRUCT; } force_inline B32 is_lambda(Ast_Type *a) { return a->kind == TYPE_LAMBDA; } force_inline B32 is_array(Ast_Type *a) { return a->kind == TYPE_ARRAY; } force_inline B32 is_slice(Ast_Type *a) { return a->kind == TYPE_SLICE; } -force_inline B32 is_tuple(Ast_Type *a) { return a->kind == TYPE_TUPLE; } force_inline B32 is_enum(Ast_Type *a) { return a->kind == TYPE_ENUM; } force_inline B32 is_pointer(Ast_Type *a) { return a->kind == TYPE_POINTER; } force_inline B32 is_void(Ast_Type *a) { return a->kind == TYPE_VOID; } @@ -71,12 +70,12 @@ force_inline B32 is_numeric(Ast_Type *type) { // Hash consed types //----------------------------------------------------------------------------- CORE_Static Ast_Type * -type_new(Allocator *allocator, Ast_Type_Kind kind, int32_t size, int32_t align) { +type_new(Allocator *allocator, Ast_Type_Kind kind, int32_t size, int32_t align, bool generate_type_id = true) { Ast_Type *result = allocate_struct(allocator, Ast_Type, true); result->kind = kind; result->size = size; result->align = align; - result->type_id = pctx->type_ids++; + if (generate_type_id) result->type_id = pctx->type_ids++; add(pctx->perm, &pctx->all_types, result); return result; } @@ -127,37 +126,6 @@ type_slice(Ast_Type *base, Ast *ast) { return result; } -CORE_Static Ast_Type * -type_try_tupling(Array types, Ast *ast) { - if (types.len == 0) return pctx->type_void; - if (types.len == 1) return types[0]; - - U64 hash = 13; - For(types) hash = hash_mix(hash, hash_ptr(it)); - Ast_Type *result = (Ast_Type *)map_get(&pctx->type_map, hash); - if (result) { - assert(result->kind == TYPE_TUPLE); - assert(result->agg.members.len == types.len); - assert(result->agg.members.len > 1); - return result; - } - - // @todo alignment, offsets - result = type_new(pctx->perm, TYPE_TUPLE, 0, pointer_align); - result->agg.members.init(pctx->perm, types.len); - For(types) { - Ast_Resolved_Member m = {}; - m.type = it; - m.offset = 0; // @todo - result->size += it->size; - result->agg.members.add(m); - } - map_insert(&pctx->type_map, hash, result); - assert(result->agg.members.len > 1); - - return result; -} - CORE_Static Ast_Type * type_array(Ast_Type *base, S32 size) { U64 hash_base = hash_ptr(base); @@ -178,24 +146,21 @@ type_array(Ast_Type *base, S32 size) { return result; } -inline U64 -calculate_hash_for_arguments(Ast_Type *a, Ast_Type *b) { +inline U64 calculate_hash_for_arguments(Ast_Type *a, Ast_Type *b) { U64 result = 13; result = hash_mix(result, hash_ptr(a)); result = hash_mix(result, hash_ptr(b)); return result; } -inline U64 -calculate_hash_for_arguments(Ast_Type *a) { +inline U64 calculate_hash_for_arguments(Ast_Type *a) { U64 result = 13; result = hash_mix(result, hash_ptr(a)); return result; } CORE_Static Ast_Type * -type_lambda(Ast *ast, Array return_vals, Array args) { - Ast_Type *ret = type_try_tupling(return_vals, ast); +type_lambda(Ast *ast, Ast_Type *ret, Array args) { U64 hash_without_ret = 13; For(args) hash_without_ret = hash_mix(hash_without_ret, hash_ptr(it)); U64 hash = hash_mix(hash_ptr(ret), hash_without_ret); @@ -232,8 +197,14 @@ type_enum(Ast_Decl *ast, Ast_Type *type) { CORE_Static Ast_Type * type_incomplete(Ast *ast) { Ast_Type_Kind kind = TYPE_INCOMPLETE; - if (is_flag_set(ast->flags, AST_POLYMORPH)) kind = TYPE_POLYMORPH; - Ast_Type *result = type_new(pctx->perm, kind, 0, 0); + + bool generate_type_id = true; + if (is_flag_set(ast->flags, AST_POLYMORPH)) { + kind = TYPE_POLYMORPH; + generate_type_id = false; + } + + Ast_Type *result = type_new(pctx->perm, kind, 0, 0, generate_type_id); result->ast = ast; return result; }