aboutsummaryrefslogtreecommitdiff
path: root/src/checker/expr.cpp
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2016-09-07 14:03:17 +0100
committerGinger Bill <bill@gingerbill.org>2016-09-07 14:03:17 +0100
commit61fcfd6f3d3c6cffd7e610abab83445b4cd1950d (patch)
treef61e6d7be5f13c79ab3d98c76fcb836901b3c25e /src/checker/expr.cpp
parent455820fc8438ab72c963ef354b9e32f6e5af1e65 (diff)
Begin Type_Info
Missing stuff in records, procedures, and tuples
Diffstat (limited to 'src/checker/expr.cpp')
-rw-r--r--src/checker/expr.cpp68
1 files changed, 68 insertions, 0 deletions
diff --git a/src/checker/expr.cpp b/src/checker/expr.cpp
index eff3852ac..b8919c0bb 100644
--- a/src/checker/expr.cpp
+++ b/src/checker/expr.cpp
@@ -1900,6 +1900,42 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node) {
return NULL;
}
+void add_type_info_type(Checker *c, Type *t) {
+ if (t == NULL) {
+ return;
+ }
+ t = default_type(t);
+ if (map_get(&c->info.type_info_types, hash_pointer(t)) != NULL) {
+ // Types have already been added
+ return;
+ }
+
+ map_set(&c->info.type_info_types, hash_pointer(t), t);
+ Type *bt = get_base_type(t);
+ switch (bt->kind) {
+ case Type_Named: add_type_info_type(c, bt->Named.base); break;
+ case Type_Array: add_type_info_type(c, bt->Array.elem); break;
+ case Type_Slice: add_type_info_type(c, bt->Slice.elem); break;
+ case Type_Vector: add_type_info_type(c, bt->Vector.elem); break;
+ case Type_Pointer: add_type_info_type(c, bt->Pointer.elem); break;
+ case Type_Record: {
+ switch (bt->Record.kind) {
+ case TypeRecord_Enum:
+ add_type_info_type(c, bt->Record.enum_base);
+ break;
+ default:
+ for (isize i = 0; i < bt->Record.field_count; i++) {
+ Entity *f = bt->Record.fields[i];
+ add_type_info_type(c, f->type);
+ }
+ break;
+ }
+ } break;
+ }
+ // TODO(bill): Type info for procedures and tuples
+ // TODO(bill): Remove duplicate identical types efficiently
+}
+
b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) {
GB_ASSERT(call->kind == AstNode_CallExpr);
ast_node(ce, CallExpr, call);
@@ -2652,6 +2688,38 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
operand->type = type;
} break;
+
+ case BuiltinProc_type_info: {
+ if (t_type_info == NULL) {
+ String type_info_str = make_string("Type_Info");
+ Entity **found = map_get(&c->global_scope->elements, hash_string(type_info_str));
+ GB_ASSERT_MSG(found != NULL, "Internal Compiler Error: Could not find type declaration for `Type_Info`");
+ Entity *e = *found;
+ t_type_info = e->type;
+ t_type_info_ptr = make_type_pointer(c->allocator, t_type_info);
+
+ auto *record = &get_base_type(e->type)->Record;
+ GB_ASSERT(record->field_count == 15);
+ t_type_info_named = record->fields[ 1]->type;
+ t_type_info_integer = record->fields[ 2]->type;
+ t_type_info_float = record->fields[ 3]->type;
+ t_type_info_string = record->fields[ 4]->type;
+ t_type_info_boolean = record->fields[ 5]->type;
+ t_type_info_pointer = record->fields[ 6]->type;
+ t_type_info_procedure = record->fields[ 7]->type;
+ t_type_info_array = record->fields[ 8]->type;
+ t_type_info_slice = record->fields[ 9]->type;
+ t_type_info_vector = record->fields[10]->type;
+ t_type_info_struct = record->fields[11]->type;
+ t_type_info_union = record->fields[12]->type;
+ t_type_info_raw_union = record->fields[13]->type;
+ t_type_info_enum = record->fields[14]->type;
+ }
+
+ add_type_info_type(c, operand->type);
+ operand->mode = Addressing_Value;
+ operand->type = t_type_info_ptr;
+ } break;
}
return true;