mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-19 01:01:31 -07:00
Compile as C! Whoop!
This commit is contained in:
@@ -186,7 +186,7 @@ typedef struct ImplicitValueInfo {
|
||||
Type * type;
|
||||
} ImplicitValueInfo;
|
||||
// NOTE(bill): This is initialized later
|
||||
gb_global ImplicitValueInfo implicit_value_infos[ImplicitValue_Count] = {};
|
||||
gb_global ImplicitValueInfo implicit_value_infos[ImplicitValue_Count] = {0};
|
||||
|
||||
|
||||
|
||||
@@ -667,7 +667,7 @@ void add_type_and_value(CheckerInfo *i, AstNode *expression, AddressingMode mode
|
||||
}
|
||||
}
|
||||
|
||||
TypeAndValue tv = {};
|
||||
TypeAndValue tv = {0};
|
||||
tv.type = type;
|
||||
tv.value = value;
|
||||
tv.mode = mode;
|
||||
@@ -852,7 +852,7 @@ void add_type_info_type(Checker *c, Type *t) {
|
||||
|
||||
|
||||
void check_procedure_later(Checker *c, AstFile *file, Token token, DeclInfo *decl, Type *type, AstNode *body, u32 tags) {
|
||||
ProcedureInfo info = {};
|
||||
ProcedureInfo info = {0};
|
||||
info.file = file;
|
||||
info.token = token;
|
||||
info.decl = decl;
|
||||
@@ -879,7 +879,7 @@ Type *const curr_procedure(Checker *c) {
|
||||
}
|
||||
|
||||
void add_curr_ast_file(Checker *c, AstFile *file) {
|
||||
TokenPos zero_pos = {};
|
||||
TokenPos zero_pos = {0};
|
||||
global_error_collector.prev = zero_pos;
|
||||
c->curr_ast_file = file;
|
||||
c->context.decl = file->decl_info;
|
||||
@@ -911,7 +911,7 @@ void add_dependency_to_map(MapEntity *map, CheckerInfo *info, Entity *node) {
|
||||
}
|
||||
|
||||
MapEntity generate_minimum_dependency_map(CheckerInfo *info, Entity *start) {
|
||||
MapEntity map = {}; // Key: Entity *
|
||||
MapEntity map = {0}; // Key: Entity *
|
||||
map_entity_init(&map, heap_allocator());
|
||||
|
||||
for_array(i, info->entities.entries) {
|
||||
@@ -1027,7 +1027,7 @@ void check_global_entity(Checker *c, EntityKind kind) {
|
||||
|
||||
Scope *prev_scope = c->context.scope;
|
||||
c->context.scope = d->scope;
|
||||
check_entity_decl(c, e, d, NULL);
|
||||
check_entity_decl(c, e, d, NULL, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ void check_init_variables(Checker *c, Entity **lhs, isize lhs_count, AstNodeArra
|
||||
|
||||
for_array(i, inits) {
|
||||
AstNode *rhs = inits.e[i];
|
||||
Operand o = {};
|
||||
Operand o = {0};
|
||||
check_multi_expr(c, &o, rhs);
|
||||
if (o.type->kind != Type_Tuple) {
|
||||
array_add(&operands, o);
|
||||
@@ -185,7 +185,7 @@ void check_var_decl_node(Checker *c, AstNode *node) {
|
||||
|
||||
Type *init_type = NULL;
|
||||
if (vd->type) {
|
||||
init_type = check_type(c, vd->type, NULL);
|
||||
init_type = check_type_extra(c, vd->type, NULL, NULL);
|
||||
if (init_type == NULL)
|
||||
init_type = t_invalid;
|
||||
}
|
||||
@@ -280,7 +280,7 @@ void check_const_decl(Checker *c, Entity *e, AstNode *type_expr, AstNode *init_e
|
||||
e->type = t;
|
||||
}
|
||||
|
||||
Operand operand = {};
|
||||
Operand operand = {0};
|
||||
if (init_expr) {
|
||||
check_expr(c, &operand, init_expr);
|
||||
}
|
||||
@@ -296,12 +296,12 @@ void check_type_decl(Checker *c, Entity *e, AstNode *type_expr, Type *def, Cycle
|
||||
}
|
||||
e->type = named;
|
||||
|
||||
CycleChecker local_cycle_checker = {};
|
||||
CycleChecker local_cycle_checker = {0};
|
||||
if (cycle_checker == NULL) {
|
||||
cycle_checker = &local_cycle_checker;
|
||||
}
|
||||
|
||||
Type *bt = check_type(c, type_expr, named, cycle_checker_add(cycle_checker, e));
|
||||
Type *bt = check_type_extra(c, type_expr, named, cycle_checker_add(cycle_checker, e));
|
||||
named->Named.base = bt;
|
||||
named->Named.base = base_type(named->Named.base);
|
||||
if (named->Named.base == t_invalid) {
|
||||
@@ -457,7 +457,7 @@ void check_var_decl(Checker *c, Entity *e, Entity **entities, isize entity_count
|
||||
e->flags |= EntityFlag_Visited;
|
||||
|
||||
if (type_expr != NULL)
|
||||
e->type = check_type(c, type_expr, NULL);
|
||||
e->type = check_type_extra(c, type_expr, NULL, NULL);
|
||||
|
||||
if (init_expr == NULL) {
|
||||
if (type_expr == NULL)
|
||||
@@ -467,7 +467,7 @@ void check_var_decl(Checker *c, Entity *e, Entity **entities, isize entity_count
|
||||
|
||||
if (entities == NULL || entity_count == 1) {
|
||||
GB_ASSERT(entities == NULL || entities[0] == e);
|
||||
Operand operand = {};
|
||||
Operand operand = {0};
|
||||
check_expr(c, &operand, init_expr);
|
||||
check_init_variable(c, e, &operand, str_lit("variable declaration"));
|
||||
}
|
||||
|
||||
@@ -37,7 +37,8 @@ typedef enum EntityFlag {
|
||||
EntityFlag_VectorElem = 1<<5,
|
||||
} EntityFlag;
|
||||
|
||||
typedef struct Entity {
|
||||
typedef struct Entity Entity;
|
||||
struct Entity {
|
||||
EntityKind kind;
|
||||
u32 flags;
|
||||
Token token;
|
||||
@@ -57,8 +58,8 @@ typedef struct Entity {
|
||||
i32 field_index;
|
||||
i32 field_src_index;
|
||||
} Variable;
|
||||
struct {} TypeName;
|
||||
struct {} Procedure;
|
||||
i32 TypeName;
|
||||
i32 Procedure;
|
||||
struct {
|
||||
BuiltinProcId id;
|
||||
} Builtin;
|
||||
@@ -68,14 +69,14 @@ typedef struct Entity {
|
||||
Scope *scope;
|
||||
bool used;
|
||||
} ImportName;
|
||||
struct {} Nil;
|
||||
i32 Nil;
|
||||
struct {
|
||||
// TODO(bill): Should this be a user-level construct rather than compiler-level?
|
||||
ImplicitValueId id;
|
||||
Entity * backing;
|
||||
} ImplicitValue;
|
||||
};
|
||||
} Entity;
|
||||
};
|
||||
|
||||
bool is_entity_exported(Entity *e) {
|
||||
if (e->kind == Entity_ImportName) {
|
||||
|
||||
+65
-66
@@ -1,18 +1,23 @@
|
||||
void check_expr (Checker *c, Operand *operand, AstNode *expression);
|
||||
void check_multi_expr (Checker *c, Operand *operand, AstNode *expression);
|
||||
void check_expr_or_type (Checker *c, Operand *operand, AstNode *expression);
|
||||
ExprKind check_expr_base (Checker *c, Operand *operand, AstNode *expression, Type *type_hint = NULL);
|
||||
Type * check_type (Checker *c, AstNode *expression, Type *named_type = NULL, CycleChecker *cycle_checker = NULL);
|
||||
ExprKind check_expr_base (Checker *c, Operand *operand, AstNode *expression, Type *type_hint);
|
||||
Type * check_type_extra (Checker *c, AstNode *expression, Type *named_type, CycleChecker *cycle_checker);
|
||||
Type * check_type (Checker *c, AstNode *expression);
|
||||
void check_type_decl (Checker *c, Entity *e, AstNode *type_expr, Type *def, CycleChecker *cycle_checker);
|
||||
Entity * check_selector (Checker *c, Operand *operand, AstNode *node);
|
||||
void check_not_tuple (Checker *c, Operand *operand);
|
||||
bool check_value_is_expressible(Checker *c, ExactValue in_value, Type *type, ExactValue *out_value);
|
||||
void convert_to_typed (Checker *c, Operand *operand, Type *target_type, i32 level = 0);
|
||||
bool check_value_is_expressible(Checker *c, ExactValue in_value, Type *type, ExactValue *out_value);
|
||||
void convert_to_typed (Checker *c, Operand *operand, Type *target_type, i32 level);
|
||||
gbString expr_to_string (AstNode *expression);
|
||||
void check_entity_decl (Checker *c, Entity *e, DeclInfo *decl, Type *named_type, CycleChecker *cycle_checker = NULL);
|
||||
void check_entity_decl (Checker *c, Entity *e, DeclInfo *decl, Type *named_type, CycleChecker *cycle_checker);
|
||||
void check_proc_body (Checker *c, Token token, DeclInfo *decl, Type *type, AstNode *body);
|
||||
void update_expr_type (Checker *c, AstNode *e, Type *type, bool final);
|
||||
|
||||
gb_inline Type *check_type(Checker *c, AstNode *expression) {
|
||||
return check_type_extra(c, expression, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool check_is_assignable_to_using_subtype(Type *dst, Type *src) {
|
||||
@@ -46,7 +51,7 @@ bool check_is_assignable_to_using_subtype(Type *dst, Type *src) {
|
||||
}
|
||||
|
||||
|
||||
bool check_is_assignable_to(Checker *c, Operand *operand, Type *type, bool is_argument = false) {
|
||||
bool check_is_assignable_to(Checker *c, Operand *operand, Type *type) {
|
||||
if (operand->mode == Addressing_Invalid ||
|
||||
type == t_invalid) {
|
||||
return true;
|
||||
@@ -138,19 +143,12 @@ bool check_is_assignable_to(Checker *c, Operand *operand, Type *type, bool is_ar
|
||||
return true;
|
||||
}
|
||||
|
||||
if (true || is_argument) {
|
||||
// NOTE(bill): Polymorphism for subtyping
|
||||
if (check_is_assignable_to_using_subtype(type, src)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// NOTE(bill): `content_name` is for debugging and error messages
|
||||
void check_assignment(Checker *c, Operand *operand, Type *type, String context_name, bool is_argument = false) {
|
||||
void check_assignment(Checker *c, Operand *operand, Type *type, String context_name) {
|
||||
check_not_tuple(c, operand);
|
||||
if (operand->mode == Addressing_Invalid) {
|
||||
return;
|
||||
@@ -169,14 +167,14 @@ void check_assignment(Checker *c, Operand *operand, Type *type, String context_n
|
||||
add_type_info_type(c, type);
|
||||
target_type = default_type(operand->type);
|
||||
}
|
||||
convert_to_typed(c, operand, target_type);
|
||||
convert_to_typed(c, operand, target_type, 0);
|
||||
if (operand->mode == Addressing_Invalid) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (type != NULL) {
|
||||
if (!check_is_assignable_to(c, operand, type, is_argument)) {
|
||||
if (!check_is_assignable_to(c, operand, type)) {
|
||||
gbString type_str = type_to_string(type);
|
||||
gbString op_type_str = type_to_string(operand->type);
|
||||
gbString expr_str = expr_to_string(operand->expr);
|
||||
@@ -243,7 +241,7 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls,
|
||||
CycleChecker *cycle_checker, String context) {
|
||||
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
|
||||
|
||||
MapEntity entity_map = {};
|
||||
MapEntity entity_map = {0};
|
||||
map_entity_init_with_reserve(&entity_map, c->tmp_allocator, 2*(field_count+other_field_count));
|
||||
|
||||
isize other_field_index = 0;
|
||||
@@ -350,7 +348,7 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls,
|
||||
}
|
||||
|
||||
ast_node(vd, VarDecl, decl);
|
||||
Type *base_type = check_type(c, vd->type, NULL, cycle_checker);
|
||||
Type *base_type = check_type_extra(c, vd->type, NULL, cycle_checker);
|
||||
|
||||
for_array(name_index, vd->names) {
|
||||
AstNode *name = vd->names.e[name_index];
|
||||
@@ -386,7 +384,7 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls,
|
||||
}
|
||||
ast_node(vd, VarDecl, decl);
|
||||
|
||||
Type *type = check_type(c, vd->type, NULL, cycle_checker);
|
||||
Type *type = check_type_extra(c, vd->type, NULL, cycle_checker);
|
||||
|
||||
if (vd->is_using) {
|
||||
if (vd->names.count > 1) {
|
||||
@@ -459,8 +457,8 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls,
|
||||
|
||||
// TODO(bill): Cleanup struct field reordering
|
||||
// TODO(bill): Inline sorting procedure?
|
||||
gb_global BaseTypeSizes __checker_sizes = {};
|
||||
gb_global gbAllocator __checker_allocator = {};
|
||||
gb_global BaseTypeSizes __checker_sizes = {0};
|
||||
gb_global gbAllocator __checker_allocator = {0};
|
||||
|
||||
GB_COMPARE_PROC(cmp_struct_entity_size) {
|
||||
// Rule:
|
||||
@@ -677,7 +675,7 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
|
||||
|
||||
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
|
||||
|
||||
MapEntity entity_map = {};
|
||||
MapEntity entity_map = {0};
|
||||
map_entity_init_with_reserve(&entity_map, c->tmp_allocator, 2*(et->fields.count));
|
||||
|
||||
Entity *blank_entity = make_entity_constant(c->allocator, c->context.scope, blank_token, constant_type, make_exact_value_integer(0));;
|
||||
@@ -702,7 +700,7 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
|
||||
continue;
|
||||
}
|
||||
|
||||
Operand o = {};
|
||||
Operand o = {0};
|
||||
if (f->value != NULL) {
|
||||
check_expr(c, &o, f->value);
|
||||
if (o.mode != Addressing_Constant) {
|
||||
@@ -892,7 +890,7 @@ void check_identifier(Checker *c, Operand *o, AstNode *n, Type *named_type, Cycl
|
||||
}
|
||||
add_entity_use(c, n, e);
|
||||
|
||||
// CycleChecker local_cycle_checker = {};
|
||||
// CycleChecker local_cycle_checker = {0};
|
||||
// if (cycle_checker == NULL) {
|
||||
// cycle_checker = &local_cycle_checker;
|
||||
// }
|
||||
@@ -990,7 +988,7 @@ i64 check_array_count(Checker *c, AstNode *e) {
|
||||
if (e == NULL) {
|
||||
return 0;
|
||||
}
|
||||
Operand o = {};
|
||||
Operand o = {0};
|
||||
check_expr(c, &o, e);
|
||||
if (o.mode != Addressing_Constant) {
|
||||
if (o.mode != Addressing_Invalid) {
|
||||
@@ -1013,14 +1011,14 @@ i64 check_array_count(Checker *c, AstNode *e) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Type *check_type(Checker *c, AstNode *e, Type *named_type, CycleChecker *cycle_checker) {
|
||||
Type *check_type_extra(Checker *c, AstNode *e, Type *named_type, CycleChecker *cycle_checker) {
|
||||
ExactValue null_value = {ExactValue_Invalid};
|
||||
Type *type = NULL;
|
||||
gbString err_str = NULL;
|
||||
|
||||
switch (e->kind) {
|
||||
case_ast_node(i, Ident, e);
|
||||
Operand o = {};
|
||||
Operand o = {0};
|
||||
check_identifier(c, &o, e, named_type, cycle_checker);
|
||||
|
||||
switch (o.mode) {
|
||||
@@ -1042,7 +1040,7 @@ Type *check_type(Checker *c, AstNode *e, Type *named_type, CycleChecker *cycle_c
|
||||
case_end;
|
||||
|
||||
case_ast_node(se, SelectorExpr, e);
|
||||
Operand o = {};
|
||||
Operand o = {0};
|
||||
check_selector(c, &o, e);
|
||||
|
||||
switch (o.mode) {
|
||||
@@ -1064,7 +1062,7 @@ Type *check_type(Checker *c, AstNode *e, Type *named_type, CycleChecker *cycle_c
|
||||
case_end;
|
||||
|
||||
case_ast_node(pe, ParenExpr, e);
|
||||
type = check_type(c, pe->expr, named_type, cycle_checker);
|
||||
type = check_type_extra(c, pe->expr, named_type, cycle_checker);
|
||||
goto end;
|
||||
case_end;
|
||||
|
||||
@@ -1092,7 +1090,7 @@ Type *check_type(Checker *c, AstNode *e, Type *named_type, CycleChecker *cycle_c
|
||||
|
||||
case_ast_node(at, ArrayType, e);
|
||||
if (at->count != NULL) {
|
||||
Type *elem = check_type(c, at->elem, NULL, cycle_checker);
|
||||
Type *elem = check_type_extra(c, at->elem, NULL, cycle_checker);
|
||||
type = make_type_array(c->allocator, elem, check_array_count(c, at->count));
|
||||
} else {
|
||||
Type *elem = check_type(c, at->elem);
|
||||
@@ -1164,7 +1162,7 @@ Type *check_type(Checker *c, AstNode *e, Type *named_type, CycleChecker *cycle_c
|
||||
case_end;
|
||||
|
||||
case_ast_node(ce, CallExpr, e);
|
||||
Operand o = {};
|
||||
Operand o = {0};
|
||||
check_expr_or_type(c, &o, e);
|
||||
if (o.mode == Addressing_Type) {
|
||||
type = o.type;
|
||||
@@ -1586,7 +1584,7 @@ void check_shift(Checker *c, Operand *x, Operand *y, AstNode *node) {
|
||||
GB_ASSERT(node->kind == AstNode_BinaryExpr);
|
||||
ast_node(be, BinaryExpr, node);
|
||||
|
||||
ExactValue x_val = {};
|
||||
ExactValue x_val = {0};
|
||||
if (x->mode == Addressing_Constant) {
|
||||
x_val = exact_value_to_integer(x->value);
|
||||
}
|
||||
@@ -1604,7 +1602,7 @@ void check_shift(Checker *c, Operand *x, Operand *y, AstNode *node) {
|
||||
if (is_type_unsigned(y->type)) {
|
||||
|
||||
} else if (is_type_untyped(y->type)) {
|
||||
convert_to_typed(c, y, t_untyped_integer);
|
||||
convert_to_typed(c, y, t_untyped_integer, 0);
|
||||
if (y->mode == Addressing_Invalid) {
|
||||
x->mode = Addressing_Invalid;
|
||||
return;
|
||||
@@ -1741,7 +1739,7 @@ bool check_is_castable_to(Checker *c, Operand *operand, Type *y) {
|
||||
}
|
||||
|
||||
String check_down_cast_name(Type *dst_, Type *src_) {
|
||||
String result = {};
|
||||
String result = {0};
|
||||
Type *dst = type_deref(dst_);
|
||||
Type *src = type_deref(src_);
|
||||
Type *dst_s = base_type(dst);
|
||||
@@ -1776,7 +1774,7 @@ Operand check_ptr_addition(Checker *c, TokenKind op, Operand *ptr, Operand *offs
|
||||
GB_ASSERT(is_type_integer(offset->type));
|
||||
GB_ASSERT(op == Token_Add || op == Token_Sub);
|
||||
|
||||
Operand operand = {};
|
||||
Operand operand = {0};
|
||||
operand.mode = Addressing_Value;
|
||||
operand.type = ptr->type;
|
||||
operand.expr = node;
|
||||
@@ -1809,7 +1807,7 @@ Operand check_ptr_addition(Checker *c, TokenKind op, Operand *ptr, Operand *offs
|
||||
|
||||
void check_binary_expr(Checker *c, Operand *x, AstNode *node) {
|
||||
GB_ASSERT(node->kind == AstNode_BinaryExpr);
|
||||
Operand y_ = {}, *y = &y_;
|
||||
Operand y_ = {0}, *y = &y_;
|
||||
|
||||
ast_node(be, BinaryExpr, node);
|
||||
|
||||
@@ -2079,11 +2077,11 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) {
|
||||
}
|
||||
|
||||
|
||||
convert_to_typed(c, x, y->type);
|
||||
convert_to_typed(c, x, y->type, 0);
|
||||
if (x->mode == Addressing_Invalid) {
|
||||
return;
|
||||
}
|
||||
convert_to_typed(c, y, x->type);
|
||||
convert_to_typed(c, y, x->type, 0);
|
||||
if (y->mode == Addressing_Invalid) {
|
||||
x->mode = Addressing_Invalid;
|
||||
return;
|
||||
@@ -2261,6 +2259,7 @@ void convert_untyped_error(Checker *c, Operand *operand, Type *target_type) {
|
||||
operand->mode = Addressing_Invalid;
|
||||
}
|
||||
|
||||
// NOTE(bill): Set initial level to 0
|
||||
void convert_to_typed(Checker *c, Operand *operand, Type *target_type, i32 level) {
|
||||
GB_ASSERT_NOT_NULL(target_type);
|
||||
if (operand->mode == Addressing_Invalid ||
|
||||
@@ -2348,7 +2347,7 @@ bool check_index_value(Checker *c, AstNode *index_value, i64 max_count, i64 *val
|
||||
return false;
|
||||
}
|
||||
|
||||
convert_to_typed(c, &operand, t_int);
|
||||
convert_to_typed(c, &operand, t_int, 0);
|
||||
if (operand.mode == Addressing_Invalid) {
|
||||
if (value) *value = 0;
|
||||
return false;
|
||||
@@ -2400,7 +2399,7 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node) {
|
||||
bool check_op_expr = true;
|
||||
Entity *expr_entity = NULL;
|
||||
Entity *entity = NULL;
|
||||
Selection sel = {}; // NOTE(bill): Not used if it's an import name
|
||||
Selection sel = {0}; // NOTE(bill): Not used if it's an import name
|
||||
|
||||
AstNode *op_expr = se->expr;
|
||||
AstNode *selector = unparen_expr(se->selector);
|
||||
@@ -2425,7 +2424,7 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node) {
|
||||
goto error;
|
||||
}
|
||||
if (entity->type == NULL) { // Not setup yet
|
||||
check_entity_decl(c, entity, NULL, NULL);
|
||||
check_entity_decl(c, entity, NULL, NULL, NULL);
|
||||
}
|
||||
GB_ASSERT(entity->type != NULL);
|
||||
bool is_not_exported = !is_entity_exported(entity);
|
||||
@@ -2449,7 +2448,7 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node) {
|
||||
}
|
||||
}
|
||||
if (check_op_expr) {
|
||||
check_expr_base(c, operand, op_expr);
|
||||
check_expr_base(c, operand, op_expr, NULL);
|
||||
if (operand->mode == Addressing_Invalid) {
|
||||
goto error;
|
||||
}
|
||||
@@ -2564,7 +2563,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
switch (id) {
|
||||
case BuiltinProc_new: {
|
||||
// new :: proc(Type) -> ^Type
|
||||
Operand op = {};
|
||||
Operand op = {0};
|
||||
check_expr_or_type(c, &op, ce->args.e[0]);
|
||||
Type *type = op.type;
|
||||
if ((op.mode != Addressing_Type && type == NULL) || type == t_invalid) {
|
||||
@@ -2576,7 +2575,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
} break;
|
||||
case BuiltinProc_new_slice: {
|
||||
// new_slice :: proc(Type, len: int[, cap: int]) -> []Type
|
||||
Operand op = {};
|
||||
Operand op = {0};
|
||||
check_expr_or_type(c, &op, ce->args.e[0]);
|
||||
Type *type = op.type;
|
||||
if ((op.mode != Addressing_Type && type == NULL) || type == t_invalid) {
|
||||
@@ -2679,7 +2678,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
|
||||
case BuiltinProc_offset_of: {
|
||||
// offset_of :: proc(Type, field) -> untyped int
|
||||
Operand op = {};
|
||||
Operand op = {0};
|
||||
Type *bt = check_type(c, ce->args.e[0]);
|
||||
Type *type = base_type(bt);
|
||||
if (type == NULL || type == t_invalid) {
|
||||
@@ -2861,7 +2860,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
if (d->kind == Type_Slice) {
|
||||
dest_type = d->Slice.elem;
|
||||
}
|
||||
Operand op = {};
|
||||
Operand op = {0};
|
||||
check_expr(c, &op, ce->args.e[1]);
|
||||
if (op.mode == Addressing_Invalid) {
|
||||
return false;
|
||||
@@ -2900,7 +2899,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
Type *x_type = NULL, *y_type = NULL;
|
||||
x_type = base_type(operand->type);
|
||||
|
||||
Operand op = {};
|
||||
Operand op = {0};
|
||||
check_expr(c, &op, ce->args.e[1]);
|
||||
if (op.mode == Addressing_Invalid) {
|
||||
return false;
|
||||
@@ -2951,7 +2950,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
continue;
|
||||
}
|
||||
AstNode *arg = ce->args.e[i];
|
||||
Operand op = {};
|
||||
Operand op = {0};
|
||||
check_expr(c, &op, arg);
|
||||
if (op.mode == Addressing_Invalid) {
|
||||
return false;
|
||||
@@ -3006,7 +3005,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
}
|
||||
|
||||
AstNode *offset = ce->args.e[1];
|
||||
Operand op = {};
|
||||
Operand op = {0};
|
||||
check_expr(c, &op, offset);
|
||||
if (op.mode == Addressing_Invalid)
|
||||
return false;
|
||||
@@ -3047,7 +3046,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
return false;
|
||||
}
|
||||
AstNode *offset = ce->args[1];
|
||||
Operand op = {};
|
||||
Operand op = {0};
|
||||
check_expr(c, &op, offset);
|
||||
if (op.mode == Addressing_Invalid)
|
||||
return false;
|
||||
@@ -3115,7 +3114,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
cap = ce->args.e[2];
|
||||
}
|
||||
|
||||
Operand op = {};
|
||||
Operand op = {0};
|
||||
check_expr(c, &op, len);
|
||||
if (op.mode == Addressing_Invalid)
|
||||
return false;
|
||||
@@ -3165,7 +3164,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
|
||||
AstNode *other_arg = ce->args.e[1];
|
||||
Operand a = *operand;
|
||||
Operand b = {};
|
||||
Operand b = {0};
|
||||
check_expr(c, &b, other_arg);
|
||||
if (b.mode == Addressing_Invalid) {
|
||||
return false;
|
||||
@@ -3197,11 +3196,11 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
operand->mode = Addressing_Value;
|
||||
operand->type = type;
|
||||
|
||||
convert_to_typed(c, &a, b.type);
|
||||
convert_to_typed(c, &a, b.type, 0);
|
||||
if (a.mode == Addressing_Invalid) {
|
||||
return false;
|
||||
}
|
||||
convert_to_typed(c, &b, a.type);
|
||||
convert_to_typed(c, &b, a.type, 0);
|
||||
if (b.mode == Addressing_Invalid) {
|
||||
return false;
|
||||
}
|
||||
@@ -3234,7 +3233,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
|
||||
AstNode *other_arg = ce->args.e[1];
|
||||
Operand a = *operand;
|
||||
Operand b = {};
|
||||
Operand b = {0};
|
||||
check_expr(c, &b, other_arg);
|
||||
if (b.mode == Addressing_Invalid) {
|
||||
return false;
|
||||
@@ -3266,11 +3265,11 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
operand->mode = Addressing_Value;
|
||||
operand->type = type;
|
||||
|
||||
convert_to_typed(c, &a, b.type);
|
||||
convert_to_typed(c, &a, b.type, 0);
|
||||
if (a.mode == Addressing_Invalid) {
|
||||
return false;
|
||||
}
|
||||
convert_to_typed(c, &b, a.type);
|
||||
convert_to_typed(c, &b, a.type, 0);
|
||||
if (b.mode == Addressing_Invalid) {
|
||||
return false;
|
||||
}
|
||||
@@ -3396,7 +3395,7 @@ void check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode
|
||||
array_init_reserve(&operands, c->tmp_allocator, 2*param_count);
|
||||
|
||||
for_array(i, ce->args) {
|
||||
Operand o = {};
|
||||
Operand o = {0};
|
||||
check_multi_expr(c, &o, ce->args.e[i]);
|
||||
if (o.type->kind != Type_Tuple) {
|
||||
array_add(&operands, o);
|
||||
@@ -3443,7 +3442,7 @@ void check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode
|
||||
if (variadic) {
|
||||
o = operands.e[operand_index];
|
||||
}
|
||||
check_assignment(c, &o, arg_type, str_lit("argument"), true);
|
||||
check_assignment(c, &o, arg_type, str_lit("argument"));
|
||||
}
|
||||
|
||||
if (variadic) {
|
||||
@@ -3463,7 +3462,7 @@ void check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode
|
||||
break;
|
||||
}
|
||||
}
|
||||
check_assignment(c, &o, t, str_lit("argument"), true);
|
||||
check_assignment(c, &o, t, str_lit("argument"));
|
||||
}
|
||||
}
|
||||
end:
|
||||
@@ -3500,7 +3499,7 @@ ExprKind check_call_expr(Checker *c, Operand *operand, AstNode *call) {
|
||||
|
||||
if (operand->mode == Addressing_Invalid) {
|
||||
for_array(i, ce->args) {
|
||||
check_expr_base(c, operand, ce->args.e[i]);
|
||||
check_expr_base(c, operand, ce->args.e[i], NULL);
|
||||
}
|
||||
operand->mode = Addressing_Invalid;
|
||||
operand->expr = call;
|
||||
@@ -3799,7 +3798,7 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
|
||||
case Type_Vector:
|
||||
{
|
||||
Type *elem_type = NULL;
|
||||
String context_name = {};
|
||||
String context_name = {0};
|
||||
if (t->kind == Type_Slice) {
|
||||
elem_type = t->Slice.elem;
|
||||
context_name = str_lit("slice literal");
|
||||
@@ -3839,7 +3838,7 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
|
||||
error(ast_node_token(e), "Index %lld is out of bounds (>= %lld) for vector literal", index, t->Vector.count);
|
||||
}
|
||||
|
||||
Operand operand = {};
|
||||
Operand operand = {0};
|
||||
check_expr_with_type_hint(c, &operand, e, elem_type);
|
||||
check_assignment(c, &operand, elem_type, context_name);
|
||||
|
||||
@@ -4023,7 +4022,7 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
|
||||
|
||||
o->mode = Addressing_Value;
|
||||
|
||||
i64 indices[3] = {};
|
||||
i64 indices[3] = {0};
|
||||
AstNode *nodes[3] = {se->low, se->high, se->max};
|
||||
for (isize i = 0; i < gb_count_of(nodes); i++) {
|
||||
i64 index = max_count;
|
||||
@@ -4157,7 +4156,7 @@ ExprKind check_expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint)
|
||||
|
||||
void check_multi_expr(Checker *c, Operand *o, AstNode *e) {
|
||||
gbString err_str = NULL;
|
||||
check_expr_base(c, o, e);
|
||||
check_expr_base(c, o, e, NULL);
|
||||
switch (o->mode) {
|
||||
default:
|
||||
return; // NOTE(bill): Valid
|
||||
@@ -4195,7 +4194,7 @@ void check_expr(Checker *c, Operand *o, AstNode *e) {
|
||||
|
||||
|
||||
void check_expr_or_type(Checker *c, Operand *o, AstNode *e) {
|
||||
check_expr_base(c, o, e);
|
||||
check_expr_base(c, o, e, NULL);
|
||||
check_not_tuple(c, o);
|
||||
if (o->mode == Addressing_NoValue) {
|
||||
gbString str = expr_to_string(o->expr);
|
||||
|
||||
+21
-21
@@ -1,14 +1,14 @@
|
||||
bool check_is_terminating(AstNode *node);
|
||||
bool check_has_break (AstNode *stmt, bool implicit);
|
||||
bool check_is_terminating(AstNode *node);
|
||||
bool check_has_break (AstNode *stmt, bool implicit);
|
||||
void check_stmt (Checker *c, AstNode *node, u32 flags);
|
||||
|
||||
|
||||
// Statements and Declarations
|
||||
enum StmtFlag : u32 {
|
||||
typedef enum StmtFlag {
|
||||
Stmt_BreakAllowed = GB_BIT(0),
|
||||
Stmt_ContinueAllowed = GB_BIT(1),
|
||||
Stmt_FallthroughAllowed = GB_BIT(2), // TODO(bill): fallthrough
|
||||
};
|
||||
} StmtFlag;
|
||||
|
||||
|
||||
|
||||
@@ -74,10 +74,10 @@ void check_stmt_list(Checker *c, AstNodeArray stmts, u32 flags) {
|
||||
}
|
||||
|
||||
for_array(i, delayed_type) {
|
||||
check_entity_decl(c, delayed_type.e[i].e, delayed_type.e[i].d, NULL);
|
||||
check_entity_decl(c, delayed_type.e[i].e, delayed_type.e[i].d, NULL, NULL);
|
||||
}
|
||||
for_array(i, delayed_const) {
|
||||
check_entity_decl(c, delayed_const.e[i].e, delayed_const.e[i].d, NULL);
|
||||
check_entity_decl(c, delayed_const.e[i].e, delayed_const.e[i].d, NULL, NULL);
|
||||
}
|
||||
|
||||
bool ft_ok = (flags & Stmt_FallthroughAllowed) != 0;
|
||||
@@ -352,7 +352,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
|
||||
case_ast_node(es, ExprStmt, node)
|
||||
Operand operand = {Addressing_Invalid};
|
||||
ExprKind kind = check_expr_base(c, &operand, es->expr);
|
||||
ExprKind kind = check_expr_base(c, &operand, es->expr, NULL);
|
||||
switch (operand.mode) {
|
||||
case Addressing_Type:
|
||||
error(ast_node_token(node), "Is not an expression");
|
||||
@@ -436,7 +436,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
|
||||
for_array(i, as->rhs) {
|
||||
AstNode *rhs = as->rhs.e[i];
|
||||
Operand o = {};
|
||||
Operand o = {0};
|
||||
check_multi_expr(c, &o, rhs);
|
||||
if (o.type->kind != Type_Tuple) {
|
||||
array_add(&operands, o);
|
||||
@@ -592,7 +592,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
case_end;
|
||||
|
||||
case_ast_node(ms, MatchStmt, node);
|
||||
Operand x = {};
|
||||
Operand x = {0};
|
||||
|
||||
mod_flags |= Stmt_BreakAllowed;
|
||||
check_open_scope(c, node);
|
||||
@@ -608,7 +608,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
x.type = t_bool;
|
||||
x.value = make_exact_value_bool(true);
|
||||
|
||||
Token token = {};
|
||||
Token token = {0};
|
||||
token.pos = ast_node_token(ms->body).pos;
|
||||
token.string = str_lit("true");
|
||||
x.expr = make_ident(c->curr_ast_file, token);
|
||||
@@ -642,7 +642,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
}
|
||||
;
|
||||
|
||||
MapTypeAndToken seen = {}; // NOTE(bill): Multimap
|
||||
MapTypeAndToken seen = {0}; // NOTE(bill): Multimap
|
||||
map_type_and_token_init(&seen, heap_allocator());
|
||||
|
||||
for_array(i, bs->stmts) {
|
||||
@@ -656,8 +656,8 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
|
||||
for_array(j, cc->list) {
|
||||
AstNode *expr = cc->list.e[j];
|
||||
Operand y = {};
|
||||
Operand z = {};
|
||||
Operand y = {0};
|
||||
Operand z = {0};
|
||||
Token eq = {Token_CmpEq};
|
||||
|
||||
check_expr(c, &y, expr);
|
||||
@@ -665,7 +665,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
y.mode == Addressing_Invalid) {
|
||||
continue;
|
||||
}
|
||||
convert_to_typed(c, &y, x.type);
|
||||
convert_to_typed(c, &y, x.type, 0);
|
||||
if (y.mode == Addressing_Invalid) {
|
||||
continue;
|
||||
}
|
||||
@@ -732,7 +732,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
case_end;
|
||||
|
||||
case_ast_node(ms, TypeMatchStmt, node);
|
||||
Operand x = {};
|
||||
Operand x = {0};
|
||||
|
||||
mod_flags |= Stmt_BreakAllowed;
|
||||
check_open_scope(c, node);
|
||||
@@ -783,7 +783,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
}
|
||||
|
||||
|
||||
MapBool seen = {};
|
||||
MapBool seen = {0};
|
||||
map_bool_init(&seen, heap_allocator());
|
||||
|
||||
for_array(i, bs->stmts) {
|
||||
@@ -801,7 +801,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
AstNode *type_expr = cc->list.count > 0 ? cc->list.e[0] : NULL;
|
||||
Type *case_type = NULL;
|
||||
if (type_expr != NULL) { // Otherwise it's a default expression
|
||||
Operand y = {};
|
||||
Operand y = {0};
|
||||
check_expr_or_type(c, &y, type_expr);
|
||||
|
||||
if (is_union_ptr) {
|
||||
@@ -915,7 +915,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
String name = expr->Ident.string;
|
||||
e = scope_lookup_entity(c->context.scope, name);
|
||||
} else if (expr->kind == AstNode_SelectorExpr) {
|
||||
Operand o = {};
|
||||
Operand o = {0};
|
||||
e = check_selector(c, &o, expr);
|
||||
is_selector = true;
|
||||
}
|
||||
@@ -1083,7 +1083,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
|
||||
|
||||
case_ast_node(pa, PushAllocator, node);
|
||||
Operand op = {};
|
||||
Operand op = {0};
|
||||
check_expr(c, &op, pa->expr);
|
||||
check_assignment(c, &op, t_allocator, str_lit("argument to push_allocator"));
|
||||
check_stmt(c, pa->body, mod_flags);
|
||||
@@ -1091,7 +1091,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
|
||||
|
||||
case_ast_node(pa, PushContext, node);
|
||||
Operand op = {};
|
||||
Operand op = {0};
|
||||
check_expr(c, &op, pa->expr);
|
||||
check_assignment(c, &op, t_context, str_lit("argument to push_context"));
|
||||
check_stmt(c, pa->body, mod_flags);
|
||||
@@ -1124,7 +1124,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
d->proc_decl = node;
|
||||
|
||||
add_entity_and_decl_info(c, pd->name, e, d);
|
||||
check_entity_decl(c, e, d, NULL);
|
||||
check_entity_decl(c, e, d, NULL, NULL);
|
||||
case_end;
|
||||
}
|
||||
}
|
||||
|
||||
+11
-5
@@ -295,7 +295,7 @@ gb_global Type *t_context_ptr = NULL;
|
||||
|
||||
|
||||
|
||||
gbString type_to_string(Type *type, gbAllocator a = heap_allocator());
|
||||
gbString type_to_string(Type *type);
|
||||
|
||||
Type *base_type(Type *t) {
|
||||
for (;;) {
|
||||
@@ -823,7 +823,13 @@ gb_global Entity *entity__string_count = NULL;
|
||||
gb_global Entity *entity__slice_count = NULL;
|
||||
gb_global Entity *entity__slice_capacity = NULL;
|
||||
|
||||
Selection lookup_field(gbAllocator a, Type *type_, String field_name, bool is_type, Selection sel = empty_selection) {
|
||||
Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_name, bool is_type, Selection sel);
|
||||
|
||||
Selection lookup_field(gbAllocator a, Type *type_, String field_name, bool is_type) {
|
||||
return lookup_field_with_selection(a, type_, field_name, is_type, empty_selection);
|
||||
}
|
||||
|
||||
Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_name, bool is_type, Selection sel) {
|
||||
GB_ASSERT(type_ != NULL);
|
||||
|
||||
if (str_eq(field_name, str_lit("_"))) {
|
||||
@@ -1010,7 +1016,7 @@ Selection lookup_field(gbAllocator a, Type *type_, String field_name, bool is_ty
|
||||
isize prev_count = sel.index.count;
|
||||
selection_add_index(&sel, i); // HACK(bill): Leaky memory
|
||||
|
||||
sel = lookup_field(a, f->type, field_name, is_type, sel);
|
||||
sel = lookup_field_with_selection(a, f->type, field_name, is_type, sel);
|
||||
|
||||
if (sel.entity != NULL) {
|
||||
if (is_type_pointer(f->type)) {
|
||||
@@ -1473,8 +1479,8 @@ gbString write_type_to_string(gbString str, Type *type) {
|
||||
}
|
||||
|
||||
|
||||
gbString type_to_string(Type *type, gbAllocator a) {
|
||||
gbString str = gb_string_make(a, "");
|
||||
gbString type_to_string(Type *type) {
|
||||
gbString str = gb_string_make(gb_heap_allocator(), "");
|
||||
return write_type_to_string(str, type);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user