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 bld --dont_compile_core
cd build 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 bld --dont_compile_core --link=vendor/raylib/windows/raylibdll.lib
rem build\generated_main.exe rem build\generated_main.exe
cd .. cd ..

View File

@@ -30,7 +30,7 @@ QuestionMark16 :: 0x003f
String32 :: struct;; str: *U32; len: int String32 :: struct;; str: *U32; len: int
String16 :: struct;; str: *U16; 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 out_str: U32
advance: int advance: int
if (c[0] & 0b10000000) == 0 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) out_str = (c0 & 0b00001111) << 18 | (c1 & 0b00111111) << 12 | (c2 & 0b00111111) << 6 | (c3 & 0b00111111)
advance = 4 advance = 4
return out_str, advance return {out_str, advance}
Utf32ToUtf16 :: (codepoint: U32): [2]U16, int Utf32ToUtf16 :: (codepoint: U32): Two([2]U16, int)
str: [2]U16 result: Two([2]U16, int)
len := 0
if codepoint < 0x10000 if codepoint < 0x10000
str[0] = codepoint->U16 result.a[0] = codepoint->U16
len = 1 result.b = 1
elif codepoint <= 0x10FFFF elif codepoint <= 0x10FFFF
code: U32 = (codepoint - 0x10000) code: U32 = (codepoint - 0x10000)
str[0] = (0xD800 | (code >> 10))->U16 result.a[0] = (0xD800 | (code >> 10))->U16
str[1] = (0xDC00 | (code & 0x3FF))->U16 result.a[1] = (0xDC00 | (code & 0x3FF))->U16
len = 2 result.b = 2
return result
return str, len
StringToString16 :: (arena: *Arena, in: String): String16 StringToString16 :: (arena: *Arena, in: String): String16
in_str := &in[0] in_str := &in[0]
@@ -82,7 +80,9 @@ StringToString16 :: (arena: *Arena, in: String): String16
alloc_size := (Len(in)*2)+1 alloc_size := (Len(in)*2)+1
result := String16{str = PushSize(arena, alloc_size->U64)} result := String16{str = PushSize(arena, alloc_size->U64)}
for i := 0, i < Len(in) 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 if s32_len != 0
i += s32_len i += s32_len
s16, s16_len := Utf32ToUtf16(s32) 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 SetWindowPos :: #foreign (hWnd: HWND, hWndInsertAfter: HWND, X: int, Y: int, cx: int, cy: int, uFlags: UINT): BOOL
GetClientRect :: #foreign (hWnd: HWND, lpRect: LPRECT): BOOL GetClientRect :: #foreign (hWnd: HWND, lpRect: LPRECT): BOOL
CW_USEDEFAULT :: -2147483648//0x80000000 CW_USEDEFAULT :: 0x80000000-1 // -2147483648
WS_CAPTION :: 0x00C00000 WS_CAPTION :: 0x00C00000

View File

@@ -110,11 +110,11 @@ ast_expr_index(Token *pos, Ast_Expr *expr, Ast_Expr *index) {
} }
CORE_Static Ast_Lambda * 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); AST_NEW(Lambda, LAMBDA_EXPR, pos, AST_EXPR);
result->flags = AST_EXPR; result->flags = AST_EXPR;
result->args = params.tight_copy(pctx->perm); result->args = params.tight_copy(pctx->perm);
result->ret = ret.tight_copy(pctx->perm); result->ret = ret;
result->scope = scope; result->scope = scope;
if (scope) scope->parent_ast = result; if (scope) scope->parent_ast = result;
@@ -171,12 +171,9 @@ ast_continue(Token *pos) {
} }
CORE_Static Ast_Return * 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); AST_NEW(Return, RETURN, pos, AST_STMT);
if (expr.len) { result->expr = expr;
For(expr) assert(is_flag_set(it->flags, AST_EXPR));
result->expr = expr.tight_copy(pctx->perm);
}
return result; return result;
} }
@@ -623,14 +620,14 @@ void next(Ast_Iter *iter) {
case AST_RETURN: { case AST_RETURN: {
Ast_Return *node = (Ast_Return *)ast; Ast_Return *node = (Ast_Return *)ast;
if (!iter->skip_end_blocks) iter->stack.add(node); 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; } break;
case AST_LAMBDA_EXPR: { case AST_LAMBDA_EXPR: {
Ast_Lambda *node = (Ast_Lambda *)ast; Ast_Lambda *node = (Ast_Lambda *)ast;
if (!iter->skip_end_blocks) iter->stack.add(node); if (!iter->skip_end_blocks) iter->stack.add(node);
if (node->scope) iter->stack.add(node->scope); 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); For(node->args) iter->stack.add(it);
} break; } break;

View File

@@ -72,7 +72,6 @@ get_ctype_name_for_type(Ast_Type *type) {
case TYPE_U16: return "uint16_t"; case TYPE_U16: return "uint16_t";
case TYPE_U32: return "uint32_t"; case TYPE_U32: return "uint32_t";
case TYPE_U64: return "uint64_t"; case TYPE_U64: return "uint64_t";
case TYPE_TUPLE: return "Tuple";
case TYPE_TYPE: return "int64_t"; case TYPE_TYPE: return "int64_t";
case TYPE_INCOMPLETE: { case TYPE_INCOMPLETE: {
@@ -105,10 +104,6 @@ string_simple_decl_prefix(Ast_Type *ast) {
string = pctx->fmt("Slice%llu ", ast->type_id); string = pctx->fmt("Slice%llu ", ast->type_id);
return string; return string;
} break; } break;
case TYPE_TUPLE: {
String string = pctx->fmt("Tuple%llu ", ast->type_id);
return string;
} break;
case TYPE_UNION: case TYPE_UNION:
case TYPE_STRUCT: { case TYPE_STRUCT: {
auto constant = (Ast_Decl *)ast->ast; auto constant = (Ast_Decl *)ast->ast;
@@ -189,6 +184,7 @@ get_type_postfix(Ast_Type *type) {
case TYPE_U8: case TYPE_U8:
case TYPE_UCHAR: case TYPE_UCHAR:
case TYPE_U16: case TYPE_U16:
case TYPE_UINT:
case TYPE_U32: return "U"_s; break; case TYPE_U32: return "U"_s; break;
case TYPE_SHORT: case TYPE_SHORT:
@@ -585,39 +581,8 @@ gen_ast(Ast *ast) {
} }
CASE(RETURN, Return) { 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 "); gen("return ");
For(node->expr) gen_expr(it); gen_expr(node->expr);
gen(";"); gen(";");
BREAK(); BREAK();
} }
@@ -814,10 +779,10 @@ gen_ast(Ast *ast) {
} }
CASE(VAR_UNPACK, Var_Unpack) { CASE(VAR_UNPACK, Var_Unpack) {
For(node->vars) Ast_Type *t = node->resolved_type;
For(node->vars) {
gen_ast(it); gen_ast(it);
}
Scoped_Arena scratch(pctx->scratch);
Intern_String var_name = get_unique_name(); Intern_String var_name = get_unique_name();
gen_simple_decl(node->resolved_type, var_name); gen_simple_decl(node->resolved_type, var_name);
@@ -827,7 +792,12 @@ gen_ast(Ast *ast) {
int i = 0; int i = 0;
For(node->vars) { 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(); BREAK();
} }
@@ -926,10 +896,8 @@ int printf(const char *format, ...);
} }
} }
// Generate slice and tuple types // Generate slice types
For2(pctx->all_types, type) { For2(pctx->all_types, type) {
Scoped_Arena scratch(pctx->scratch);
if (type->kind == TYPE_SLICE) { if (type->kind == TYPE_SLICE) {
genln("typedef struct Slice%llu{", type->type_id); genln("typedef struct Slice%llu{", type->type_id);
global_indent++; global_indent++;
@@ -940,20 +908,6 @@ int printf(const char *format, ...);
global_indent--; global_indent--;
genln("} Slice%llu;", type->type_id); 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); Intern_String intern_main = pctx->intern("main"_s);
@@ -994,12 +948,15 @@ int printf(const char *format, ...);
} }
// Generate type info // 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[]){"); genln("Type_Info *type_infos = (Type_Info[]){");
global_indent++; global_indent++;
int i = 0;
For2(pctx->all_types, t) { For2(pctx->all_types, t) {
if (t->kind == TYPE_POLYMORPH) continue; 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)); genln("{/*%Q*/", typestring(t));
global_indent += 1; global_indent += 1;
@@ -1042,9 +999,11 @@ int printf(const char *format, ...);
global_indent -= 1; global_indent -= 1;
genln("}"); genln("}");
} break; } break;
case AST_ENUM: {
// todo;
} break;
default: { default: {
} }
// invalid_default_case;
} }
end_of_switch:; end_of_switch:;
global_indent -= 1; global_indent -= 1;

View File

@@ -335,7 +335,11 @@ Any :: struct
String :: struct String :: struct
data: *U8 data: *U8
len: S64 len: int
Two :: struct($A: Type, $B: Type)
a: A
b: B
Type_Info_Kind :: enum Type_Info_Kind :: enum
S64 // FIRST_NUMERIC S64 // FIRST_NUMERIC
@@ -366,26 +370,26 @@ Type_Info_Kind :: enum
Type_Info_Struct_Member :: struct Type_Info_Struct_Member :: struct
name: String name: String
type: Type type: Type
offset: S64 offset: int
Type_Info :: struct Type_Info :: struct
kind: Type_Info_Kind kind: Type_Info_Kind
size: S64 size: int
align: S64 align: int
is_unsigned: bool is_unsigned: bool
type: Type type: Type
base_type: Type base_type: Type
array_size: S64 array_size: int
struct_members: []Type_Info_Struct_Member struct_members: []Type_Info_Struct_Member
lambda_arguments: []Type_Info lambda_arguments: []Type_Info
lambda_return: Type lambda_return: Type
type_infos_len: S64 #foreign type_infos_len: int #foreign
type_infos : *Type_Info #foreign type_infos : *Type_Info #foreign
GetTypeInfo :: (type: Type): *Type_Info GetTypeInfo :: (type: Type): *Type_Info
id := type->S64 id := type->int
if id >= type_infos_len if id >= type_infos_len
return 0 return 0
return type_infos + id return type_infos + id

View File

@@ -218,7 +218,6 @@ enum Ast_Type_Kind {
TYPE_ENUM, TYPE_ENUM,
TYPE_TYPE, TYPE_TYPE,
TYPE_SLICE, TYPE_SLICE,
TYPE_TUPLE,
TYPE_COMPLETING, TYPE_COMPLETING,
TYPE_INCOMPLETE, TYPE_INCOMPLETE,
@@ -509,7 +508,7 @@ struct Ast_Builtin : Ast_Expr {
struct Ast_Return : Ast { struct Ast_Return : Ast {
Ast_Type *resolved_type; Ast_Type *resolved_type;
Array<Ast_Expr *> expr; Ast_Expr *expr;
}; };
struct Ast_If_Node : Ast { struct Ast_If_Node : Ast {
@@ -538,16 +537,7 @@ struct Ast_For : Ast {
struct Ast_Lambda : Ast_Expr { struct Ast_Lambda : Ast_Expr {
Array<Ast_Decl *> args; Array<Ast_Decl *> args;
Ast_Expr *ret;
// :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_Scope *scope; Ast_Scope *scope;
}; };

View File

@@ -284,13 +284,8 @@ parse_stmt_scope(Ast_Scope *scope_defined_outside = 0) {
Token *token = token_get(); Token *token = token_get();
if (token_match_keyword(pctx->keyword_return)) { if (token_match_keyword(pctx->keyword_return)) {
Array<Ast_Expr *> expr = {scratch.arena}; Ast_Expr *expr = 0;
if (!token_is_scope()) { if (!token_is_scope()) expr = parse_expr();
do {
Ast_Expr *subexpr = parse_expr();
expr.add(subexpr);
} while (token_match(TK_Comma));
}
scope->stmts.add(ast_return(token, expr)); scope->stmts.add(ast_return(token, expr));
} }
@@ -518,17 +513,7 @@ parse_lambda(Token *token) {
Scoped_Arena scratch(pctx->scratch); Scoped_Arena scratch(pctx->scratch);
Array<Ast_Decl *> params = parse_parameter_list(scratch.arena); Array<Ast_Decl *> params = parse_parameter_list(scratch.arena);
Array<Ast_Expr *> ret = {scratch.arena}; Ast_Expr *ret = parse_optional_type();
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_Scope *scope = token_is(OPEN_SCOPE) ? parse_stmt_scope() : 0; Ast_Scope *scope = token_is(OPEN_SCOPE) ? parse_stmt_scope() : 0;
Ast_Lambda *result = ast_lambda(token, params, ret, scope); Ast_Lambda *result = ast_lambda(token, params, ret, scope);
return result; 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; Ast_Expr *result = 0;
switch (type->kind) { switch (type->kind) {
case TYPE_NONE: case TYPE_NONE:
case TYPE_TUPLE:
case TYPE_COMPLETING: case TYPE_COMPLETING:
case TYPE_INCOMPLETE: case TYPE_INCOMPLETE:
case TYPE_POLYMORPH: 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 *src = (Ast_Return *)ast;
Ast_Return *dst = ast_create_copy(parent_scope, Ast_Return, ast); Ast_Return *dst = ast_create_copy(parent_scope, Ast_Return, ast);
dst->expr.init(pctx->perm, src->expr.len); dst->expr = (Ast_Expr *)ast_copy(src->expr, parent_scope, repl);
For(src->expr) {
auto copy = (Ast_Expr *)ast_copy(it, parent_scope, repl);
dst->expr.add(copy);
}
result = dst; result = dst;
} break; } break;
@@ -413,11 +408,7 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope, Array<Poly_Replacement> *repl)
dst->args.add(copy); dst->args.add(copy);
} }
dst->ret.init(pctx->perm, src->ret.len); dst->ret = (Ast_Expr *)ast_copy(src->ret, parent_scope, repl);
For(src->ret) {
auto copy = (Ast_Expr *)ast_copy(it, parent_scope, repl);
dst->ret.add(copy);
}
dst->scope = (Ast_Scope *)ast_copy(src->scope, parent_scope, repl); dst->scope = (Ast_Scope *)ast_copy(src->scope, parent_scope, repl);
result = dst; result = dst;
} break; } break;

View File

@@ -77,9 +77,6 @@ core_type_to_string(Ast_Type *type) {
String base = core_type_to_string(type->base); String base = core_type_to_string(type->base);
return pctx->fmt("[]%Q", base); return pctx->fmt("[]%Q", base);
} break; } break;
case TYPE_TUPLE: {
invalid_codepath;
} break;
case TYPE_TYPE: return "Type"_s; break; case TYPE_TYPE: return "Type"_s; break;
case TYPE_UNTYPED_BOOL: return "UntypedBool"_s; break; case TYPE_UNTYPED_BOOL: return "UntypedBool"_s; break;
@@ -342,10 +339,7 @@ void core__stringify(Ast *ast) {
case AST_RETURN: { case AST_RETURN: {
Ast_Return *n = (Ast_Return *)ast; Ast_Return *n = (Ast_Return *)ast;
gen("return "); gen("return ");
For(n->expr) { core__stringify(n->expr);
core__stringify(it);
if (!n->expr.is_last(it)) gen(", ");
}
} break; } break;
case AST_LAMBDA_EXPR: { case AST_LAMBDA_EXPR: {
@@ -358,12 +352,8 @@ void core__stringify(Ast *ast) {
} }
gen(")"); gen(")");
if (n->ret.len) gen(": "); if (n->ret) gen(": ");
For(n->ret) { core__stringify(n->ret);
core__stringify(it);
if (!n->ret.is_last(it)) gen(", ");
}
core__stringify(n->scope); core__stringify(n->scope);
} break; } break;

View File

@@ -723,48 +723,25 @@ require_const_int(Ast_Expr *expr, Resolve_Flag flags) {
return op; return op;
} }
// @note: Ret is return value of CORE_Static passed down the stack // ret is return value passed down the stack to check if type matches
// to check if type matches CORE_Static void resolve_stmt(Ast *ast, Ast_Type *ret) {
CORE_Static void
resolve_stmt(Ast *ast, Ast_Type *ret) {
if (!ast) return; if (!ast) return;
assert(ast->parent_scope->kind == AST_SCOPE); assert(ast->parent_scope->kind == AST_SCOPE);
if (ast->flags & AST_COMPILER_BREAKPOINT) Breakpoint; if (ast->flags & AST_COMPILER_BREAKPOINT) Breakpoint;
switch (ast->kind) { switch (ast->kind) {
CASE(RETURN, Return) { // @todo: need to check if all paths return a value CASE(RETURN, Return) { // @todo: need to check if all paths return a value
Scoped_Arena scratch(pctx->scratch); Ast_Type *value_type = pctx->type_void;
Array<Ast_Type *> types = {scratch.arena}; if (node->expr) {
Operand op = resolve_expr(node->expr, AST_CAN_BE_NULL, ret, 0);
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); convert_untyped_to_typed(node->pos, &op.value, ret);
value_type = op.type;
} }
types.add(op.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));
i += 1; node->resolved_type = ret;
}
Ast_Type *type = type_try_tupling(types, node); if (node->expr) try_propagating_resolved_type_to_untyped_literals(node->expr, ret);
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;
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;
}
BREAK(); BREAK();
} }
@@ -877,8 +854,8 @@ resolve_stmt(Ast *ast, Ast_Type *ret) {
CASE(VAR_UNPACK, Var_Unpack) { CASE(VAR_UNPACK, Var_Unpack) {
Operand expr_op = resolve_expr(node->expr, AST_CANT_BE_NULL, 0, 0); Operand expr_op = resolve_expr(node->expr, AST_CANT_BE_NULL, 0, 0);
if (!is_tuple(expr_op.type)) if (!is_struct_union(expr_op.type))
compiler_error(node->pos, "Expected expression to be of type [Tuple]"); compiler_error(node->pos, "Expected expression to have either [Struct] or [Union] type");
if (expr_op.type->agg.members.len != node->vars.len) if (expr_op.type->agg.members.len != node->vars.len)
compiler_error(node->pos, "Different count of return values and assigning values"); compiler_error(node->pos, "Different count of return values and assigning values");
node->resolved_type = expr_op.type; node->resolved_type = expr_op.type;
@@ -907,11 +884,8 @@ CORE_Static Ast_Type *
resolve_lambda_type(Ast_Lambda *lambda) { resolve_lambda_type(Ast_Lambda *lambda) {
Scoped_Arena scratch(pctx->scratch); Scoped_Arena scratch(pctx->scratch);
Array<Ast_Type *> args = {scratch.arena}; Array<Ast_Type *> args = {scratch.arena};
Array<Ast_Type *> ret = {scratch.arena}; Ast_Type *ret = resolve_typespec(lambda->ret, AST_CAN_BE_NULL);
For(lambda->ret) { if (!ret) ret = pctx->type_void;
Ast_Type *type = resolve_typespec(it, AST_CANT_BE_NULL);
ret.add(type);
}
For(lambda->args) { For(lambda->args) {
if (it->name == pctx->intern("..."_s)) { 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; if (is_pointer(type)) type = type->base;
type_complete(type); 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)); 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; 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) { if (operator_overload) {
proceed_to_default_operator_handler = false; 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; left.value = left_copy;
right.value = right_copy; right.value = right_copy;
// @warning: might be buggy, added after a long break // @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); Ast_Decl *operator_overload = resolve_operator_overload(node->parent_scope, value.type, 0, node->pos, node->op, hash);
if (operator_overload) { if (operator_overload) {
proceed_to_default_operator_handler = false; 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_type = operator_overload->type->func.ret;
node->resolved_operator_overload = operator_overload; 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_U16: return "U16";
case TYPE_U32: return "U32"; case TYPE_U32: return "U32";
case TYPE_U64: return "U64"; case TYPE_U64: return "U64";
case TYPE_TUPLE: return "Tuple";
case TYPE_TYPE: case TYPE_TYPE:
return "Type"; return "Type";
case TYPE_POLYMORPH: 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_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_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_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_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_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_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_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_pointer(Ast_Type *a) { return a->kind == TYPE_POINTER; }
force_inline B32 is_void(Ast_Type *a) { return a->kind == TYPE_VOID; } 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 // Hash consed types
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
CORE_Static Ast_Type * 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); Ast_Type *result = allocate_struct(allocator, Ast_Type, true);
result->kind = kind; result->kind = kind;
result->size = size; result->size = size;
result->align = align; 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); add(pctx->perm, &pctx->all_types, result);
return result; return result;
} }
@@ -127,37 +126,6 @@ type_slice(Ast_Type *base, Ast *ast) {
return result; 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 * CORE_Static Ast_Type *
type_array(Ast_Type *base, S32 size) { type_array(Ast_Type *base, S32 size) {
U64 hash_base = hash_ptr(base); U64 hash_base = hash_ptr(base);
@@ -178,24 +146,21 @@ type_array(Ast_Type *base, S32 size) {
return result; return result;
} }
inline U64 inline U64 calculate_hash_for_arguments(Ast_Type *a, Ast_Type *b) {
calculate_hash_for_arguments(Ast_Type *a, Ast_Type *b) {
U64 result = 13; U64 result = 13;
result = hash_mix(result, hash_ptr(a)); result = hash_mix(result, hash_ptr(a));
result = hash_mix(result, hash_ptr(b)); result = hash_mix(result, hash_ptr(b));
return result; return result;
} }
inline U64 inline U64 calculate_hash_for_arguments(Ast_Type *a) {
calculate_hash_for_arguments(Ast_Type *a) {
U64 result = 13; U64 result = 13;
result = hash_mix(result, hash_ptr(a)); result = hash_mix(result, hash_ptr(a));
return result; return result;
} }
CORE_Static Ast_Type * CORE_Static Ast_Type *
type_lambda(Ast *ast, Array<Ast_Type *> return_vals, Array<Ast_Type *> args) { type_lambda(Ast *ast, Ast_Type *ret, Array<Ast_Type *> args) {
Ast_Type *ret = type_try_tupling(return_vals, ast);
U64 hash_without_ret = 13; U64 hash_without_ret = 13;
For(args) hash_without_ret = hash_mix(hash_without_ret, hash_ptr(it)); For(args) hash_without_ret = hash_mix(hash_without_ret, hash_ptr(it));
U64 hash = hash_mix(hash_ptr(ret), hash_without_ret); 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 * CORE_Static Ast_Type *
type_incomplete(Ast *ast) { type_incomplete(Ast *ast) {
Ast_Type_Kind kind = TYPE_INCOMPLETE; 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; result->ast = ast;
return result; return result;
} }