aboutsummaryrefslogtreecommitdiff
path: root/src/checker
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2016-09-19 23:59:26 +0100
committerGinger Bill <bill@gingerbill.org>2016-09-19 23:59:26 +0100
commit59b0cf61efdccc44efafda24ff59399dde6afc4d (patch)
tree35162a81623e3482929f7c6e3415d517cdf478eb /src/checker
parent3b266b194f36507208b6f90145475d93b53896ee (diff)
fmt improvement; Minor refactoring
Diffstat (limited to 'src/checker')
-rw-r--r--src/checker/checker.cpp20
-rw-r--r--src/checker/expr.cpp59
-rw-r--r--src/checker/type.cpp97
3 files changed, 80 insertions, 96 deletions
diff --git a/src/checker/checker.cpp b/src/checker/checker.cpp
index c891b3024..abb911709 100644
--- a/src/checker/checker.cpp
+++ b/src/checker/checker.cpp
@@ -416,7 +416,7 @@ Entity *scope_insert_entity(Scope *s, Entity *entity) {
void check_scope_usage(Checker *c, Scope *scope) {
// TODO(bill): Use this?
-#if 1
+#if 0
gb_for_array(i, scope->elements.entries) {
auto *entry = scope->elements.entries + i;
Entity *e = entry->value;
@@ -457,9 +457,7 @@ void add_global_entity(Entity *entity) {
}
void add_global_constant(gbAllocator a, String name, Type *type, ExactValue value) {
- Token token = {Token_Identifier};
- token.string = name;
- Entity *entity = alloc_entity(a, Entity_Constant, NULL, token, type);
+ Entity *entity = alloc_entity(a, Entity_Constant, NULL, make_token_ident(name), type);
entity->Constant.value = value;
add_global_entity(entity);
}
@@ -475,14 +473,10 @@ void init_universal_scope(void) {
// Types
for (isize i = 0; i < gb_count_of(basic_types); i++) {
- Token token = {Token_Identifier};
- token.string = basic_types[i].Basic.name;
- add_global_entity(make_entity_type_name(a, NULL, token, &basic_types[i]));
+ add_global_entity(make_entity_type_name(a, NULL, make_token_ident(basic_types[i].Basic.name), &basic_types[i]));
}
for (isize i = 0; i < gb_count_of(basic_type_aliases); i++) {
- Token token = {Token_Identifier};
- token.string = basic_type_aliases[i].Basic.name;
- add_global_entity(make_entity_type_name(a, NULL, token, &basic_type_aliases[i]));
+ add_global_entity(make_entity_type_name(a, NULL, make_token_ident(basic_type_aliases[i].Basic.name), &basic_type_aliases[i]));
}
// Constants
@@ -493,9 +487,7 @@ void init_universal_scope(void) {
// Builtin Procedures
for (isize i = 0; i < gb_count_of(builtin_procs); i++) {
BuiltinProcId id = cast(BuiltinProcId)i;
- Token token = {Token_Identifier};
- token.string = builtin_procs[i].name;
- Entity *entity = alloc_entity(a, Entity_Builtin, NULL, token, t_invalid);
+ Entity *entity = alloc_entity(a, Entity_Builtin, NULL, make_token_ident(builtin_procs[i].name), t_invalid);
entity->Builtin.id = id;
add_global_entity(entity);
}
@@ -968,7 +960,7 @@ void check_parsed_files(Checker *c) {
di->entities = entities;
di->entity_count = entity_count;
di->type_expr = vd->type;
- di->init_expr = vd->values[0]; // TODO(bill): Is this correct?
+ di->init_expr = vd->values[0];
}
gb_for_array(i, vd->names) {
diff --git a/src/checker/expr.cpp b/src/checker/expr.cpp
index 231e467bf..bea09e678 100644
--- a/src/checker/expr.cpp
+++ b/src/checker/expr.cpp
@@ -133,8 +133,7 @@ b32 check_is_assignable_to(Checker *c, Operand *operand, Type *type, b32 is_argu
}
-// NOTE(bill): `content_name` is for debugging
-// TODO(bill): Maybe allow assignment to tuples?
+// NOTE(bill): `content_name` is for debugging and error messages
void check_assignment(Checker *c, Operand *operand, Type *type, String context_name, b32 is_argument = false) {
check_not_tuple(c, operand);
if (operand->mode == Addressing_Invalid)
@@ -153,8 +152,6 @@ void check_assignment(Checker *c, Operand *operand, Type *type, String context_n
}
}
-
-
if (type != NULL) {
if (!check_is_assignable_to(c, operand, type, is_argument)) {
gbString type_string = type_to_string(type);
@@ -579,8 +576,6 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
if (named_type != NULL) {
constant_type = named_type;
}
- Token blank_token = {Token_Identifier};
- blank_token.string = make_string("");
Entity *blank_entity = make_entity_constant(c->allocator, c->context.scope, blank_token, constant_type, make_exact_value_integer(0));;
gb_for_array(i, et->fields) {
@@ -590,15 +585,15 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
Token name_token = f->field->Ident;
if (name_token.string == make_string("count")) {
- error(name_token, "`count` is a reserved identifier for enums");
+ error(name_token, "`count` is a reserved identifier for enumerations");
fields[field_index++] = blank_entity;
continue;
} else if (name_token.string == make_string("min_value")) {
- error(name_token, "`min_value` is a reserved identifier for enums");
+ error(name_token, "`min_value` is a reserved identifier for enumerations");
fields[field_index++] = blank_entity;
continue;
} else if (name_token.string == make_string("max_value")) {
- error(name_token, "`max_value` is a reserved identifier for enums");
+ error(name_token, "`max_value` is a reserved identifier for enumerations");
fields[field_index++] = blank_entity;
continue;
}
@@ -611,7 +606,7 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
o.mode = Addressing_Invalid;
}
if (o.mode != Addressing_Invalid) {
- check_assignment(c, &o, base_type, make_string("enumeration"));
+ check_assignment(c, &o, constant_type, make_string("enumeration"));
}
if (o.mode != Addressing_Invalid) {
iota = o.value;
@@ -639,14 +634,21 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
error(name_token, "`%.*s` is already declared in this enumeration", LIT(name_token.string));
} else {
map_set(&entity_map, key, e);
+ add_entity(c, c->context.scope, NULL, e);
fields[field_index++] = e;
}
add_entity_use(&c->info, f->field, e);
}
- enum_type->Record.min_value = min_value;
- enum_type->Record.max_value = max_value;
+
enum_type->Record.other_fields = fields;
enum_type->Record.other_field_count = gb_array_count(et->fields);
+
+ enum_type->Record.enum_count = make_entity_constant(c->allocator, NULL,
+ make_token_ident(make_string("count")), t_int, make_exact_value_integer(enum_type->Record.other_field_count));
+ enum_type->Record.min_value = make_entity_constant(c->allocator, NULL,
+ make_token_ident(make_string("min_value")), constant_type, make_exact_value_integer(min_value));
+ enum_type->Record.max_value = make_entity_constant(c->allocator, NULL,
+ make_token_ident(make_string("max_value")), constant_type, make_exact_value_integer(max_value));
}
Type *check_get_params(Checker *c, Scope *scope, AstNodeArray fields, b32 *is_variadic_) {
@@ -1019,7 +1021,9 @@ Type *check_type(Checker *c, AstNode *e, Type *named_type, CycleChecker *cycle_c
case_ast_node(et, EnumType, e);
type = make_type_enum(c->allocator);
set_base_type(named_type, type);
+ check_open_scope(c, e);
check_enum_type(c, type, named_type, e);
+ check_close_scope(c);
type->Record.node = e;
goto end;
case_end;
@@ -2070,7 +2074,7 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node) {
}
if (entity == NULL) {
- entity = lookup_field(operand->type, selector->Ident.string, operand->mode == Addressing_Type).entity;
+ entity = lookup_field(c->allocator, operand->type, selector->Ident.string, operand->mode == Addressing_Type).entity;
}
if (entity == NULL) {
gbString op_str = expr_to_string(op_expr);
@@ -2217,7 +2221,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
Operand op = {};
check_expr_or_type(c, &op, ce->args[0]);
Type *type = op.type;
- if (!type) {
+ if (type == NULL || op.mode == Addressing_Builtin) {
error(ast_node_token(ce->args[0]), "Expected a type for `size_of`");
return false;
}
@@ -2231,8 +2235,9 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
case BuiltinProc_size_of_val:
// size_of_val :: proc(val: Type) -> int
check_assignment(c, operand, NULL, make_string("argument of `size_of_val`"));
- if (operand->mode == Addressing_Invalid)
+ if (operand->mode == Addressing_Invalid) {
return false;
+ }
operand->mode = Addressing_Constant;
operand->value = make_exact_value_integer(type_size_of(c->sizes, c->allocator, operand->type));
@@ -2244,7 +2249,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
Operand op = {};
check_expr_or_type(c, &op, ce->args[0]);
Type *type = op.type;
- if (!type) {
+ if (type == NULL || op.mode == Addressing_Builtin) {
error(ast_node_token(ce->args[0]), "Expected a type for `align_of`");
return false;
}
@@ -2256,8 +2261,9 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
case BuiltinProc_align_of_val:
// align_of_val :: proc(val: Type) -> int
check_assignment(c, operand, NULL, make_string("argument of `align_of_val`"));
- if (operand->mode == Addressing_Invalid)
+ if (operand->mode == Addressing_Invalid) {
return false;
+ }
operand->mode = Addressing_Constant;
operand->value = make_exact_value_integer(type_align_of(c->sizes, c->allocator, operand->type));
@@ -2270,7 +2276,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
check_expr_or_type(c, &op, ce->args[0]);
Type *type = get_base_type(op.type);
AstNode *field_arg = unparen_expr(ce->args[1]);
- if (type != NULL) {
+ if (type != NULL || op.mode == Addressing_Builtin) {
error(ast_node_token(ce->args[0]), "Expected a type for `offset_of`");
return false;
}
@@ -2286,7 +2292,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
ast_node(arg, Ident, field_arg);
- Selection sel = lookup_field(type, arg->string, operand->mode == Addressing_Type);
+ Selection sel = lookup_field(c->allocator, type, arg->string, operand->mode == Addressing_Type);
if (sel.entity == NULL) {
gbString type_str = type_to_string(type);
error(ast_node_token(ce->args[0]),
@@ -2324,7 +2330,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
ast_node(i, Ident, s->selector);
- Selection sel = lookup_field(type, i->string, operand->mode == Addressing_Type);
+ Selection sel = lookup_field(c->allocator, type, i->string, operand->mode == Addressing_Type);
if (sel.entity == NULL) {
gbString type_str = type_to_string(type);
error(ast_node_token(arg),
@@ -2341,7 +2347,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
case BuiltinProc_type_of_val:
// type_of_val :: proc(val: Type) -> type(Type)
check_assignment(c, operand, NULL, make_string("argument of `type_of_val`"));
- if (operand->mode == Addressing_Invalid)
+ if (operand->mode == Addressing_Invalid || operand->mode == Addressing_Builtin)
return false;
operand->mode = Addressing_Type;
break;
@@ -2349,11 +2355,16 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
case BuiltinProc_type_info: {
// type_info :: proc(val_or_type) -> ^Type_Info
+ operand->mode = Addressing_Value;
+ operand->type = t_type_info_ptr;
+
Operand op = {};
check_expr_or_type(c, &op, ce->args[0]);
+ if (op.type == NULL || op.type == t_invalid || operand->mode == Addressing_Builtin) {
+ error(ast_node_token(op.expr), "Invalid argument to `type_info`");
+ return false;
+ }
add_type_info_type(c, op.type);
- operand->mode = Addressing_Value;
- operand->type = t_type_info_ptr;
} break;
case BuiltinProc_compile_assert:
@@ -3193,7 +3204,7 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
}
String name = kv->field->Ident.string;
- Selection sel = lookup_field(type, name, o->mode == Addressing_Type);
+ Selection sel = lookup_field(c->allocator, type, name, o->mode == Addressing_Type);
if (sel.entity == NULL) {
error(ast_node_token(elem),
"Unknown field `%.*s` in structure literal", LIT(name));
diff --git a/src/checker/type.cpp b/src/checker/type.cpp
index 215df1612..c8fe672f7 100644
--- a/src/checker/type.cpp
+++ b/src/checker/type.cpp
@@ -120,8 +120,9 @@ struct Type {
// enum only
Type * enum_base; // Default is `int`
- i64 min_value;
- i64 max_value;
+ Entity * enum_count;
+ Entity * min_value;
+ Entity * max_value;
// struct only
i64 * struct_offsets;
@@ -703,25 +704,28 @@ Selection make_selection(Entity *entity, gbArray(isize) index, b32 indirect) {
}
void selection_add_index(Selection *s, isize index) {
+ // IMPORTANT NOTE(bill): this requires a stretchy buffer/dynamic array so it requires some form
+ // of heap allocation
if (s->index == NULL) {
gb_array_init(s->index, gb_heap_allocator());
}
gb_array_append(s->index, index);
}
-gb_global Entity *entity__any_type_info = NULL;
-gb_global Entity *entity__any_data = NULL;
-gb_global Entity *entity__string_data = NULL;
-gb_global Entity *entity__string_count = NULL;
+gb_global Entity *entity__any_type_info = NULL;
+gb_global Entity *entity__any_data = NULL;
+gb_global Entity *entity__string_data = NULL;
+gb_global Entity *entity__string_count = NULL;
+gb_global Entity *entity__slice_count = NULL;
+gb_global Entity *entity__slice_capacity = NULL;
-Selection lookup_field(Type *type_, String field_name, b32 is_type, Selection sel = empty_selection) {
+Selection lookup_field(gbAllocator a, Type *type_, String field_name, b32 is_type, Selection sel = empty_selection) {
GB_ASSERT(type_ != NULL);
if (field_name == make_string("_")) {
return empty_selection;
}
- gbAllocator a = gb_heap_allocator();
Type *type = type_deref(type_);
b32 is_ptr = type != type_;
type = get_base_type(type);
@@ -732,14 +736,10 @@ Selection lookup_field(Type *type_, String field_name, b32 is_type, Selection se
String type_info_str = make_string("type_info");
String data_str = make_string("data");
if (entity__any_type_info == NULL) {
- Token token = {Token_Identifier};
- token.string = type_info_str;
- entity__any_type_info = make_entity_field(a, NULL, token, t_type_info_ptr, false, 0);
+ entity__any_type_info = make_entity_field(a, NULL, make_token_ident(type_info_str), t_type_info_ptr, false, 0);
}
if (entity__any_data == NULL) {
- Token token = {Token_Identifier};
- token.string = data_str;
- entity__any_data = make_entity_field(a, NULL, token, t_rawptr, false, 1);
+ entity__any_data = make_entity_field(a, NULL, make_token_ident(data_str), t_rawptr, false, 1);
}
if (field_name == type_info_str) {
@@ -756,15 +756,11 @@ Selection lookup_field(Type *type_, String field_name, b32 is_type, Selection se
String data_str = make_string("data");
String count_str = make_string("count");
if (entity__string_data == NULL) {
- Token token = {Token_Identifier};
- token.string = data_str;
- entity__string_data = make_entity_field(a, NULL, token, make_type_pointer(a, t_u8), false, 0);
+ entity__string_data = make_entity_field(a, NULL, make_token_ident(data_str), make_type_pointer(a, t_u8), false, 0);
}
if (entity__string_count == NULL) {
- Token token = {Token_Identifier};
- token.string = count_str;
- entity__string_count = make_entity_field(a, NULL, token, t_int, false, 1);
+ entity__string_count = make_entity_field(a, NULL, make_token_ident(count_str), t_int, false, 1);
}
if (field_name == data_str) {
@@ -784,20 +780,16 @@ Selection lookup_field(Type *type_, String field_name, b32 is_type, Selection se
String count_str = make_string("count");
// NOTE(bill): Underlying memory address cannot be changed
if (field_name == count_str) {
- Token token = {Token_Identifier};
- token.string = count_str;
// HACK(bill): Memory leak
- sel.entity = make_entity_constant(a, NULL, token, t_int, make_exact_value_integer(type->Array.count));
+ sel.entity = make_entity_constant(a, NULL, make_token_ident(count_str), t_int, make_exact_value_integer(type->Array.count));
return sel;
}
} else if (type->kind == Type_Vector) {
String count_str = make_string("count");
// NOTE(bill): Vectors are not addressable
if (field_name == count_str) {
- Token token = {Token_Identifier};
- token.string = count_str;
// HACK(bill): Memory leak
- sel.entity = make_entity_constant(a, NULL, token, t_int, make_exact_value_integer(type->Vector.count));
+ sel.entity = make_entity_constant(a, NULL, make_token_ident(count_str), t_int, make_exact_value_integer(type->Vector.count));
return sel;
}
} else if (type->kind == Type_Slice) {
@@ -807,24 +799,24 @@ Selection lookup_field(Type *type_, String field_name, b32 is_type, Selection se
if (field_name == data_str) {
selection_add_index(&sel, 0);
- Token token = {Token_Identifier};
- token.string = data_str;
// HACK(bill): Memory leak
- sel.entity = make_entity_field(a, NULL, token, make_type_pointer(a, type->Slice.elem), false, 0);
+ sel.entity = make_entity_field(a, NULL, make_token_ident(data_str), make_type_pointer(a, type->Slice.elem), false, 0);
return sel;
} else if (field_name == count_str) {
selection_add_index(&sel, 1);
- Token token = {Token_Identifier};
- token.string = count_str;
- // HACK(bill): Memory leak
- sel.entity = make_entity_field(a, NULL, token, t_int, false, 1);
+ if (entity__slice_count == NULL) {
+ entity__slice_count = make_entity_field(a, NULL, make_token_ident(count_str), t_int, false, 1);
+ }
+
+ sel.entity = entity__slice_count;
return sel;
} else if (field_name == capacity_str) {
selection_add_index(&sel, 2);
- Token token = {Token_Identifier};
- token.string = capacity_str;
- // HACK(bill): Memory leak
- sel.entity = make_entity_field(a, NULL, token, t_int, false, 2);
+ if (entity__slice_capacity == NULL) {
+ entity__slice_capacity = make_entity_field(a, NULL, make_token_ident(capacity_str), t_int, false, 2);
+ }
+
+ sel.entity = entity__slice_capacity;
return sel;
}
}
@@ -834,6 +826,8 @@ Selection lookup_field(Type *type_, String field_name, b32 is_type, Selection se
}
if (is_type) {
if (is_type_union(type)) {
+ // NOTE(bill): The subtype for a union are stored in the fields
+ // as they are "kind of" like variables but not
for (isize i = 0; i < type->Record.field_count; i++) {
Entity *f = type->Record.fields[i];
GB_ASSERT(f->kind == Entity_TypeName);
@@ -856,27 +850,14 @@ Selection lookup_field(Type *type_, String field_name, b32 is_type, Selection se
}
if (is_type_enum(type)) {
- String count_str = make_string("count");
- String min_value_str = make_string("min_value");
- String max_value_str = make_string("max_value");
-
- if (field_name == count_str) {
- Token token = {Token_Identifier};
- token.string = count_str;
- // HACK(bill): Memory leak
- sel.entity = make_entity_constant(a, NULL, token, t_int, make_exact_value_integer(type->Record.other_field_count));
+ if (field_name == make_string("count")) {
+ sel.entity = type->Record.enum_count;
return sel;
- } else if (field_name == min_value_str) {
- Token token = {Token_Identifier};
- token.string = min_value_str;
- // HACK(bill): Memory leak
- sel.entity = make_entity_constant(a, NULL, token, type->Record.enum_base, make_exact_value_integer(type->Record.min_value));
+ } else if (field_name == make_string("min_value")) {
+ sel.entity = type->Record.min_value;
return sel;
- } else if (field_name == max_value_str) {
- Token token = {Token_Identifier};
- token.string = max_value_str;
- // HACK(bill): Memory leak
- sel.entity = make_entity_constant(a, NULL, token, type->Record.enum_base, make_exact_value_integer(type->Record.max_value));
+ } else if (field_name == make_string("max_value")) {
+ sel.entity = type->Record.max_value;
return sel;
}
}
@@ -887,7 +868,7 @@ Selection lookup_field(Type *type_, String field_name, b32 is_type, Selection se
GB_ASSERT(f->kind == Entity_Variable && f->Variable.is_field);
String str = f->token.string;
if (field_name == str) {
- selection_add_index(&sel, i);
+ selection_add_index(&sel, i); // HACK(bill): Leaky memory
sel.entity = f;
return sel;
}
@@ -899,7 +880,7 @@ Selection lookup_field(Type *type_, String field_name, b32 is_type, Selection se
}
selection_add_index(&sel, i); // HACK(bill): Leaky memory
- sel = lookup_field(f->type, field_name, is_type, sel);
+ sel = lookup_field(a, f->type, field_name, is_type, sel);
if (sel.entity != NULL) {
if (is_type_pointer(f->type))