mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-11 05:41:25 -07:00
match to switch; Optional semicolons after "import" statements
This commit is contained in:
+8
-1
@@ -234,7 +234,7 @@ void check_const_decl(Checker *c, Entity *e, AstNode *type_expr, AstNode *init,
|
||||
d->type_expr = d->init_expr;
|
||||
check_type_decl(c, e, d->type_expr, named_type);
|
||||
return;
|
||||
} break;
|
||||
}
|
||||
|
||||
// NOTE(bill): Check to see if the expression it to be aliases
|
||||
#if 1
|
||||
@@ -446,6 +446,13 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) {
|
||||
error(e->token, "Procedure `main` cannot have a custom calling convention");
|
||||
}
|
||||
pt->calling_convention = ProcCC_Contextless;
|
||||
if (d->scope->is_init) {
|
||||
if (c->info.entry_point != nullptr) {
|
||||
error(e->token, "Redeclaration of the entry pointer procedure `main`");
|
||||
} else {
|
||||
c->info.entry_point = e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_inline && is_no_inline) {
|
||||
|
||||
+141
-58
@@ -2469,7 +2469,8 @@ Type *type_to_abi_compat_param_type(gbAllocator a, Type *original_type) {
|
||||
if (sz > 8 && build_context.word_size < 8) {
|
||||
new_type = make_type_pointer(a, original_type);
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
case Type_Pointer: break;
|
||||
case Type_Proc: break; // NOTE(bill): Just a pointer
|
||||
|
||||
@@ -2495,7 +2496,9 @@ Type *type_to_abi_compat_param_type(gbAllocator a, Type *original_type) {
|
||||
new_type = make_type_pointer(a, original_type);
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (build_context.ODIN_OS == "linux" ||
|
||||
build_context.ODIN_OS == "osx") {
|
||||
@@ -2508,7 +2511,9 @@ Type *type_to_abi_compat_param_type(gbAllocator a, Type *original_type) {
|
||||
if (sz > 8 && build_context.word_size < 8) {
|
||||
new_type = make_type_pointer(a, original_type);
|
||||
}
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
case Type_Pointer: break;
|
||||
case Type_Proc: break; // NOTE(bill): Just a pointer
|
||||
|
||||
@@ -2528,7 +2533,9 @@ Type *type_to_abi_compat_param_type(gbAllocator a, Type *original_type) {
|
||||
if (8*size > 16) {
|
||||
new_type = make_type_pointer(a, original_type);
|
||||
}
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// IMPORTANT TODO(bill): figure out the ABI settings for Linux, OSX etc. for
|
||||
@@ -2579,7 +2586,9 @@ Type *type_to_abi_compat_result_type(gbAllocator a, Type *original_type) {
|
||||
case 64: new_type = t_u64; break;
|
||||
#endif
|
||||
}
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (build_context.ODIN_OS == "linux") {
|
||||
|
||||
@@ -3031,26 +3040,29 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type)
|
||||
|
||||
switch (e->kind) {
|
||||
case_ast_node(i, Ident, e);
|
||||
|
||||
Operand o = {};
|
||||
check_ident(c, &o, e, named_type, nullptr, false);
|
||||
|
||||
gbString err_str;
|
||||
switch (o.mode) {
|
||||
case Addressing_Invalid:
|
||||
break;
|
||||
case Addressing_Type: {
|
||||
case Addressing_Type:
|
||||
*type = o.type;
|
||||
return true;
|
||||
} break;
|
||||
case Addressing_NoValue: {
|
||||
gbString err_str = expr_to_string(e);
|
||||
|
||||
case Addressing_NoValue:
|
||||
err_str = expr_to_string(e);
|
||||
error(e, "`%s` used as a type", err_str);
|
||||
gb_string_free(err_str);
|
||||
} break;
|
||||
default: {
|
||||
gbString err_str = expr_to_string(e);
|
||||
break;
|
||||
|
||||
default:
|
||||
err_str = expr_to_string(e);
|
||||
error(e, "`%s` used as a type when not a type", err_str);
|
||||
gb_string_free(err_str);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
case_end;
|
||||
|
||||
@@ -3104,6 +3116,7 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type)
|
||||
Operand o = {};
|
||||
check_selector(c, &o, e, nullptr);
|
||||
|
||||
gbString err_str;
|
||||
switch (o.mode) {
|
||||
case Addressing_Invalid:
|
||||
break;
|
||||
@@ -3111,16 +3124,16 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type)
|
||||
GB_ASSERT(o.type != nullptr);
|
||||
*type = o.type;
|
||||
return true;
|
||||
case Addressing_NoValue: {
|
||||
gbString err_str = expr_to_string(e);
|
||||
case Addressing_NoValue:
|
||||
err_str = expr_to_string(e);
|
||||
error(e, "`%s` used as a type", err_str);
|
||||
gb_string_free(err_str);
|
||||
} break;
|
||||
default: {
|
||||
gbString err_str = expr_to_string(e);
|
||||
break;
|
||||
default:
|
||||
err_str = expr_to_string(e);
|
||||
error(e, "`%s` is not a type", err_str);
|
||||
gb_string_free(err_str);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
case_end;
|
||||
|
||||
@@ -3533,7 +3546,8 @@ bool check_representable_as_constant(Checker *c, ExactValue in_value, Type *type
|
||||
if (out_value) *out_value = exact_binary_operator_value(Token_Add, real, exact_value_make_imag(imag));
|
||||
return true;
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
case Basic_UntypedComplex:
|
||||
return true;
|
||||
|
||||
@@ -3724,9 +3738,9 @@ void check_comparison(Checker *c, Operand *x, Operand *y, TokenKind op) {
|
||||
case Token_Lt:
|
||||
case Token_Gt:
|
||||
case Token_LtEq:
|
||||
case Token_GtEq: {
|
||||
case Token_GtEq:
|
||||
defined = is_type_ordered(x->type);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!defined) {
|
||||
@@ -4176,7 +4190,9 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) {
|
||||
if (xt) error_operand_not_expression(x);
|
||||
if (yt) error_operand_not_expression(y);
|
||||
}
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
check_expr(c, x, be->left);
|
||||
@@ -4522,7 +4538,9 @@ void convert_to_typed(Checker *c, Operand *operand, Type *target_type, i32 level
|
||||
convert_untyped_error(c, operand, target_type);
|
||||
return;
|
||||
}
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case Type_Union:
|
||||
if (!is_operand_nil(*operand) && !is_operand_undef(*operand)) {
|
||||
@@ -5112,7 +5130,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
|
||||
operand->type = t_source_code_location;
|
||||
operand->mode = Addressing_Value;
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case BuiltinProc_len:
|
||||
case BuiltinProc_cap: {
|
||||
@@ -5159,7 +5179,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
operand->mode = mode;
|
||||
operand->value = value;
|
||||
operand->type = type;
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
#if 0
|
||||
case BuiltinProc_new: {
|
||||
@@ -5173,7 +5195,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
}
|
||||
operand->mode = Addressing_Value;
|
||||
operand->type = make_type_pointer(c->allocator, type);
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
case BuiltinProc_new_slice: {
|
||||
@@ -5212,7 +5236,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
|
||||
operand->mode = Addressing_Value;
|
||||
operand->type = make_type_slice(c->allocator, type);
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case BuiltinProc_make: {
|
||||
// proc make(Type, len: int) -> Type
|
||||
@@ -5268,7 +5294,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
|
||||
operand->mode = Addressing_Value;
|
||||
operand->type = type;
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
#if 0
|
||||
case BuiltinProc_free: {
|
||||
@@ -5299,7 +5327,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
|
||||
|
||||
operand->mode = Addressing_NoValue;
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -5329,7 +5359,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
|
||||
operand->type = nullptr;
|
||||
operand->mode = Addressing_NoValue;
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
case BuiltinProc_clear: {
|
||||
@@ -5345,7 +5377,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
|
||||
operand->type = nullptr;
|
||||
operand->mode = Addressing_NoValue;
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
case BuiltinProc_append: {
|
||||
@@ -5394,7 +5428,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
}
|
||||
operand->mode = Addressing_Value;
|
||||
operand->type = t_int;
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
case BuiltinProc_delete: {
|
||||
@@ -5426,7 +5462,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
}
|
||||
|
||||
operand->mode = Addressing_NoValue;
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -5447,7 +5485,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
operand->mode = Addressing_Constant;
|
||||
operand->value = exact_value_i64(type_size_of(c->allocator, t));
|
||||
operand->type = t_untyped_integer;
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case BuiltinProc_align_of: {
|
||||
// proc align_of(Type or expr) -> untyped int
|
||||
@@ -5466,7 +5506,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
operand->mode = Addressing_Constant;
|
||||
operand->value = exact_value_i64(type_align_of(c->allocator, t));
|
||||
operand->type = t_untyped_integer;
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case BuiltinProc_offset_of: {
|
||||
@@ -5511,7 +5553,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
operand->mode = Addressing_Constant;
|
||||
operand->value = exact_value_i64(type_offset_of_from_selection(c->allocator, type, sel));
|
||||
operand->type = t_untyped_integer;
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case BuiltinProc_type_of:
|
||||
@@ -5557,7 +5601,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
|
||||
operand->mode = Addressing_Value;
|
||||
operand->type = t_type_info_ptr;
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case BuiltinProc_compile_assert:
|
||||
// proc compile_assert(cond: bool) -> bool
|
||||
@@ -5630,7 +5676,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
Type *elem_type = vector_type->Vector.elem;
|
||||
operand->type = make_type_vector(c->allocator, elem_type, arg_count);
|
||||
operand->mode = Addressing_Value;
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case BuiltinProc_complex: {
|
||||
// proc complex(real, imag: float_type) -> complex_type
|
||||
@@ -5689,7 +5737,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
case Basic_UntypedFloat: operand->type = t_untyped_complex; break;
|
||||
default: GB_PANIC("Invalid type"); break;
|
||||
}
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case BuiltinProc_real:
|
||||
case BuiltinProc_imag: {
|
||||
@@ -5733,7 +5783,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
case Basic_UntypedComplex: x->type = t_untyped_float; break;
|
||||
default: GB_PANIC("Invalid type"); break;
|
||||
}
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case BuiltinProc_conj: {
|
||||
// proc conj(x: type) -> type
|
||||
@@ -5755,7 +5807,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
return false;
|
||||
}
|
||||
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
#if 0
|
||||
case BuiltinProc_slice_ptr: {
|
||||
@@ -5799,7 +5853,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
}
|
||||
operand->type = make_type_slice(c->allocator, ptr_type->Pointer.elem);
|
||||
operand->mode = Addressing_Value;
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case BuiltinProc_slice_to_bytes: {
|
||||
// proc slice_to_bytes(a: []T) -> []u8
|
||||
@@ -5813,7 +5869,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
|
||||
operand->type = t_u8_slice;
|
||||
operand->mode = Addressing_Value;
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case BuiltinProc_expand_to_tuple: {
|
||||
Type *type = base_type(operand->type);
|
||||
@@ -5834,7 +5892,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
|
||||
operand->type = tuple;
|
||||
operand->mode = Addressing_Value;
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case BuiltinProc_min: {
|
||||
// proc min(a, b: ordered) -> ordered
|
||||
@@ -5900,7 +5960,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
}
|
||||
}
|
||||
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case BuiltinProc_max: {
|
||||
// proc min(a, b: ordered) -> ordered
|
||||
@@ -5968,7 +6030,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
}
|
||||
}
|
||||
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case BuiltinProc_abs: {
|
||||
// proc abs(n: numeric) -> numeric
|
||||
@@ -5991,7 +6055,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
f64 r = operand->value.value_complex.real;
|
||||
f64 i = operand->value.value_complex.imag;
|
||||
operand->value = exact_value_float(gb_sqrt(r*r + i*i));
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
GB_PANIC("Invalid numeric constant");
|
||||
break;
|
||||
@@ -6004,7 +6070,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
operand->type = base_complex_elem_type(operand->type);
|
||||
}
|
||||
GB_ASSERT(!is_type_complex(operand->type));
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case BuiltinProc_clamp: {
|
||||
// proc clamp(a, min, max: ordered) -> ordered
|
||||
@@ -6092,7 +6160,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
#if 0
|
||||
case BuiltinProc_transmute: {
|
||||
@@ -6143,7 +6213,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
|
||||
o->mode = Addressing_Value;
|
||||
o->type = t;
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -7103,7 +7175,9 @@ ExprKind check_call_expr(Checker *c, Operand *operand, AstNode *call) {
|
||||
if (operand->mode != Addressing_Invalid) {
|
||||
check_cast(c, operand, t);
|
||||
}
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Expr_Expr;
|
||||
@@ -7330,7 +7404,9 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t
|
||||
switch (r) {
|
||||
case 'i': t = t_untyped_complex; break;
|
||||
}
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
default: GB_PANIC("Unknown literal"); break;
|
||||
}
|
||||
o->mode = Addressing_Constant;
|
||||
@@ -7663,7 +7739,8 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t
|
||||
}
|
||||
}
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case Type_Slice:
|
||||
case Type_Array:
|
||||
@@ -7740,7 +7817,9 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t
|
||||
if (t->kind == Type_Array && is_to_be_determined_array_count) {
|
||||
t->Array.count = max;
|
||||
}
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case Type_Basic: {
|
||||
if (!is_type_any(t)) {
|
||||
@@ -7819,7 +7898,9 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t
|
||||
}
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case Type_Map: {
|
||||
if (cl->elems.count == 0) {
|
||||
@@ -7844,7 +7925,9 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t
|
||||
check_assignment(c, o, t->Map.value, str_lit("map literal"));
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
if (cl->elems.count == 0) {
|
||||
@@ -7855,7 +7938,7 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t
|
||||
error(node, "Invalid compound literal type `%s`", str);
|
||||
gb_string_free(str);
|
||||
return kind;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_constant) {
|
||||
|
||||
+48
-30
@@ -138,10 +138,10 @@ bool check_is_terminating(AstNode *node) {
|
||||
return false;
|
||||
case_end;
|
||||
|
||||
case_ast_node(ms, MatchStmt, node);
|
||||
case_ast_node(ss, SwitchStmt, node);
|
||||
bool has_default = false;
|
||||
for_array(i, ms->body->BlockStmt.stmts) {
|
||||
AstNode *clause = ms->body->BlockStmt.stmts[i];
|
||||
for_array(i, ss->body->BlockStmt.stmts) {
|
||||
AstNode *clause = ss->body->BlockStmt.stmts[i];
|
||||
ast_node(cc, CaseClause, clause);
|
||||
if (cc->list.count == 0) {
|
||||
has_default = true;
|
||||
@@ -154,10 +154,10 @@ bool check_is_terminating(AstNode *node) {
|
||||
return has_default;
|
||||
case_end;
|
||||
|
||||
case_ast_node(ms, TypeMatchStmt, node);
|
||||
case_ast_node(ss, TypeSwitchStmt, node);
|
||||
bool has_default = false;
|
||||
for_array(i, ms->body->BlockStmt.stmts) {
|
||||
AstNode *clause = ms->body->BlockStmt.stmts[i];
|
||||
for_array(i, ss->body->BlockStmt.stmts) {
|
||||
AstNode *clause = ss->body->BlockStmt.stmts[i];
|
||||
ast_node(cc, CaseClause, clause);
|
||||
if (cc->list.count == 0) {
|
||||
has_default = true;
|
||||
@@ -309,7 +309,9 @@ Type *check_assignment_variable(Checker *c, Operand *rhs, AstNode *lhs_node) {
|
||||
}
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
if (lhs.expr->kind == AstNode_SelectorExpr) {
|
||||
@@ -332,7 +334,9 @@ Type *check_assignment_variable(Checker *c, Operand *rhs, AstNode *lhs_node) {
|
||||
error(lhs.expr, "Cannot assign to `%s`", str);
|
||||
}
|
||||
gb_string_free(str);
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
check_assignment(c, rhs, assignment_type, str_lit("assignment"));
|
||||
@@ -490,7 +494,9 @@ bool check_using_stmt_entity(Checker *c, AstNodeUsingStmt *us, AstNode *expr, bo
|
||||
} else {
|
||||
error(us->token, "`using` can be only applied to enum type entities");
|
||||
}
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case Entity_ImportName: {
|
||||
Scope *scope = e->ImportName.scope;
|
||||
@@ -511,7 +517,9 @@ bool check_using_stmt_entity(Checker *c, AstNodeUsingStmt *us, AstNode *expr, bo
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case Entity_Variable: {
|
||||
Type *t = base_type(type_deref(e->type));
|
||||
@@ -538,7 +546,9 @@ bool check_using_stmt_entity(Checker *c, AstNodeUsingStmt *us, AstNode *expr, bo
|
||||
error(us->token, "`using` can only be applied to variables of type struct or raw_union");
|
||||
return false;
|
||||
}
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case Entity_Constant:
|
||||
error(us->token, "`using` cannot be applied to a constant");
|
||||
@@ -583,7 +593,9 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
gbString str = type_to_string(operand.type);
|
||||
error(node, "`%s` is not an expression", str);
|
||||
gb_string_free(str);
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
case Addressing_NoValue:
|
||||
return;
|
||||
default: {
|
||||
@@ -605,7 +617,9 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
gbString expr_str = expr_to_string(operand.expr);
|
||||
error(node, "Expression is not used: `%s`", expr_str);
|
||||
gb_string_free(expr_str);
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
case_end;
|
||||
|
||||
@@ -695,7 +709,9 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
error(as->lhs[0], "Assignment count mismatch `%td` = `%td`", lhs_count, rhs_count);
|
||||
}
|
||||
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
// a += 1; // Single-sided
|
||||
@@ -723,7 +739,9 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
}
|
||||
// NOTE(bill): Only use the first one will be used
|
||||
check_assignment_variable(c, &operand, as->lhs[0]);
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
case_end;
|
||||
|
||||
@@ -1161,18 +1179,18 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
check_close_scope(c);
|
||||
case_end;
|
||||
|
||||
case_ast_node(ms, MatchStmt, node);
|
||||
case_ast_node(ss, SwitchStmt, node);
|
||||
Operand x = {};
|
||||
|
||||
mod_flags |= Stmt_BreakAllowed;
|
||||
check_open_scope(c, node);
|
||||
check_label(c, ms->label); // TODO(bill): What should the label's "scope" be?
|
||||
check_label(c, ss->label); // TODO(bill): What should the label's "scope" be?
|
||||
|
||||
if (ms->init != nullptr) {
|
||||
check_stmt(c, ms->init, 0);
|
||||
if (ss->init != nullptr) {
|
||||
check_stmt(c, ss->init, 0);
|
||||
}
|
||||
if (ms->tag != nullptr) {
|
||||
check_expr(c, &x, ms->tag);
|
||||
if (ss->tag != nullptr) {
|
||||
check_expr(c, &x, ss->tag);
|
||||
check_assignment(c, &x, nullptr, str_lit("match expression"));
|
||||
} else {
|
||||
x.mode = Addressing_Constant;
|
||||
@@ -1180,7 +1198,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
x.value = exact_value_bool(true);
|
||||
|
||||
Token token = {};
|
||||
token.pos = ast_node_token(ms->body).pos;
|
||||
token.pos = ast_node_token(ss->body).pos;
|
||||
token.string = str_lit("true");
|
||||
x.expr = ast_ident(c->curr_ast_file, token);
|
||||
}
|
||||
@@ -1194,7 +1212,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
|
||||
// NOTE(bill): Check for multiple defaults
|
||||
AstNode *first_default = nullptr;
|
||||
ast_node(bs, BlockStmt, ms->body);
|
||||
ast_node(bs, BlockStmt, ss->body);
|
||||
for_array(i, bs->stmts) {
|
||||
AstNode *stmt = bs->stmts[i];
|
||||
AstNode *default_stmt = nullptr;
|
||||
@@ -1365,22 +1383,22 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
check_close_scope(c);
|
||||
case_end;
|
||||
|
||||
case_ast_node(ms, TypeMatchStmt, node);
|
||||
case_ast_node(ss, TypeSwitchStmt, node);
|
||||
Operand x = {};
|
||||
|
||||
mod_flags |= Stmt_BreakAllowed;
|
||||
check_open_scope(c, node);
|
||||
check_label(c, ms->label); // TODO(bill): What should the label's "scope" be?
|
||||
check_label(c, ss->label); // TODO(bill): What should the label's "scope" be?
|
||||
|
||||
MatchTypeKind match_type_kind = MatchType_Invalid;
|
||||
|
||||
if (ms->tag->kind != AstNode_AssignStmt) {
|
||||
error(ms->tag, "Expected an `in` assignment for this type match statement");
|
||||
if (ss->tag->kind != AstNode_AssignStmt) {
|
||||
error(ss->tag, "Expected an `in` assignment for this type match statement");
|
||||
break;
|
||||
}
|
||||
|
||||
ast_node(as, AssignStmt, ms->tag);
|
||||
Token as_token = ast_node_token(ms->tag);
|
||||
ast_node(as, AssignStmt, ss->tag);
|
||||
Token as_token = ast_node_token(ss->tag);
|
||||
if (as->lhs.count != 1) {
|
||||
syntax_error(as_token, "Expected 1 name before `in`");
|
||||
break;
|
||||
@@ -1406,7 +1424,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
|
||||
// NOTE(bill): Check for multiple defaults
|
||||
AstNode *first_default = nullptr;
|
||||
ast_node(bs, BlockStmt, ms->body);
|
||||
ast_node(bs, BlockStmt, ss->body);
|
||||
for_array(i, bs->stmts) {
|
||||
AstNode *stmt = bs->stmts[i];
|
||||
AstNode *default_stmt = nullptr;
|
||||
|
||||
+46
-76
@@ -448,8 +448,9 @@ struct CheckerInfo {
|
||||
Map<isize> type_info_map; // Key: Type *
|
||||
isize type_info_count;
|
||||
|
||||
Scope * init_scope;
|
||||
Entity * entry_point;
|
||||
PtrSet<Entity *> minimum_dependency_map;
|
||||
PtrSet<Entity *> minimum_dependency_set;
|
||||
|
||||
};
|
||||
|
||||
@@ -1293,7 +1294,7 @@ void add_type_info_type(Checker *c, Type *t) {
|
||||
add_type_info_type(c, bt);
|
||||
|
||||
switch (bt->kind) {
|
||||
case Type_Basic: {
|
||||
case Type_Basic:
|
||||
switch (bt->Basic.kind) {
|
||||
case Basic_string:
|
||||
add_type_info_type(c, t_u8_ptr);
|
||||
@@ -1313,7 +1314,7 @@ void add_type_info_type(Checker *c, Type *t) {
|
||||
add_type_info_type(c, t_f64);
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
|
||||
case Type_Pointer:
|
||||
add_type_info_type(c, bt->Pointer.elem);
|
||||
@@ -1352,7 +1353,7 @@ void add_type_info_type(Checker *c, Type *t) {
|
||||
}
|
||||
break;
|
||||
|
||||
case Type_Struct: {
|
||||
case Type_Struct:
|
||||
if (bt->Struct.scope != nullptr) {
|
||||
for_array(i, bt->Struct.scope->elements.entries) {
|
||||
Entity *e = bt->Struct.scope->elements.entries[i].value;
|
||||
@@ -1363,14 +1364,14 @@ void add_type_info_type(Checker *c, Type *t) {
|
||||
Entity *f = bt->Struct.fields[i];
|
||||
add_type_info_type(c, f->type);
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
|
||||
case Type_Map: {
|
||||
case Type_Map:
|
||||
generate_map_internal_types(c->allocator, bt);
|
||||
add_type_info_type(c, bt->Map.key);
|
||||
add_type_info_type(c, bt->Map.value);
|
||||
add_type_info_type(c, bt->Map.generated_struct_type);
|
||||
} break;
|
||||
break;
|
||||
|
||||
case Type_Tuple:
|
||||
for_array(i, bt->Tuple.variables) {
|
||||
@@ -1457,7 +1458,7 @@ void add_dependency_to_map(PtrSet<Entity *> *map, CheckerInfo *info, Entity *ent
|
||||
}
|
||||
}
|
||||
|
||||
PtrSet<Entity *> generate_minimum_dependency_map(CheckerInfo *info, Entity *start) {
|
||||
PtrSet<Entity *> generate_minimum_dependency_set(CheckerInfo *info, Entity *start) {
|
||||
PtrSet<Entity *> map = {}; // Key: Entity *
|
||||
ptr_set_init(&map, heap_allocator());
|
||||
|
||||
@@ -2360,7 +2361,9 @@ void add_import_dependency_node(Checker *c, AstNode *decl, Map<ImportGraphNode *
|
||||
for_array(i, stmts) {
|
||||
add_import_dependency_node(c, stmts[i], M);
|
||||
}
|
||||
} break;
|
||||
|
||||
break;
|
||||
}
|
||||
case AstNode_WhenStmt:
|
||||
add_import_dependency_node(c, ws->else_stmt, M);
|
||||
break;
|
||||
@@ -2839,17 +2842,15 @@ void check_import_entities(Checker *c) {
|
||||
};
|
||||
|
||||
|
||||
if (path.count > 0) {
|
||||
Scope *s = path[path.count-1];
|
||||
Token token = mt(s);
|
||||
error(token, "Cyclic importation of `%.*s`", LIT(token.string));
|
||||
for (isize i = 0; i < path.count; i++) {
|
||||
gb_printf_err("\t`%.*s` refers to\n", LIT(token.string));
|
||||
s = path[i];
|
||||
token = mt(s);
|
||||
}
|
||||
gb_printf_err("\t`%.*s`\n", LIT(token.string));
|
||||
Scope *s = path[path.count-1];
|
||||
Token token = mt(s);
|
||||
error(token, "Cyclic importation of `%.*s`", LIT(token.string));
|
||||
for (isize i = 0; i < path.count; i++) {
|
||||
gb_printf_err("\t`%.*s` refers to\n", LIT(token.string));
|
||||
s = path[i];
|
||||
token = mt(s);
|
||||
}
|
||||
gb_printf_err("\t`%.*s`\n", LIT(token.string));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3059,11 +3060,14 @@ void check_parsed_files(Checker *c) {
|
||||
for_array(i, c->parser->files) {
|
||||
AstFile *f = c->parser->files[i];
|
||||
Scope *scope = create_scope_from_file(c, f);
|
||||
|
||||
f->decl_info = make_declaration_info(c->allocator, f->scope, c->context.decl);
|
||||
HashKey key = hash_string(f->tokenizer.fullpath);
|
||||
map_set(&c->file_scopes, key, scope);
|
||||
map_set(&c->info.files, key, f);
|
||||
|
||||
if (scope->is_init) {
|
||||
c->info.init_scope = scope;
|
||||
}
|
||||
}
|
||||
|
||||
// Collect Entities
|
||||
@@ -3077,7 +3081,7 @@ void check_parsed_files(Checker *c) {
|
||||
|
||||
check_import_entities(c);
|
||||
check_all_global_entities(c);
|
||||
init_preload(c); // NOTE(bill): This could be setup previously through the use of `type_info(_of_val)`
|
||||
init_preload(c); // NOTE(bill): This could be setup previously through the use of `type_info_of`
|
||||
|
||||
// Check procedure bodies
|
||||
// NOTE(bill): Nested procedures bodies will be added to this "queue"
|
||||
@@ -3112,25 +3116,12 @@ void check_parsed_files(Checker *c) {
|
||||
check_proc_body(c, pi->token, pi->decl, pi->type, pi->body);
|
||||
}
|
||||
|
||||
{
|
||||
for_array(i, c->info.entities.entries) {
|
||||
auto *entry = &c->info.entities.entries[i];
|
||||
Entity *e = cast(Entity *)entry->key.ptr;
|
||||
String name = e->token.string;
|
||||
if (e->kind == Entity_Procedure && !e->scope->is_global) {
|
||||
if (e->scope->is_init && name == "main") {
|
||||
c->info.entry_point = e;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
c->info.minimum_dependency_map = generate_minimum_dependency_map(&c->info, c->info.entry_point);
|
||||
}
|
||||
c->info.minimum_dependency_set = generate_minimum_dependency_set(&c->info, c->info.entry_point);
|
||||
|
||||
|
||||
// Calculate initialization order of global variables
|
||||
calculate_global_init_order(c);
|
||||
|
||||
|
||||
// Add untyped expression values
|
||||
for_array(i, c->info.untyped.entries) {
|
||||
auto *entry = &c->info.untyped.entries[i];
|
||||
@@ -3148,8 +3139,6 @@ void check_parsed_files(Checker *c) {
|
||||
// TODO(bill): Check for unused imports (and remove) or even warn/err
|
||||
// TODO(bill): Any other checks?
|
||||
|
||||
|
||||
#if 1
|
||||
// Add "Basic" type information
|
||||
for (isize i = 0; i < gb_count_of(basic_types)-1; i++) {
|
||||
Type *t = &basic_types[i];
|
||||
@@ -3158,53 +3147,34 @@ void check_parsed_files(Checker *c) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
for (isize i = 0; i < gb_count_of(basic_type_aliases)-1; i++) {
|
||||
Type *t = &basic_type_aliases[i];
|
||||
if (t->Basic.size > 0) {
|
||||
add_type_info_type(c, t);
|
||||
}
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
|
||||
|
||||
// NOTE(bill): Check for illegal cyclic type declarations
|
||||
for_array(i, c->info.definitions.entries) {
|
||||
Entity *e = c->info.definitions.entries[i].value;
|
||||
if (e->kind == Entity_TypeName) {
|
||||
if (e->type != nullptr) {
|
||||
// i64 size = type_size_of(c->sizes, c->allocator, e->type);
|
||||
i64 align = type_align_of(c->allocator, e->type);
|
||||
if (align > 0) {
|
||||
add_type_info_type(c, e->type);
|
||||
}
|
||||
if (e->kind == Entity_TypeName && e->type != nullptr) {
|
||||
// i64 size = type_size_of(c->sizes, c->allocator, e->type);
|
||||
i64 align = type_align_of(c->allocator, e->type);
|
||||
if (align > 0) {
|
||||
add_type_info_type(c, e->type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// gb_printf_err("Count: %td\n", c->info.type_info_count++);
|
||||
|
||||
if (!build_context.is_dll) {
|
||||
for_array(i, c->file_scopes.entries) {
|
||||
Scope *s = c->file_scopes.entries[i].value;
|
||||
if (s->is_init) {
|
||||
Entity *e = current_scope_lookup_entity(s, str_lit("main"));
|
||||
if (e == nullptr) {
|
||||
Token token = {};
|
||||
if (s->file->tokens.count > 0) {
|
||||
token = s->file->tokens[0];
|
||||
} else {
|
||||
token.pos.file = s->file->tokenizer.fullpath;
|
||||
token.pos.line = 1;
|
||||
token.pos.column = 1;
|
||||
}
|
||||
|
||||
error(token, "Undefined entry point procedure `main`");
|
||||
}
|
||||
|
||||
break;
|
||||
Scope *s = c->info.init_scope;
|
||||
GB_ASSERT(s != nullptr);
|
||||
GB_ASSERT(s->is_init);
|
||||
Entity *e = current_scope_lookup_entity(s, str_lit("main"));
|
||||
if (e == nullptr) {
|
||||
Token token = {};
|
||||
if (s->file->tokens.count > 0) {
|
||||
token = s->file->tokens[0];
|
||||
} else {
|
||||
token.pos.file = s->file->tokenizer.fullpath;
|
||||
token.pos.line = 1;
|
||||
token.pos.column = 1;
|
||||
}
|
||||
|
||||
error(token, "Undefined entry point procedure `main`");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+12
-6
@@ -50,16 +50,19 @@ GB_ALLOCATOR_PROC(heap_allocator_proc) {
|
||||
if (flags & gbAllocatorFlag_ClearToZero) {
|
||||
gb_zero_size(ptr, size);
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case gbAllocation_Free: {
|
||||
free(old_memory);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case gbAllocation_Resize: {
|
||||
// ptr = realloc(old_memory, size);
|
||||
ptr = gb_default_resize_align(heap_allocator(), old_memory, old_size, size, alignment);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
// TODO(bill): *nix version that's decent
|
||||
case gbAllocation_Alloc: {
|
||||
@@ -68,15 +71,18 @@ GB_ALLOCATOR_PROC(heap_allocator_proc) {
|
||||
if (flags & gbAllocatorFlag_ClearToZero) {
|
||||
gb_zero_size(ptr, size);
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case gbAllocation_Free: {
|
||||
free(old_memory);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case gbAllocation_Resize: {
|
||||
ptr = gb_default_resize_align(heap_allocator(), old_memory, old_size, size, alignment);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
case gbAllocation_FreeAll:
|
||||
|
||||
+28
-14
@@ -270,7 +270,8 @@ ExactValue exact_value_to_integer(ExactValue v) {
|
||||
if (f == v.value_float) {
|
||||
return exact_value_i128(i);
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case ExactValue_Pointer:
|
||||
return exact_value_i64(cast(i64)cast(intptr)v.value_pointer);
|
||||
@@ -352,7 +353,8 @@ ExactValue exact_unary_operator_value(TokenKind op, ExactValue v, i32 precision)
|
||||
case ExactValue_Complex:
|
||||
return v;
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case Token_Sub: {
|
||||
switch (v.kind) {
|
||||
@@ -374,7 +376,8 @@ ExactValue exact_unary_operator_value(TokenKind op, ExactValue v, i32 precision)
|
||||
return exact_value_complex(-real, -imag);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case Token_Xor: {
|
||||
i128 i = I128_ZERO;
|
||||
@@ -396,7 +399,8 @@ ExactValue exact_unary_operator_value(TokenKind op, ExactValue v, i32 precision)
|
||||
}
|
||||
|
||||
return exact_value_i128(i);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case Token_Not: {
|
||||
switch (v.kind) {
|
||||
@@ -404,7 +408,8 @@ ExactValue exact_unary_operator_value(TokenKind op, ExactValue v, i32 precision)
|
||||
case ExactValue_Bool:
|
||||
return exact_value_bool(!v.value_bool);
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
failure:
|
||||
@@ -521,7 +526,8 @@ ExactValue exact_binary_operator_value(TokenKind op, ExactValue x, ExactValue y)
|
||||
}
|
||||
|
||||
return exact_value_i128(c);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case ExactValue_Float: {
|
||||
f64 a = x.value_float;
|
||||
@@ -533,7 +539,8 @@ ExactValue exact_binary_operator_value(TokenKind op, ExactValue x, ExactValue y)
|
||||
case Token_Quo: return exact_value_float(a / b);
|
||||
default: goto error;
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case ExactValue_Complex: {
|
||||
y = exact_value_to_complex(y);
|
||||
@@ -560,11 +567,13 @@ ExactValue exact_binary_operator_value(TokenKind op, ExactValue x, ExactValue y)
|
||||
f64 s = c*c + d*d;
|
||||
real = (a*c + b*d)/s;
|
||||
imag = (b*c - a*d)/s;
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
default: goto error;
|
||||
}
|
||||
return exact_value_complex(real, imag);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case ExactValue_String: {
|
||||
if (op != Token_Add) goto error;
|
||||
@@ -577,7 +586,8 @@ ExactValue exact_binary_operator_value(TokenKind op, ExactValue x, ExactValue y)
|
||||
gb_memmove(data, sx.text, sx.len);
|
||||
gb_memmove(data+sx.len, sy.text, sy.len);
|
||||
return exact_value_string(make_string(data, len));
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
error:; // NOTE(bill): MSVC accepts this??? apparently you cannot declare variables immediately after labels...
|
||||
@@ -620,7 +630,8 @@ bool compare_exact_values(TokenKind op, ExactValue x, ExactValue y) {
|
||||
case Token_Gt: return a > b;
|
||||
case Token_GtEq: return a >= b;
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case ExactValue_Float: {
|
||||
f64 a = x.value_float;
|
||||
@@ -633,7 +644,8 @@ bool compare_exact_values(TokenKind op, ExactValue x, ExactValue y) {
|
||||
case Token_Gt: return cmp_f64(a, b) > 0;
|
||||
case Token_GtEq: return cmp_f64(a, b) >= 0;
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case ExactValue_Complex: {
|
||||
f64 a = x.value_complex.real;
|
||||
@@ -644,7 +656,8 @@ bool compare_exact_values(TokenKind op, ExactValue x, ExactValue y) {
|
||||
case Token_CmpEq: return cmp_f64(a, c) == 0 && cmp_f64(b, d) == 0;
|
||||
case Token_NotEq: return cmp_f64(a, c) != 0 || cmp_f64(b, d) != 0;
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case ExactValue_String: {
|
||||
String a = x.value_string;
|
||||
@@ -658,7 +671,8 @@ bool compare_exact_values(TokenKind op, ExactValue x, ExactValue y) {
|
||||
case Token_Gt: return a > b;
|
||||
case Token_GtEq: return a >= b;
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case ExactValue_Type:
|
||||
switch (op) {
|
||||
|
||||
+178
-105
@@ -19,7 +19,7 @@ struct irModule {
|
||||
String layout;
|
||||
// String triple;
|
||||
|
||||
PtrSet<Entity *> min_dep_map;
|
||||
PtrSet<Entity *> min_dep_set;
|
||||
Map<irValue *> values; // Key: Entity *
|
||||
Map<irValue *> members; // Key: String
|
||||
Map<String> entity_names; // Key: Entity * of the typename
|
||||
@@ -623,7 +623,7 @@ Type *ir_instr_type(irInstr *instr) {
|
||||
return pt;
|
||||
}
|
||||
return nullptr;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@@ -741,7 +741,8 @@ Array<irValue *> *ir_value_referrers(irValue *v) {
|
||||
case irInstr_Local:
|
||||
return &i->Local.referrers;
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
@@ -2107,7 +2108,8 @@ irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue *
|
||||
irValue *z = ir_emit_arith(proc, Token_Mul, b, c, ft);
|
||||
irValue *w = ir_emit_arith(proc, Token_Mul, a, d, ft);
|
||||
imag = ir_emit_arith(proc, Token_Add, z, w, ft);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
case Token_Quo: {
|
||||
irValue *s1 = ir_emit_arith(proc, Token_Mul, c, c, ft);
|
||||
irValue *s2 = ir_emit_arith(proc, Token_Mul, d, d, ft);
|
||||
@@ -2122,7 +2124,8 @@ irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue *
|
||||
irValue *w = ir_emit_arith(proc, Token_Mul, a, d, ft);
|
||||
imag = ir_emit_arith(proc, Token_Sub, z, w, ft);
|
||||
imag = ir_emit_arith(proc, Token_Quo, imag, s, ft);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ir_emit_store(proc, ir_emit_struct_ep(proc, res, 0), real);
|
||||
@@ -2473,7 +2476,8 @@ irValue *ir_emit_struct_ev(irProcedure *proc, irValue *s, i32 index) {
|
||||
case 0: result_type = ft; break;
|
||||
case 1: result_type = ft; break;
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Type_Struct:
|
||||
@@ -2509,7 +2513,8 @@ irValue *ir_emit_struct_ev(irProcedure *proc, irValue *s, i32 index) {
|
||||
case 0: result_type = gst->Struct.fields[0]->type; break;
|
||||
case 1: result_type = gst->Struct.fields[1]->type; break;
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
GB_PANIC("TODO(bill): struct_ev type: %s, %d", type_to_string(ir_type(s)), index);
|
||||
@@ -2558,7 +2563,8 @@ irValue *ir_emit_deep_field_gep(irProcedure *proc, irValue *e, Selection sel) {
|
||||
type = t_type_info_ptr;
|
||||
}
|
||||
e = ir_emit_struct_ep(proc, e, index);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case Basic_string:
|
||||
e = ir_emit_struct_ep(proc, e, index);
|
||||
@@ -2924,12 +2930,14 @@ irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) {
|
||||
irValue **args = gb_alloc_array(a, irValue *, 1);
|
||||
args[0] = value;
|
||||
return ir_emit_global_call(proc, "__gnu_h2f_ieee", args, 1);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
irValue **args = gb_alloc_array(a, irValue *, 1);
|
||||
args[0] = value;
|
||||
return ir_emit_global_call(proc, "__f16_to_f64", args, 1);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (dz == 2) {
|
||||
switch (sz) {
|
||||
@@ -2938,12 +2946,14 @@ irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) {
|
||||
irValue **args = gb_alloc_array(a, irValue *, 1);
|
||||
args[0] = value;
|
||||
return ir_emit_global_call(proc, "__gnu_f2h_ieee", args, 1);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
irValue **args = gb_alloc_array(a, irValue *, 1);
|
||||
args[0] = value;
|
||||
return ir_emit_global_call(proc, "__truncdfhf2", args, 1);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3897,12 +3907,14 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
|
||||
|
||||
}
|
||||
return ir_emit_source_code_location(proc, procedure, pos);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case BuiltinProc_type_info_of: {
|
||||
Type *t = default_type(type_of_expr(proc->module->info, ce->args[0]));
|
||||
return ir_type_info(proc, t);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case BuiltinProc_len: {
|
||||
irValue *v = ir_build_expr(proc, ce->args[0]);
|
||||
@@ -3929,7 +3941,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
|
||||
}
|
||||
|
||||
GB_PANIC("Unreachable");
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case BuiltinProc_cap: {
|
||||
irValue *v = ir_build_expr(proc, ce->args[0]);
|
||||
@@ -3956,7 +3969,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
|
||||
|
||||
GB_PANIC("Unreachable");
|
||||
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
#if 0
|
||||
case BuiltinProc_new: {
|
||||
@@ -3993,7 +4007,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
|
||||
ir_emit_store(proc, tag_ptr, ir_const_int(a, variant_index));
|
||||
}
|
||||
return v;
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
case BuiltinProc_make: {
|
||||
@@ -4079,7 +4094,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
|
||||
|
||||
return ir_emit_load(proc, array);
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
#if 0
|
||||
case BuiltinProc_free: {
|
||||
@@ -4154,7 +4170,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
|
||||
irValue **args = gb_alloc_array(a, irValue *, 1);
|
||||
args[0] = ptr;
|
||||
return ir_emit_global_call(proc, "free_ptr", args, 1);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
case BuiltinProc_reserve: {
|
||||
@@ -4190,7 +4207,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
|
||||
} else {
|
||||
GB_PANIC("Unknown type for `reserve`");
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
case BuiltinProc_clear: {
|
||||
@@ -4217,7 +4235,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
|
||||
GB_PANIC("TODO(bill): ir clear for `%s`", type_to_string(t));
|
||||
}
|
||||
return nullptr;
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
case BuiltinProc_append: {
|
||||
@@ -4327,7 +4346,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
|
||||
return ir_emit_global_call(proc, "__slice_append", daa_args, 5);
|
||||
}
|
||||
return ir_emit_global_call(proc, "__dynamic_array_append", daa_args, 5);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
case BuiltinProc_delete: {
|
||||
@@ -4345,7 +4365,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
|
||||
args[0] = ir_gen_map_header(proc, addr, map_type);
|
||||
args[1] = ir_gen_map_key(proc, key, key_type);
|
||||
return ir_emit_global_call(proc, "__dynamic_map_delete", args, 2);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
case BuiltinProc_swizzle: {
|
||||
@@ -4374,7 +4395,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
|
||||
ir_emit_comment(proc, str_lit("swizzle.end"));
|
||||
return ir_emit_load(proc, dst);
|
||||
// return ir_emit(proc, ir_instr_vector_shuffle(proc, vector, indices, index_count));
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case BuiltinProc_complex: {
|
||||
ir_emit_comment(proc, str_lit("complex"));
|
||||
@@ -4389,20 +4411,23 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
|
||||
ir_emit_store(proc, ir_emit_struct_ep(proc, dst, 1), imag);
|
||||
|
||||
return ir_emit_load(proc, dst);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case BuiltinProc_real: {
|
||||
ir_emit_comment(proc, str_lit("real"));
|
||||
irValue *val = ir_build_expr(proc, ce->args[0]);
|
||||
irValue *real = ir_emit_struct_ev(proc, val, 0);
|
||||
return ir_emit_conv(proc, real, tv.type);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
case BuiltinProc_imag: {
|
||||
ir_emit_comment(proc, str_lit("imag"));
|
||||
irValue *val = ir_build_expr(proc, ce->args[0]);
|
||||
irValue *imag = ir_emit_struct_ev(proc, val, 1);
|
||||
return ir_emit_conv(proc, imag, tv.type);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case BuiltinProc_conj: {
|
||||
ir_emit_comment(proc, str_lit("conj"));
|
||||
@@ -4418,7 +4443,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
|
||||
ir_emit_store(proc, ir_emit_struct_ep(proc, res, 1), imag);
|
||||
}
|
||||
return ir_emit_load(proc, res);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
#if 0
|
||||
case BuiltinProc_slice_ptr: {
|
||||
@@ -4436,7 +4462,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
|
||||
irValue *slice = ir_add_local_generated(proc, slice_type);
|
||||
ir_fill_slice(proc, slice, ptr, count, capacity);
|
||||
return ir_emit_load(proc, slice);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case BuiltinProc_slice_to_bytes: {
|
||||
ir_emit_comment(proc, str_lit("slice_to_bytes"));
|
||||
@@ -4455,7 +4482,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
|
||||
capacity = ir_emit_arith(proc, Token_Mul, capacity, ir_const_int(proc->module->allocator, elem_size), t_int);
|
||||
ir_fill_slice(proc, slice, ptr, count, capacity);
|
||||
return ir_emit_load(proc, slice);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
case BuiltinProc_expand_to_tuple: {
|
||||
@@ -4475,7 +4503,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
|
||||
ir_emit_store(proc, ep, f);
|
||||
}
|
||||
return ir_emit_load(proc, tuple);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case BuiltinProc_min: {
|
||||
ir_emit_comment(proc, str_lit("min"));
|
||||
@@ -4484,7 +4513,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
|
||||
irValue *y = ir_emit_conv(proc, ir_build_expr(proc, ce->args[1]), t);
|
||||
irValue *cond = ir_emit_comp(proc, Token_Lt, x, y);
|
||||
return ir_emit_select(proc, cond, x, y);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case BuiltinProc_max: {
|
||||
ir_emit_comment(proc, str_lit("max"));
|
||||
@@ -4493,7 +4523,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
|
||||
irValue *y = ir_emit_conv(proc, ir_build_expr(proc, ce->args[1]), t);
|
||||
irValue *cond = ir_emit_comp(proc, Token_Gt, x, y);
|
||||
return ir_emit_select(proc, cond, x, y);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case BuiltinProc_abs: {
|
||||
ir_emit_comment(proc, str_lit("abs"));
|
||||
@@ -4514,7 +4545,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
|
||||
irValue *cond = ir_emit_comp(proc, Token_Lt, x, zero);
|
||||
irValue *neg = ir_emit(proc, ir_instr_unary_op(proc, Token_Sub, x, t));
|
||||
return ir_emit_select(proc, cond, neg, x);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case BuiltinProc_clamp: {
|
||||
ir_emit_comment(proc, str_lit("clamp"));
|
||||
@@ -4523,7 +4555,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
|
||||
ir_build_expr(proc, ce->args[0]),
|
||||
ir_build_expr(proc, ce->args[1]),
|
||||
ir_build_expr(proc, ce->args[2]));
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GB_PANIC("Unhandled built-in procedure");
|
||||
@@ -4775,7 +4808,8 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
|
||||
irValue *right = ir_build_expr(proc, be->right);
|
||||
irValue *cmp = ir_emit_comp(proc, be->op.kind, left, right);
|
||||
return ir_emit_conv(proc, cmp, type);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case Token_CmpAnd:
|
||||
case Token_CmpOr:
|
||||
@@ -5307,7 +5341,8 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
||||
irValue *len = ir_const_int(a, t->Vector.count);
|
||||
ir_emit_bounds_check(proc, ast_node_token(ie->index), index, len);
|
||||
return ir_addr(elem);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case Type_Array: {
|
||||
irValue *array = nullptr;
|
||||
@@ -5324,7 +5359,8 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
||||
irValue *len = ir_const_int(a, t->Vector.count);
|
||||
ir_emit_bounds_check(proc, ast_node_token(ie->index), index, len);
|
||||
return ir_addr(elem);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case Type_Slice: {
|
||||
irValue *slice = nullptr;
|
||||
@@ -5342,7 +5378,8 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
||||
ir_emit_bounds_check(proc, ast_node_token(ie->index), index, len);
|
||||
irValue *v = ir_emit_ptr_offset(proc, elem, index);
|
||||
return ir_addr(v);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case Type_DynamicArray: {
|
||||
irValue *dynamic_array = nullptr;
|
||||
@@ -5360,7 +5397,8 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
||||
ir_emit_bounds_check(proc, ast_node_token(ie->index), index, len);
|
||||
irValue *v = ir_emit_ptr_offset(proc, elem, index);
|
||||
return ir_addr(v);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case Type_Basic: { // Basic_string
|
||||
@@ -5384,7 +5422,8 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
||||
ir_emit_bounds_check(proc, ast_node_token(ie->index), index, len);
|
||||
|
||||
return ir_addr(ir_emit_ptr_offset(proc, elem, index));
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
case_end;
|
||||
|
||||
@@ -5485,7 +5524,8 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
||||
irValue *str = ir_add_local_generated(proc, t_string);
|
||||
ir_fill_string(proc, str, elem, len);
|
||||
return ir_addr(str);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GB_PANIC("Unknown slicable type");
|
||||
@@ -5544,7 +5584,8 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
||||
ir_emit_store(proc, gep, ev);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case Type_Struct: {
|
||||
// TODO(bill): "constant" unions are not initialized constantly at the moment.
|
||||
@@ -5590,7 +5631,8 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
||||
ir_emit_store(proc, gep, fv);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case Type_Map: {
|
||||
if (cl->elems.count == 0) {
|
||||
@@ -5611,7 +5653,8 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
||||
irValue *value = ir_build_expr(proc, fv->value);
|
||||
ir_insert_dynamic_map_key_and_value(proc, v, type, key, value);
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case Type_DynamicArray: {
|
||||
if (cl->elems.count == 0) {
|
||||
@@ -5649,7 +5692,8 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
||||
args[4] = ir_const_int(a, item_count);
|
||||
ir_emit_global_call(proc, "__dynamic_array_append", args, 5);
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case Type_Array: {
|
||||
if (cl->elems.count > 0) {
|
||||
@@ -5667,7 +5711,8 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
||||
ir_emit_store(proc, gep, ev);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
case Type_Slice: {
|
||||
if (cl->elems.count > 0) {
|
||||
Type *elem_type = bt->Slice.elem;
|
||||
@@ -5695,7 +5740,8 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
||||
irValue *count = ir_const_int(proc->module->allocator, slice->ConstantSlice.count);
|
||||
ir_fill_slice(proc, v, data, count, count);
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case Type_Basic: {
|
||||
GB_ASSERT(is_type_any(bt));
|
||||
@@ -5814,7 +5860,7 @@ irValue *ir_build_cond(irProcedure *proc, AstNode *cond, irBlock *true_block, ir
|
||||
void ir_build_poly_proc(irProcedure *proc, AstNodeProcLit *pd, Entity *e) {
|
||||
GB_ASSERT(pd->body != nullptr);
|
||||
|
||||
if (ptr_set_exists(&proc->module->min_dep_map, e) == false) {
|
||||
if (ptr_set_exists(&proc->module->min_dep_set, e) == false) {
|
||||
// NOTE(bill): Nothing depends upon it so doesn't need to be built
|
||||
return;
|
||||
}
|
||||
@@ -5876,7 +5922,7 @@ void ir_build_constant_value_decl(irProcedure *proc, AstNodeValueDecl *vd) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!polymorphic_struct && !ptr_set_exists(&proc->module->min_dep_map, e)) {
|
||||
if (!polymorphic_struct && !ptr_set_exists(&proc->module->min_dep_set, e)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -5905,7 +5951,7 @@ void ir_build_constant_value_decl(irProcedure *proc, AstNodeValueDecl *vd) {
|
||||
auto procs = *found;
|
||||
for_array(i, procs) {
|
||||
Entity *e = procs[i];
|
||||
if (!ptr_set_exists(&proc->module->min_dep_map, e)) {
|
||||
if (!ptr_set_exists(&proc->module->min_dep_set, e)) {
|
||||
continue;
|
||||
}
|
||||
DeclInfo *d = decl_info_of_entity(info, e);
|
||||
@@ -6061,19 +6107,23 @@ void ir_build_range_indexed(irProcedure *proc, irValue *expr, Type *val_type, ir
|
||||
switch (expr_type->kind) {
|
||||
case Type_Array: {
|
||||
val = ir_emit_load(proc, ir_emit_array_ep(proc, expr, idx));
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
case Type_Vector: {
|
||||
val = ir_emit_load(proc, ir_emit_array_ep(proc, expr, idx));
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
case Type_Slice: {
|
||||
irValue *elem = ir_slice_elem(proc, expr);
|
||||
val = ir_emit_load(proc, ir_emit_ptr_offset(proc, elem, idx));
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
case Type_DynamicArray: {
|
||||
irValue *elem = ir_emit_struct_ep(proc, expr, 0);
|
||||
elem = ir_emit_load(proc, elem);
|
||||
val = ir_emit_load(proc, ir_emit_ptr_offset(proc, elem, idx));
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
case Type_Map: {
|
||||
irValue *entries = ir_emit_struct_ep(proc, expr, 1);
|
||||
irValue *elem = ir_emit_struct_ep(proc, entries, 0);
|
||||
@@ -6093,7 +6143,8 @@ void ir_build_range_indexed(irProcedure *proc, irValue *expr, Type *val_type, ir
|
||||
}
|
||||
|
||||
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
GB_PANIC("Cannot do range_indexed of %s", type_to_string(expr_type));
|
||||
break;
|
||||
@@ -6393,7 +6444,8 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
||||
}
|
||||
}
|
||||
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
// NOTE(bill): Only 1 += 1 is allowed, no tuples
|
||||
@@ -6403,7 +6455,8 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
||||
irAddr lhs = ir_build_addr(proc, as->lhs[0]);
|
||||
irValue *value = ir_build_expr(proc, as->rhs[0]);
|
||||
ir_build_assign_op(proc, lhs, value, cast(TokenKind)op);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gb_temp_arena_memory_end(tmp);
|
||||
@@ -6726,7 +6779,8 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
||||
irValue *entries_ptr = ir_emit_struct_ep(proc, map, 1);
|
||||
irValue *count_ptr = ir_emit_struct_ep(proc, entries_ptr, 1);
|
||||
ir_build_range_indexed(proc, map, val_type, count_ptr, &val, &index, &loop, &done);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
case Type_Array: {
|
||||
irValue *count_ptr = nullptr;
|
||||
irValue *array = ir_build_addr(proc, rs->expr).addr;
|
||||
@@ -6736,7 +6790,8 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
||||
count_ptr = ir_add_local_generated(proc, t_int);
|
||||
ir_emit_store(proc, count_ptr, ir_const_int(proc->module->allocator, et->Array.count));
|
||||
ir_build_range_indexed(proc, array, val_type, count_ptr, &val, &index, &loop, &done);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
case Type_Vector: {
|
||||
irValue *count_ptr = nullptr;
|
||||
irValue *vector = ir_build_addr(proc, rs->expr).addr;
|
||||
@@ -6746,7 +6801,8 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
||||
count_ptr = ir_add_local_generated(proc, t_int);
|
||||
ir_emit_store(proc, count_ptr, ir_const_int(proc->module->allocator, et->Vector.count));
|
||||
ir_build_range_indexed(proc, vector, val_type, count_ptr, &val, &index, &loop, &done);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
case Type_DynamicArray: {
|
||||
irValue *count_ptr = nullptr;
|
||||
irValue *array = ir_build_addr(proc, rs->expr).addr;
|
||||
@@ -6755,7 +6811,8 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
||||
}
|
||||
count_ptr = ir_emit_struct_ep(proc, array, 1);
|
||||
ir_build_range_indexed(proc, array, val_type, count_ptr, &val, &index, &loop, &done);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
case Type_Slice: {
|
||||
irValue *count_ptr = nullptr;
|
||||
irValue *slice = ir_build_expr(proc, rs->expr);
|
||||
@@ -6767,7 +6824,8 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
||||
ir_emit_store(proc, count_ptr, ir_slice_count(proc, slice));
|
||||
}
|
||||
ir_build_range_indexed(proc, slice, val_type, count_ptr, &val, &index, &loop, &done);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
case Type_Basic: {
|
||||
irValue *string = ir_build_expr(proc, rs->expr);
|
||||
if (is_type_pointer(ir_type(string))) {
|
||||
@@ -6779,7 +6837,8 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
||||
string = ir_emit_load(proc, s);
|
||||
}
|
||||
ir_build_range_string(proc, string, val_type, &val, &index, &loop, &done);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
GB_PANIC("Cannot range over %s", type_to_string(expr_type));
|
||||
break;
|
||||
@@ -6812,18 +6871,18 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
||||
ir_start_block(proc, done);
|
||||
case_end;
|
||||
|
||||
case_ast_node(ms, MatchStmt, node);
|
||||
ir_emit_comment(proc, str_lit("MatchStmt"));
|
||||
if (ms->init != nullptr) {
|
||||
ir_build_stmt(proc, ms->init);
|
||||
case_ast_node(ss, SwitchStmt, node);
|
||||
ir_emit_comment(proc, str_lit("SwitchStmt"));
|
||||
if (ss->init != nullptr) {
|
||||
ir_build_stmt(proc, ss->init);
|
||||
}
|
||||
irValue *tag = v_true;
|
||||
if (ms->tag != nullptr) {
|
||||
tag = ir_build_expr(proc, ms->tag);
|
||||
if (ss->tag != nullptr) {
|
||||
tag = ir_build_expr(proc, ss->tag);
|
||||
}
|
||||
irBlock *done = ir_new_block(proc, node, "match.done"); // NOTE(bill): Append later
|
||||
irBlock *done = ir_new_block(proc, node, "switch.done"); // NOTE(bill): Append later
|
||||
|
||||
ast_node(body, BlockStmt, ms->body);
|
||||
ast_node(body, BlockStmt, ss->body);
|
||||
|
||||
Array<AstNode *> default_stmts = {};
|
||||
irBlock *default_fall = nullptr;
|
||||
@@ -6841,9 +6900,9 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
||||
|
||||
if (body == nullptr) {
|
||||
if (cc->list.count == 0) {
|
||||
body = ir_new_block(proc, clause, "match.dflt.body");
|
||||
body = ir_new_block(proc, clause, "switch.dflt.body");
|
||||
} else {
|
||||
body = ir_new_block(proc, clause, "match.case.body");
|
||||
body = ir_new_block(proc, clause, "switch.case.body");
|
||||
}
|
||||
}
|
||||
if (append_fall && body == fall) {
|
||||
@@ -6853,7 +6912,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
||||
fall = done;
|
||||
if (i+1 < case_count) {
|
||||
append_fall = true;
|
||||
fall = ir_new_block(proc, clause, "match.fall.body");
|
||||
fall = ir_new_block(proc, clause, "switch.fall.body");
|
||||
}
|
||||
|
||||
if (cc->list.count == 0) {
|
||||
@@ -6867,7 +6926,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
||||
irBlock *next_cond = nullptr;
|
||||
for_array(j, cc->list) {
|
||||
AstNode *expr = unparen_expr(cc->list[j]);
|
||||
next_cond = ir_new_block(proc, clause, "match.case.next");
|
||||
next_cond = ir_new_block(proc, clause, "switch.case.next");
|
||||
irValue *cond = v_false;
|
||||
if (is_ast_node_a_range(expr)) {
|
||||
ast_node(ie, BinaryExpr, expr);
|
||||
@@ -6891,7 +6950,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
||||
}
|
||||
ir_start_block(proc, body);
|
||||
|
||||
ir_push_target_list(proc, ms->label, done, nullptr, fall);
|
||||
ir_push_target_list(proc, ss->label, done, nullptr, fall);
|
||||
ir_open_scope(proc);
|
||||
ir_build_stmt_list(proc, cc->stmts);
|
||||
ir_close_scope(proc, irDeferExit_Default, body);
|
||||
@@ -6906,7 +6965,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
||||
ir_emit_jump(proc, default_block);
|
||||
ir_start_block(proc, default_block);
|
||||
|
||||
ir_push_target_list(proc, ms->label, done, nullptr, default_fall);
|
||||
ir_push_target_list(proc, ss->label, done, nullptr, default_fall);
|
||||
ir_open_scope(proc);
|
||||
ir_build_stmt_list(proc, default_stmts);
|
||||
ir_close_scope(proc, irDeferExit_Default, default_block);
|
||||
@@ -6918,11 +6977,11 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
||||
case_end;
|
||||
|
||||
|
||||
case_ast_node(ms, TypeMatchStmt, node);
|
||||
ir_emit_comment(proc, str_lit("TypeMatchStmt"));
|
||||
case_ast_node(ss, TypeSwitchStmt, node);
|
||||
ir_emit_comment(proc, str_lit("TypeSwitchStmt"));
|
||||
gbAllocator allocator = proc->module->allocator;
|
||||
|
||||
ast_node(as, AssignStmt, ms->tag);
|
||||
ast_node(as, AssignStmt, ss->tag);
|
||||
GB_ASSERT(as->lhs.count == 1);
|
||||
GB_ASSERT(as->rhs.count == 1);
|
||||
|
||||
@@ -6948,15 +7007,15 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
||||
union_data = ir_emit_conv(proc, parent_ptr, t_rawptr);
|
||||
}
|
||||
|
||||
irBlock *start_block = ir_new_block(proc, node, "typematch.case.first");
|
||||
irBlock *start_block = ir_new_block(proc, node, "typeswitch.case.first");
|
||||
ir_emit_jump(proc, start_block);
|
||||
ir_start_block(proc, start_block);
|
||||
|
||||
// NOTE(bill): Append this later
|
||||
irBlock *done = ir_new_block(proc, node, "typematch.done");
|
||||
irBlock *done = ir_new_block(proc, node, "typeswitch.done");
|
||||
AstNode *default_ = nullptr;
|
||||
|
||||
ast_node(body, BlockStmt, ms->body);
|
||||
ast_node(body, BlockStmt, ss->body);
|
||||
|
||||
gb_local_persist i32 weird_count = 0;
|
||||
|
||||
@@ -6968,11 +7027,11 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
||||
continue;
|
||||
}
|
||||
|
||||
irBlock *body = ir_new_block(proc, clause, "typematch.body");
|
||||
irBlock *body = ir_new_block(proc, clause, "typeswitch.body");
|
||||
irBlock *next = nullptr;
|
||||
Type *case_type = nullptr;
|
||||
for_array(type_index, cc->list) {
|
||||
next = ir_new_block(proc, nullptr, "typematch.next");
|
||||
next = ir_new_block(proc, nullptr, "typeswitch.next");
|
||||
case_type = type_of_expr(proc->module->info, cc->list[type_index]);
|
||||
irValue *cond = nullptr;
|
||||
if (match_type_kind == MatchType_Union) {
|
||||
@@ -7028,13 +7087,13 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
||||
}
|
||||
|
||||
ir_store_type_case_implicit(proc, clause, value);
|
||||
ir_type_case_body(proc, ms->label, clause, body, done);
|
||||
ir_type_case_body(proc, ss->label, clause, body, done);
|
||||
ir_start_block(proc, next);
|
||||
}
|
||||
|
||||
if (default_ != nullptr) {
|
||||
ir_store_type_case_implicit(proc, default_, parent_value);
|
||||
ir_type_case_body(proc, ms->label, default_, proc->curr_block, done);
|
||||
ir_type_case_body(proc, ss->label, default_, proc->curr_block, done);
|
||||
} else {
|
||||
ir_emit_jump(proc, done);
|
||||
}
|
||||
@@ -7635,7 +7694,7 @@ void ir_gen_tree(irGen *s) {
|
||||
array_init(&global_variables, m->tmp_allocator, global_variable_max_count);
|
||||
|
||||
m->entry_point_entity = entry_point;
|
||||
m->min_dep_map = info->minimum_dependency_map;
|
||||
m->min_dep_set = info->minimum_dependency_set;
|
||||
|
||||
for_array(i, info->variable_init_order) {
|
||||
DeclInfo *d = info->variable_init_order[i];
|
||||
@@ -7647,7 +7706,7 @@ void ir_gen_tree(irGen *s) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ptr_set_exists(&m->min_dep_map, e)) {
|
||||
if (!ptr_set_exists(&m->min_dep_set, e)) {
|
||||
continue;
|
||||
}
|
||||
DeclInfo *decl = decl_info_of_entity(info, e);
|
||||
@@ -7717,7 +7776,7 @@ void ir_gen_tree(irGen *s) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!polymorphic_struct && !ptr_set_exists(&m->min_dep_map, e)) {
|
||||
if (!polymorphic_struct && !ptr_set_exists(&m->min_dep_set, e)) {
|
||||
// NOTE(bill): Nothing depends upon it so doesn't need to be built
|
||||
continue;
|
||||
}
|
||||
@@ -7766,7 +7825,8 @@ void ir_gen_tree(irGen *s) {
|
||||
if (map_get(&m->members, hash_name) == nullptr) {
|
||||
multi_map_insert(&m->members, hash_name, p);
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8068,7 +8128,8 @@ void ir_gen_tree(irGen *s) {
|
||||
|
||||
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), name);
|
||||
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 1), gtip);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case Type_Basic:
|
||||
ir_emit_comment(proc, str_lit("TypeInfoBasic"));
|
||||
@@ -8092,7 +8153,8 @@ void ir_gen_tree(irGen *s) {
|
||||
tag = ir_emit_conv(proc, variant_ptr, t_type_info_integer_ptr);
|
||||
irValue *is_signed = ir_const_bool(a, (t->Basic.flags & BasicFlag_Unsigned) == 0);
|
||||
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), is_signed);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case Basic_rune:
|
||||
tag = ir_emit_conv(proc, variant_ptr, t_type_info_rune_ptr);
|
||||
@@ -8129,7 +8191,8 @@ void ir_gen_tree(irGen *s) {
|
||||
tag = ir_emit_conv(proc, variant_ptr, t_type_info_pointer_ptr);
|
||||
irValue *gep = ir_get_type_info_ptr(proc, t->Pointer.elem);
|
||||
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
case Type_Array: {
|
||||
ir_emit_comment(proc, str_lit("TypeInfoArray"));
|
||||
tag = ir_emit_conv(proc, variant_ptr, t_type_info_array_ptr);
|
||||
@@ -8143,7 +8206,8 @@ void ir_gen_tree(irGen *s) {
|
||||
irValue *count = ir_emit_struct_ep(proc, tag, 2);
|
||||
ir_emit_store(proc, count, ir_const_int(a, t->Array.count));
|
||||
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
case Type_DynamicArray: {
|
||||
ir_emit_comment(proc, str_lit("TypeInfoDynamicArray"));
|
||||
tag = ir_emit_conv(proc, variant_ptr, t_type_info_dynamic_array_ptr);
|
||||
@@ -8153,7 +8217,8 @@ void ir_gen_tree(irGen *s) {
|
||||
isize ez = type_size_of(a, t->DynamicArray.elem);
|
||||
irValue *elem_size = ir_emit_struct_ep(proc, tag, 1);
|
||||
ir_emit_store(proc, elem_size, ir_const_int(a, ez));
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
case Type_Slice: {
|
||||
ir_emit_comment(proc, str_lit("TypeInfoSlice"));
|
||||
tag = ir_emit_conv(proc, variant_ptr, t_type_info_slice_ptr);
|
||||
@@ -8163,7 +8228,8 @@ void ir_gen_tree(irGen *s) {
|
||||
isize ez = type_size_of(a, t->Slice.elem);
|
||||
irValue *elem_size = ir_emit_struct_ep(proc, tag, 1);
|
||||
ir_emit_store(proc, elem_size, ir_const_int(a, ez));
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
case Type_Vector: {
|
||||
ir_emit_comment(proc, str_lit("TypeInfoVector"));
|
||||
tag = ir_emit_conv(proc, variant_ptr, t_type_info_vector_ptr);
|
||||
@@ -8174,7 +8240,8 @@ void ir_gen_tree(irGen *s) {
|
||||
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 1), ir_const_int(a, ez));
|
||||
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 2), ir_const_int(a, t->Vector.count));
|
||||
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
case Type_Proc: {
|
||||
ir_emit_comment(proc, str_lit("TypeInfoProc"));
|
||||
tag = ir_emit_conv(proc, variant_ptr, t_type_info_procedure_ptr);
|
||||
@@ -8194,7 +8261,8 @@ void ir_gen_tree(irGen *s) {
|
||||
ir_emit_store(proc, convention, ir_const_int(a, t->Proc.calling_convention));
|
||||
|
||||
// TODO(bill): TypeInfo for procedures
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
case Type_Tuple: {
|
||||
ir_emit_comment(proc, str_lit("TypeInfoTuple"));
|
||||
tag = ir_emit_conv(proc, variant_ptr, t_type_info_tuple_ptr);
|
||||
@@ -8219,7 +8287,8 @@ void ir_gen_tree(irGen *s) {
|
||||
irValue *count = ir_const_int(a, t->Tuple.variables.count);
|
||||
ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 0), memory_types, count, count);
|
||||
ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 1), memory_names, count, count);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
case Type_Enum:
|
||||
ir_emit_comment(proc, str_lit("TypeInfoEnum"));
|
||||
tag = ir_emit_conv(proc, variant_ptr, t_type_info_enum_ptr);
|
||||
@@ -8293,7 +8362,8 @@ void ir_gen_tree(irGen *s) {
|
||||
ir_emit_store(proc, tag_offset_ptr, ir_const_int(a, tag_offset));
|
||||
}
|
||||
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case Type_Struct: {
|
||||
ir_emit_comment(proc, str_lit("TypeInfoStruct"));
|
||||
@@ -8347,7 +8417,8 @@ void ir_gen_tree(irGen *s) {
|
||||
ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 1), memory_names, cv, cv);
|
||||
ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 2), memory_offsets, cv, cv);
|
||||
ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 3), memory_usings, cv, cv);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
case Type_Map: {
|
||||
ir_emit_comment(proc, str_lit("TypeInfoMap"));
|
||||
tag = ir_emit_conv(proc, variant_ptr, t_type_info_map_ptr);
|
||||
@@ -8360,7 +8431,8 @@ void ir_gen_tree(irGen *s) {
|
||||
ir_emit_store(proc, key, ir_get_type_info_ptr(proc, t->Map.key));
|
||||
ir_emit_store(proc, value, ir_get_type_info_ptr(proc, t->Map.value));
|
||||
ir_emit_store(proc, generated_struct, ir_get_type_info_ptr(proc, t->Map.generated_struct_type));
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
case Type_BitField: {
|
||||
ir_emit_comment(proc, str_lit("TypeInfoBitField"));
|
||||
@@ -8403,7 +8475,8 @@ void ir_gen_tree(irGen *s) {
|
||||
irValue *offset_array_elem = ir_array_elem(proc, offset_array);
|
||||
ir_fill_slice(proc, offsets, offset_array_elem, v_count, v_count);
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+57
-40
@@ -281,14 +281,14 @@ AST_NODE_KIND(_ComplexStmtBegin, "", i32) \
|
||||
Array<AstNode *> list; \
|
||||
Array<AstNode *> stmts; \
|
||||
}) \
|
||||
AST_NODE_KIND(MatchStmt, "match statement", struct { \
|
||||
AST_NODE_KIND(SwitchStmt, "switch statement", struct { \
|
||||
Token token; \
|
||||
AstNode *label; \
|
||||
AstNode *init; \
|
||||
AstNode *tag; \
|
||||
AstNode *body; \
|
||||
}) \
|
||||
AST_NODE_KIND(TypeMatchStmt, "type match statement", struct { \
|
||||
AST_NODE_KIND(TypeSwitchStmt, "type switch statement", struct { \
|
||||
Token token; \
|
||||
AstNode *label; \
|
||||
AstNode *tag; \
|
||||
@@ -575,8 +575,8 @@ Token ast_node_token(AstNode *node) {
|
||||
case AstNode_ForStmt: return node->ForStmt.token;
|
||||
case AstNode_RangeStmt: return node->RangeStmt.token;
|
||||
case AstNode_CaseClause: return node->CaseClause.token;
|
||||
case AstNode_MatchStmt: return node->MatchStmt.token;
|
||||
case AstNode_TypeMatchStmt: return node->TypeMatchStmt.token;
|
||||
case AstNode_SwitchStmt: return node->SwitchStmt.token;
|
||||
case AstNode_TypeSwitchStmt: return node->TypeSwitchStmt.token;
|
||||
case AstNode_DeferStmt: return node->DeferStmt.token;
|
||||
case AstNode_BranchStmt: return node->BranchStmt.token;
|
||||
case AstNode_UsingStmt: return node->UsingStmt.token;
|
||||
@@ -783,16 +783,16 @@ AstNode *clone_ast_node(gbAllocator a, AstNode *node) {
|
||||
n->CaseClause.list = clone_ast_node_array(a, n->CaseClause.list);
|
||||
n->CaseClause.stmts = clone_ast_node_array(a, n->CaseClause.stmts);
|
||||
break;
|
||||
case AstNode_MatchStmt:
|
||||
n->MatchStmt.label = clone_ast_node(a, n->MatchStmt.label);
|
||||
n->MatchStmt.init = clone_ast_node(a, n->MatchStmt.init);
|
||||
n->MatchStmt.tag = clone_ast_node(a, n->MatchStmt.tag);
|
||||
n->MatchStmt.body = clone_ast_node(a, n->MatchStmt.body);
|
||||
case AstNode_SwitchStmt:
|
||||
n->SwitchStmt.label = clone_ast_node(a, n->SwitchStmt.label);
|
||||
n->SwitchStmt.init = clone_ast_node(a, n->SwitchStmt.init);
|
||||
n->SwitchStmt.tag = clone_ast_node(a, n->SwitchStmt.tag);
|
||||
n->SwitchStmt.body = clone_ast_node(a, n->SwitchStmt.body);
|
||||
break;
|
||||
case AstNode_TypeMatchStmt:
|
||||
n->TypeMatchStmt.label = clone_ast_node(a, n->TypeMatchStmt.label);
|
||||
n->TypeMatchStmt.tag = clone_ast_node(a, n->TypeMatchStmt.tag);
|
||||
n->TypeMatchStmt.body = clone_ast_node(a, n->TypeMatchStmt.body);
|
||||
case AstNode_TypeSwitchStmt:
|
||||
n->TypeSwitchStmt.label = clone_ast_node(a, n->TypeSwitchStmt.label);
|
||||
n->TypeSwitchStmt.tag = clone_ast_node(a, n->TypeSwitchStmt.tag);
|
||||
n->TypeSwitchStmt.body = clone_ast_node(a, n->TypeSwitchStmt.body);
|
||||
break;
|
||||
case AstNode_DeferStmt:
|
||||
n->DeferStmt.stmt = clone_ast_node(a, n->DeferStmt.stmt);
|
||||
@@ -1266,20 +1266,20 @@ AstNode *ast_range_stmt(AstFile *f, Token token, AstNode *value, AstNode *index,
|
||||
}
|
||||
|
||||
AstNode *ast_match_stmt(AstFile *f, Token token, AstNode *init, AstNode *tag, AstNode *body) {
|
||||
AstNode *result = make_ast_node(f, AstNode_MatchStmt);
|
||||
result->MatchStmt.token = token;
|
||||
result->MatchStmt.init = init;
|
||||
result->MatchStmt.tag = tag;
|
||||
result->MatchStmt.body = body;
|
||||
AstNode *result = make_ast_node(f, AstNode_SwitchStmt);
|
||||
result->SwitchStmt.token = token;
|
||||
result->SwitchStmt.init = init;
|
||||
result->SwitchStmt.tag = tag;
|
||||
result->SwitchStmt.body = body;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
AstNode *ast_type_match_stmt(AstFile *f, Token token, AstNode *tag, AstNode *body) {
|
||||
AstNode *result = make_ast_node(f, AstNode_TypeMatchStmt);
|
||||
result->TypeMatchStmt.token = token;
|
||||
result->TypeMatchStmt.tag = tag;
|
||||
result->TypeMatchStmt.body = body;
|
||||
AstNode *result = make_ast_node(f, AstNode_TypeSwitchStmt);
|
||||
result->TypeSwitchStmt.token = token;
|
||||
result->TypeSwitchStmt.tag = tag;
|
||||
result->TypeSwitchStmt.body = body;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1774,7 +1774,7 @@ void fix_advance_to_next_stmt(AstFile *f) {
|
||||
case Token_for:
|
||||
case Token_when:
|
||||
case Token_return:
|
||||
case Token_match:
|
||||
case Token_switch:
|
||||
case Token_defer:
|
||||
case Token_asm:
|
||||
case Token_using:
|
||||
@@ -1823,12 +1823,15 @@ bool is_semicolon_optional_for_node(AstFile *f, AstNode *s) {
|
||||
}
|
||||
|
||||
switch (s->kind) {
|
||||
case AstNode_EmptyStmt:
|
||||
return true;
|
||||
|
||||
case AstNode_IfStmt:
|
||||
case AstNode_WhenStmt:
|
||||
case AstNode_ForStmt:
|
||||
case AstNode_RangeStmt:
|
||||
case AstNode_MatchStmt:
|
||||
case AstNode_TypeMatchStmt:
|
||||
case AstNode_SwitchStmt:
|
||||
case AstNode_TypeSwitchStmt:
|
||||
return true;
|
||||
|
||||
case AstNode_PointerType:
|
||||
@@ -1842,6 +1845,11 @@ bool is_semicolon_optional_for_node(AstFile *f, AstNode *s) {
|
||||
case AstNode_ProcLit:
|
||||
return s->ProcLit.body != nullptr;
|
||||
|
||||
case AstNode_ImportDecl:
|
||||
case AstNode_ExportDecl:
|
||||
case AstNode_ForeignLibraryDecl:
|
||||
return true;
|
||||
|
||||
case AstNode_ValueDecl:
|
||||
if (s->ValueDecl.is_mutable) {
|
||||
return false;
|
||||
@@ -3176,7 +3184,7 @@ AstNode *parse_simple_stmt(AstFile *f, StmtAllowFlag flags) {
|
||||
TokenKind next = look_ahead_token_kind(f, 1);
|
||||
switch (next) {
|
||||
case Token_for:
|
||||
case Token_match: {
|
||||
case Token_switch: {
|
||||
expect_token_after(f, Token_Colon, "identifier list");
|
||||
AstNode *name = lhs[0];
|
||||
AstNode *label = ast_label_decl(f, ast_node_token(name), name);
|
||||
@@ -3185,8 +3193,8 @@ AstNode *parse_simple_stmt(AstFile *f, StmtAllowFlag flags) {
|
||||
switch (stmt->kind) {
|
||||
_SET_LABEL(ForStmt, label);
|
||||
_SET_LABEL(RangeStmt, label);
|
||||
_SET_LABEL(MatchStmt, label);
|
||||
_SET_LABEL(TypeMatchStmt, label);
|
||||
_SET_LABEL(SwitchStmt, label);
|
||||
_SET_LABEL(TypeSwitchStmt, label);
|
||||
default:
|
||||
syntax_error(token, "Labels can only be applied to a loop or match statement");
|
||||
break;
|
||||
@@ -4238,7 +4246,7 @@ AstNode *parse_match_stmt(AstFile *f) {
|
||||
return ast_bad_stmt(f, f->curr_token, f->curr_token);
|
||||
}
|
||||
|
||||
Token token = expect_token(f, Token_match);
|
||||
Token token = expect_token(f, Token_switch);
|
||||
AstNode *init = nullptr;
|
||||
AstNode *tag = nullptr;
|
||||
AstNode *body = nullptr;
|
||||
@@ -4366,12 +4374,15 @@ AstNode *parse_import_decl(AstFile *f, bool is_using) {
|
||||
cond = parse_expr(f, false);
|
||||
}
|
||||
|
||||
expect_semicolon(f, nullptr);
|
||||
AstNode *s = nullptr;
|
||||
if (f->curr_proc != nullptr) {
|
||||
syntax_error(import_name, "You cannot use `import` within a procedure. This must be done at the file scope");
|
||||
return ast_bad_decl(f, import_name, file_path);
|
||||
s = ast_bad_decl(f, import_name, file_path);
|
||||
} else {
|
||||
s = ast_import_decl(f, token, is_using, file_path, import_name, cond, docs, f->line_comment);
|
||||
}
|
||||
return ast_import_decl(f, token, is_using, file_path, import_name, cond, docs, f->line_comment);
|
||||
expect_semicolon(f, s);
|
||||
return s;
|
||||
}
|
||||
|
||||
AstNode *parse_export_decl(AstFile *f) {
|
||||
@@ -4383,12 +4394,16 @@ AstNode *parse_export_decl(AstFile *f) {
|
||||
if (allow_token(f, Token_when)) {
|
||||
cond = parse_expr(f, false);
|
||||
}
|
||||
expect_semicolon(f, nullptr);
|
||||
|
||||
AstNode *s = nullptr;
|
||||
if (f->curr_proc != nullptr) {
|
||||
syntax_error(token, "You cannot use `export` within a procedure. This must be done at the file scope");
|
||||
return ast_bad_decl(f, token, file_path);
|
||||
s = ast_bad_decl(f, token, file_path);
|
||||
} else {
|
||||
s = ast_export_decl(f, token, file_path, cond, docs, f->line_comment);
|
||||
}
|
||||
return ast_export_decl(f, token, file_path, cond, docs, f->line_comment);
|
||||
expect_semicolon(f, s);
|
||||
return s;
|
||||
}
|
||||
|
||||
AstNode *parse_foreign_decl(AstFile *f) {
|
||||
@@ -4425,14 +4440,16 @@ AstNode *parse_foreign_decl(AstFile *f) {
|
||||
cond = parse_expr(f, false);
|
||||
}
|
||||
|
||||
expect_semicolon(f, nullptr);
|
||||
|
||||
AstNode *s = nullptr;
|
||||
if (f->curr_proc != nullptr) {
|
||||
syntax_error(lib_name, "You cannot use foreign_system_library within a procedure. This must be done at the file scope");
|
||||
return ast_bad_decl(f, lib_name, file_path);
|
||||
s = ast_bad_decl(f, lib_name, file_path);
|
||||
} else {
|
||||
s = ast_foreign_library_decl(f, token, file_path, lib_name, cond, docs, f->line_comment);
|
||||
}
|
||||
|
||||
return ast_foreign_library_decl(f, token, file_path, lib_name, cond, docs, f->line_comment);
|
||||
expect_semicolon(f, s);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
@@ -4478,7 +4495,7 @@ AstNode *parse_stmt(AstFile *f) {
|
||||
case Token_if: return parse_if_stmt(f);
|
||||
case Token_when: return parse_when_stmt(f);
|
||||
case Token_for: return parse_for_stmt(f);
|
||||
case Token_match: return parse_match_stmt(f);
|
||||
case Token_switch: return parse_match_stmt(f);
|
||||
case Token_defer: return parse_defer_stmt(f);
|
||||
case Token_asm: return parse_asm_stmt(f);
|
||||
case Token_return: return parse_return_stmt(f);
|
||||
|
||||
+5
-5
@@ -2138,12 +2138,12 @@ void ssa_build_stmt_internal(ssaProc *p, AstNode *node) {
|
||||
GB_PANIC("TODO: RangeStmt");
|
||||
case_end;
|
||||
|
||||
case_ast_node(rs, MatchStmt, node);
|
||||
GB_PANIC("TODO: MatchStmt");
|
||||
case_ast_node(rs, SwitchStmt, node);
|
||||
GB_PANIC("TODO: SwitchStmt");
|
||||
case_end;
|
||||
|
||||
case_ast_node(rs, TypeMatchStmt, node);
|
||||
GB_PANIC("TODO: TypeMatchStmt");
|
||||
case_ast_node(rs, TypeSwitchStmt, node);
|
||||
GB_PANIC("TODO: TypeSwitchStmt");
|
||||
case_end;
|
||||
|
||||
case_ast_node(bs, BranchStmt, node);
|
||||
@@ -2445,7 +2445,7 @@ bool ssa_generate(Parser *parser, CheckerInfo *info) {
|
||||
|
||||
|
||||
m.entry_point_entity = entry_point;
|
||||
m.min_dep_map = generate_minimum_dependency_map(info, entry_point);
|
||||
m.min_dep_map = generate_minimum_dependency_set(info, entry_point);
|
||||
|
||||
for_array(i, info->entities.entries) {
|
||||
auto *entry = &info->entities.entries[i];
|
||||
|
||||
+1
-1
@@ -94,7 +94,7 @@ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \
|
||||
TOKEN_KIND(Token_if, "if"), \
|
||||
TOKEN_KIND(Token_else, "else"), \
|
||||
TOKEN_KIND(Token_for, "for"), \
|
||||
TOKEN_KIND(Token_match, "match"), \
|
||||
TOKEN_KIND(Token_switch, "switch"), \
|
||||
TOKEN_KIND(Token_in, "in"), \
|
||||
TOKEN_KIND(Token_do, "do"), \
|
||||
TOKEN_KIND(Token_case, "case"), \
|
||||
|
||||
Reference in New Issue
Block a user