Core: Remove AST_Tuple, repurpose VAR_UNPACK (buggy probably)

This commit is contained in:
Krzosa Karol
2023-04-21 22:49:15 +02:00
parent 108ec6121e
commit bbd8b0ab91
12 changed files with 92 additions and 238 deletions

View File

@@ -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 ..

View File

@@ -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)

View File

@@ -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

View File

@@ -110,11 +110,11 @@ ast_expr_index(Token *pos, Ast_Expr *expr, Ast_Expr *index) {
}
CORE_Static Ast_Lambda *
ast_lambda(Token *pos, Array<Ast_Decl *> params, Array<Ast_Expr *> ret, Ast_Scope *scope) {
ast_lambda(Token *pos, Array<Ast_Decl *> 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<Ast_Expr *> 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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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<Ast_Expr *> expr;
Ast_Expr *expr;
};
struct Ast_If_Node : Ast {
@@ -538,16 +537,7 @@ struct Ast_For : Ast {
struct Ast_Lambda : Ast_Expr {
Array<Ast_Decl *> 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<Ast_Expr *> ret;
Ast_Expr *ret;
Ast_Scope *scope;
};

View File

@@ -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<Ast_Expr *> 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<Ast_Decl *> params = parse_parameter_list(scratch.arena);
Array<Ast_Expr *> 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;

View File

@@ -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<Poly_Replacement> *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<Poly_Replacement> *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;

View File

@@ -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;

View File

@@ -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<Ast_Type *> 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<Ast_Type *> args = {scratch.arena};
Array<Ast_Type *> 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;
}

View File

@@ -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<Ast_Type *> 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<Ast_Type *> return_vals, Array<Ast_Type *> args) {
Ast_Type *ret = type_try_tupling(return_vals, ast);
type_lambda(Ast *ast, Ast_Type *ret, Array<Ast_Type *> 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;
}