Core: Remove AST_Tuple, repurpose VAR_UNPACK (buggy probably)
This commit is contained in:
@@ -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 ..
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
15
core_ast.cpp
15
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<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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user