aboutsummaryrefslogtreecommitdiff
path: root/src/checker/expr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/checker/expr.cpp')
-rw-r--r--src/checker/expr.cpp113
1 files changed, 49 insertions, 64 deletions
diff --git a/src/checker/expr.cpp b/src/checker/expr.cpp
index b8919c0bb..e55efd56d 100644
--- a/src/checker/expr.cpp
+++ b/src/checker/expr.cpp
@@ -45,6 +45,44 @@ b32 check_is_assignable_to_using_subtype(Type *dst, Type *src) {
return false;
}
+
+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_is_assignable_to(Checker *c, Operand *operand, Type *type, b32 is_argument = false) {
if (operand->mode == Addressing_Invalid ||
type == t_invalid) {
@@ -110,6 +148,13 @@ b32 check_is_assignable_to(Checker *c, Operand *operand, Type *type, b32 is_argu
}
}
+
+ if (dst == t_any) {
+ // NOTE(bill): Anything can cast to `Any`
+ add_type_info_type(c, s);
+ return true;
+ }
+
if (is_argument) {
// NOTE(bill): Polymorphism for subtyping
if (check_is_assignable_to_using_subtype(type, src)) {
@@ -133,11 +178,13 @@ void check_assignment(Checker *c, Operand *operand, Type *type, String context_n
if (is_type_untyped(operand->type)) {
Type *target_type = type;
- if (type == NULL)
+ if (type == NULL || is_type_any(type)) {
target_type = default_type(operand->type);
+ }
convert_to_typed(c, operand, target_type);
- if (operand->mode == Addressing_Invalid)
+ if (operand->mode == Addressing_Invalid) {
return;
+ }
}
@@ -1900,42 +1947,6 @@ 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);
@@ -2690,32 +2701,6 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
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;