Add Type -- Runtime type for comparing types (similar to TypeInfo but simpler)

This commit is contained in:
Ginger Bill
2017-06-29 15:13:41 +01:00
parent d167290b28
commit 001baf4419
10 changed files with 167 additions and 40 deletions
+18 -6
View File
@@ -8,7 +8,6 @@ import (
"mem.odin"; "mem.odin";
"opengl.odin"; "opengl.odin";
"os.odin"; "os.odin";
"pool.odin";
"raw.odin"; "raw.odin";
"strconv.odin"; "strconv.odin";
"strings.odin"; "strings.odin";
@@ -327,11 +326,11 @@ explicit_parametric_polymorphic_procedures :: proc() {
new_entity :: proc(manager: ^EntityManager, Type: type, x, y: int) -> ^Type { new_entity :: proc(manager: ^EntityManager, T: type, x, y: int) -> ^T {
result := new(Type); result := new(T);
result.entity = gen_new_entity(manager); result.entity = gen_new_entity(manager);
result.derived.data = result; result.derived.data = result;
result.derived.type_info = type_info(Type); result.derived.type_info = type_info(T);
result.position.x = f32(x); result.position.x = f32(x);
result.position.y = f32(y); result.position.y = f32(y);
@@ -345,14 +344,14 @@ explicit_parametric_polymorphic_procedures :: proc() {
rock := new_entity(&manager, Rock, 3, 5); rock := new_entity(&manager, Rock, 3, 5);
// Named arguments work too! // Named arguments work too!
door := new_entity(manager = &manager, Type = Door, x = 3, y = 6); door := new_entity(manager = &manager, T = Door, x = 3, y = 6);
// And named arguments can be any order // And named arguments can be any order
monster := new_entity( monster := new_entity(
y = 1, y = 1,
x = 2, x = 2,
manager = &manager, manager = &manager,
Type = Monster, T = Monster,
); );
append(entities, rock, door, monster); append(entities, rock, door, monster);
@@ -380,6 +379,19 @@ main :: proc() {
// Command line argument(s)! // Command line argument(s)!
// -opt=0,1,2,3 // -opt=0,1,2,3
a: Type = int;
b: Type = f32;
c: Type = int;
match a {
case int: fmt.println("a == int");
case f32: fmt.println("a == f32");
case: fmt.println("What type is a?");
}
assert(a != b);
assert(b != c);
assert(a == c);
program := "+ + * - /"; program := "+ + * - /";
accumulator := 0; accumulator := 0;
+1
View File
@@ -61,6 +61,7 @@ TypeInfo :: union {
String{}, String{},
Boolean{}, Boolean{},
Any{}, Any{},
Type{},
Pointer{ Pointer{
elem: ^TypeInfo, // nil -> rawptr elem: ^TypeInfo, // nil -> rawptr
}, },
+22 -2
View File
@@ -328,6 +328,14 @@ void check_assignment(Checker *c, Operand *operand, Type *type, String context_n
return; return;
} }
if (operand->mode == Addressing_Type) {
if (type != NULL && is_type_type(type)) {
add_type_info_type(c, type);
add_type_info_type(c, operand->type);
return;
}
}
if (is_type_untyped(operand->type)) { if (is_type_untyped(operand->type)) {
Type *target_type = type; Type *target_type = type;
if (type == NULL || is_type_any(type)) { if (type == NULL || is_type_any(type)) {
@@ -2604,6 +2612,7 @@ void check_unary_expr(Checker *c, Operand *o, Token op, AstNode *node) {
o->mode = Addressing_Value; o->mode = Addressing_Value;
} }
void check_comparison(Checker *c, Operand *x, Operand *y, TokenKind op) { void check_comparison(Checker *c, Operand *x, Operand *y, TokenKind op) {
if (x->mode == Addressing_Type && y->mode == Addressing_Type) { if (x->mode == Addressing_Type && y->mode == Addressing_Type) {
bool comp = are_types_identical(x->type, y->type); bool comp = are_types_identical(x->type, y->type);
@@ -2616,6 +2625,15 @@ void check_comparison(Checker *c, Operand *x, Operand *y, TokenKind op) {
x->value = exact_value_bool(comp); x->value = exact_value_bool(comp);
return; return;
} }
if (x->mode == Addressing_Type && is_operand_a_type_value(*y)) {
x->mode = Addressing_Value;
x->type = t_untyped_bool;
return;
} else if (y->mode == Addressing_Type && is_operand_a_type_value(*x)) {
x->mode = Addressing_Value;
x->type = t_untyped_bool;
return;
}
gbString err_str = NULL; gbString err_str = NULL;
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena); gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
@@ -3046,11 +3064,13 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) {
check_expr_or_type(c, y, be->right); check_expr_or_type(c, y, be->right);
bool xt = x->mode == Addressing_Type; bool xt = x->mode == Addressing_Type;
bool yt = y->mode == Addressing_Type; bool yt = y->mode == Addressing_Type;
bool xvt = is_operand_a_type_value(*x);
bool yvt = is_operand_a_type_value(*y);
// If only one is a type, this is an error // If only one is a type, this is an error
if (xt ^ yt) { if (xt ^ yt) {
GB_ASSERT(xt != yt); GB_ASSERT(xt != yt);
if (xt) error_operand_not_expression(x); if (xt && !yvt) error_operand_not_expression(x);
if (yt) error_operand_not_expression(y); if (yt && !xvt) error_operand_not_expression(y);
} }
} break; } break;
+5 -1
View File
@@ -1297,7 +1297,11 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
check_comparison(c, &a1, &b1, op); check_comparison(c, &a1, &b1, op);
} else { } else {
Operand y = {}; Operand y = {};
check_expr(c, &y, expr); if (is_operand_a_type_value(x)) {
check_expr_or_type(c, &y, expr);
} else {
check_expr(c, &y, expr);
}
if (x.mode == Addressing_Invalid || if (x.mode == Addressing_Invalid ||
y.mode == Addressing_Invalid) { y.mode == Addressing_Invalid) {
continue; continue;
+35 -24
View File
@@ -170,6 +170,9 @@ bool is_operand_value(Operand o) {
bool is_operand_nil(Operand o) { bool is_operand_nil(Operand o) {
return o.mode == Addressing_Value && o.type == t_untyped_nil; return o.mode == Addressing_Value && o.type == t_untyped_nil;
} }
bool is_operand_a_type_value(Operand o) {
return is_operand_value(o) && is_type_type(o.type);
}
struct BlockLabel { struct BlockLabel {
@@ -325,7 +328,7 @@ DeclInfo * decl_info_of_ident (CheckerInfo *i, AstNode *ident);
DeclInfo * decl_info_of_entity (CheckerInfo *i, Entity * e); DeclInfo * decl_info_of_entity (CheckerInfo *i, Entity * e);
AstFile * ast_file_of_filename (CheckerInfo *i, String filename); AstFile * ast_file_of_filename (CheckerInfo *i, String filename);
// IMPORTANT: Only to use once checking is done // IMPORTANT: Only to use once checking is done
isize type_info_index (CheckerInfo *i, Type * type); isize type_info_index (CheckerInfo *i, Type * type, bool error_on_failure = true);
Entity *current_scope_lookup_entity(Scope *s, String name); Entity *current_scope_lookup_entity(Scope *s, String name);
@@ -879,7 +882,7 @@ void check_remove_expr_info(CheckerInfo *i, AstNode *expr) {
isize type_info_index(CheckerInfo *info, Type *type) { isize type_info_index(CheckerInfo *info, Type *type, bool error_on_failure) {
type = default_type(type); type = default_type(type);
isize entry_index = -1; isize entry_index = -1;
@@ -903,7 +906,7 @@ isize type_info_index(CheckerInfo *info, Type *type) {
} }
} }
if (entry_index < 0) { if (error_on_failure && entry_index < 0) {
compiler_error("TypeInfo for `%s` could not be found", type_to_string(type)); compiler_error("TypeInfo for `%s` could not be found", type_to_string(type));
} }
return entry_index; return entry_index;
@@ -1086,6 +1089,9 @@ void add_type_info_type(Checker *c, Type *t) {
add_type_info_type(c, t_type_info_ptr); add_type_info_type(c, t_type_info_ptr);
add_type_info_type(c, t_rawptr); add_type_info_type(c, t_rawptr);
break; break;
case Basic_Type:
add_type_info_type(c, t_type_info_type);
break;
case Basic_complex64: case Basic_complex64:
add_type_info_type(c, t_type_info_float); add_type_info_type(c, t_type_info_float);
@@ -1248,9 +1254,12 @@ Map<Entity *> generate_minimum_dependency_map(CheckerInfo *info, Entity *start)
for_array(i, info->definitions.entries) { for_array(i, info->definitions.entries) {
Entity *e = info->definitions.entries[i].value; Entity *e = info->definitions.entries[i].value;
if (e->scope->is_global && !is_type_polymorphic(e->type)) { // TODO(bill): is the check enough? // if (e->scope->is_global && !is_type_poly_proc(e->type)) { // TODO(bill): is the check enough?
// NOTE(bill): Require runtime stuff if (e->scope->is_global) { // TODO(bill): is the check enough?
add_dependency_to_map(&map, info, e); if (!is_type_poly_proc(e->type)) {
// NOTE(bill): Require runtime stuff
add_dependency_to_map(&map, info, e);
}
} else if (e->kind == Entity_Procedure) { } else if (e->kind == Entity_Procedure) {
if ((e->Procedure.tags & ProcTag_export) != 0) { if ((e->Procedure.tags & ProcTag_export) != 0) {
add_dependency_to_map(&map, info, e); add_dependency_to_map(&map, info, e);
@@ -1299,7 +1308,7 @@ void init_preload(Checker *c) {
if (record->variant_count != 23) { if (record->variant_count != 24) {
compiler_error("Invalid `TypeInfo` layout"); compiler_error("Invalid `TypeInfo` layout");
} }
t_type_info_named = record->variants[ 1]->type; t_type_info_named = record->variants[ 1]->type;
@@ -1310,20 +1319,21 @@ void init_preload(Checker *c) {
t_type_info_string = record->variants[ 6]->type; t_type_info_string = record->variants[ 6]->type;
t_type_info_boolean = record->variants[ 7]->type; t_type_info_boolean = record->variants[ 7]->type;
t_type_info_any = record->variants[ 8]->type; t_type_info_any = record->variants[ 8]->type;
t_type_info_pointer = record->variants[ 9]->type; t_type_info_type = record->variants[ 9]->type;
t_type_info_atomic = record->variants[10]->type; t_type_info_pointer = record->variants[10]->type;
t_type_info_procedure = record->variants[11]->type; t_type_info_atomic = record->variants[11]->type;
t_type_info_array = record->variants[12]->type; t_type_info_procedure = record->variants[12]->type;
t_type_info_dynamic_array = record->variants[13]->type; t_type_info_array = record->variants[13]->type;
t_type_info_slice = record->variants[14]->type; t_type_info_dynamic_array = record->variants[14]->type;
t_type_info_vector = record->variants[15]->type; t_type_info_slice = record->variants[15]->type;
t_type_info_tuple = record->variants[16]->type; t_type_info_vector = record->variants[16]->type;
t_type_info_struct = record->variants[17]->type; t_type_info_tuple = record->variants[17]->type;
t_type_info_raw_union = record->variants[18]->type; t_type_info_struct = record->variants[18]->type;
t_type_info_union = record->variants[19]->type; t_type_info_raw_union = record->variants[19]->type;
t_type_info_enum = record->variants[20]->type; t_type_info_union = record->variants[20]->type;
t_type_info_map = record->variants[21]->type; t_type_info_enum = record->variants[21]->type;
t_type_info_bit_field = record->variants[22]->type; t_type_info_map = record->variants[22]->type;
t_type_info_bit_field = record->variants[23]->type;
t_type_info_named_ptr = make_type_pointer(c->allocator, t_type_info_named); t_type_info_named_ptr = make_type_pointer(c->allocator, t_type_info_named);
t_type_info_integer_ptr = make_type_pointer(c->allocator, t_type_info_integer); t_type_info_integer_ptr = make_type_pointer(c->allocator, t_type_info_integer);
@@ -1333,6 +1343,7 @@ void init_preload(Checker *c) {
t_type_info_string_ptr = make_type_pointer(c->allocator, t_type_info_string); t_type_info_string_ptr = make_type_pointer(c->allocator, t_type_info_string);
t_type_info_boolean_ptr = make_type_pointer(c->allocator, t_type_info_boolean); t_type_info_boolean_ptr = make_type_pointer(c->allocator, t_type_info_boolean);
t_type_info_any_ptr = make_type_pointer(c->allocator, t_type_info_any); t_type_info_any_ptr = make_type_pointer(c->allocator, t_type_info_any);
t_type_info_type_ptr = make_type_pointer(c->allocator, t_type_info_type);
t_type_info_pointer_ptr = make_type_pointer(c->allocator, t_type_info_pointer); t_type_info_pointer_ptr = make_type_pointer(c->allocator, t_type_info_pointer);
t_type_info_atomic_ptr = make_type_pointer(c->allocator, t_type_info_atomic); t_type_info_atomic_ptr = make_type_pointer(c->allocator, t_type_info_atomic);
t_type_info_procedure_ptr = make_type_pointer(c->allocator, t_type_info_procedure); t_type_info_procedure_ptr = make_type_pointer(c->allocator, t_type_info_procedure);
@@ -2197,6 +2208,9 @@ void check_import_entities(Checker *c, Map<Scope *> *file_scopes) {
void check_parsed_files(Checker *c) { void check_parsed_files(Checker *c) {
Map<Scope *> file_scopes; // Key: String (fullpath) Map<Scope *> file_scopes; // Key: String (fullpath)
map_init(&file_scopes, heap_allocator()); map_init(&file_scopes, heap_allocator());
defer (map_destroy(&file_scopes));
add_type_info_type(c, t_invalid);
// Map full filepaths to Scopes // Map full filepaths to Scopes
for_array(i, c->parser->files) { for_array(i, c->parser->files) {
@@ -2349,7 +2363,4 @@ void check_parsed_files(Checker *c) {
} }
} }
} }
map_destroy(&file_scopes);
} }
+17
View File
@@ -5,6 +5,8 @@
struct AstNode; struct AstNode;
struct HashKey; struct HashKey;
struct Type;
bool are_types_identical(Type *x, Type *y);
struct Complex128 { struct Complex128 {
f64 real, imag; f64 real, imag;
@@ -20,6 +22,7 @@ enum ExactValueKind {
ExactValue_Complex, ExactValue_Complex,
ExactValue_Pointer, ExactValue_Pointer,
ExactValue_Compound, // TODO(bill): Is this good enough? ExactValue_Compound, // TODO(bill): Is this good enough?
ExactValue_Type,
ExactValue_Count, ExactValue_Count,
}; };
@@ -34,6 +37,7 @@ struct ExactValue {
i64 value_pointer; i64 value_pointer;
Complex128 value_complex; Complex128 value_complex;
AstNode * value_compound; AstNode * value_compound;
Type * value_type;
}; };
}; };
@@ -99,6 +103,12 @@ ExactValue exact_value_pointer(i64 ptr) {
return result; return result;
} }
ExactValue exact_value_type(Type *type) {
ExactValue result = {ExactValue_Type};
result.value_type = type;
return result;
}
ExactValue exact_value_integer_from_string(String string) { ExactValue exact_value_integer_from_string(String string) {
return exact_value_u128(u128_from_string(string)); return exact_value_u128(u128_from_string(string));
@@ -639,6 +649,13 @@ bool compare_exact_values(TokenKind op, ExactValue x, ExactValue y) {
case Token_GtEq: return a >= b; case Token_GtEq: return a >= b;
} }
} break; } break;
case ExactValue_Type:
switch (op) {
case Token_CmpEq: return are_types_identical(x.value_type, y.value_type);
case Token_NotEq: return !are_types_identical(x.value_type, y.value_type);
}
break;
} }
GB_PANIC("Invalid comparison"); GB_PANIC("Invalid comparison");
+48 -6
View File
@@ -749,6 +749,7 @@ void ir_build_defer_stmt (irProcedure *proc, irDefer d);
irAddr ir_build_addr (irProcedure *proc, AstNode *expr); irAddr ir_build_addr (irProcedure *proc, AstNode *expr);
void ir_build_proc (irValue *value, irProcedure *parent); void ir_build_proc (irValue *value, irProcedure *parent);
void ir_gen_global_type_name(irModule *m, Entity *e, String name); void ir_gen_global_type_name(irModule *m, Entity *e, String name);
irValue *ir_get_type_info_ptr (irProcedure *proc, Type *type);
@@ -2771,6 +2772,23 @@ String ir_lookup_subtype_polymorphic_field(CheckerInfo *info, Type *dst, Type *s
} }
irValue *ir_emit_ptr_to_int(irProcedure *proc, irValue *value, Type *t, bool allow_type_type = false) {
Type *vt = core_type(ir_type(value));
GB_ASSERT(is_type_pointer(vt));
if (allow_type_type) {
GB_ASSERT(is_type_int_or_uint(core_type(t)) || is_type_type(t));
} else {
GB_ASSERT(is_type_int_or_uint(core_type(t)));
}
return ir_emit(proc, ir_instr_conv(proc, irConv_ptrtoint, value, vt, t));
}
irValue *ir_emit_int_to_ptr(irProcedure *proc, irValue *value, Type *t) {
Type *vt = core_type(ir_type(value));
GB_ASSERT(is_type_int_or_uint(vt));
GB_ASSERT(is_type_pointer(core_type(t)));
return ir_emit(proc, ir_instr_conv(proc, irConv_inttoptr, value, vt, t));
}
irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) { irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) {
Type *src_type = ir_type(value); Type *src_type = ir_type(value);
@@ -2925,10 +2943,10 @@ irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) {
// Pointer <-> int // Pointer <-> int
if (is_type_pointer(src) && is_type_int_or_uint(dst)) { if (is_type_pointer(src) && is_type_int_or_uint(dst)) {
return ir_emit(proc, ir_instr_conv(proc, irConv_ptrtoint, value, src_type, t)); return ir_emit_ptr_to_int(proc, value, t);
} }
if (is_type_int_or_uint(src) && is_type_pointer(dst)) { if (is_type_int_or_uint(src) && is_type_pointer(dst)) {
return ir_emit(proc, ir_instr_conv(proc, irConv_inttoptr, value, src_type, t)); return ir_emit_int_to_ptr(proc, value, t);
} }
if (is_type_union(dst)) { if (is_type_union(dst)) {
@@ -4388,7 +4406,14 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
if (tv.mode == Addressing_Type) { if (tv.mode == Addressing_Type) {
// TODO(bill): Handle this correctly // TODO(bill): Handle this correctly
return ir_value_nil(proc->module->allocator, tv.type); i32 entry_index = type_info_index(proc->module->info, tv.type, false);
if (entry_index >= 0) {
irValue *ptr = ir_get_type_info_ptr(proc, tv.type);
return ir_emit_ptr_to_int(proc, ptr, t_type, true);
// i32 id = entry_index+1;
// return ir_value_constant(proc->module->allocator, t_int, exact_value_i64(id));
}
return v_raw_nil;
} }
if (tv.value.kind != ExactValue_Invalid) { if (tv.value.kind != ExactValue_Invalid) {
@@ -4766,7 +4791,10 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
GB_ASSERT(!vari_expand); GB_ASSERT(!vari_expand);
isize i = 0; isize i = 0;
for (; i < type->param_count-1; i++) { for (; i < type->param_count-1; i++) {
args[i] = ir_emit_conv(proc, args[i], pt->variables[i]->type); Entity *e = pt->variables[i];
if (e->kind == Entity_Variable) {
args[i] = ir_emit_conv(proc, args[i], e->type);
}
} }
Type *variadic_type = pt->variables[i]->type; Type *variadic_type = pt->variables[i]->type;
GB_ASSERT(is_type_slice(variadic_type)); GB_ASSERT(is_type_slice(variadic_type));
@@ -4783,7 +4811,10 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
} else if (variadic) { } else if (variadic) {
isize i = 0; isize i = 0;
for (; i < type->param_count-1; i++) { for (; i < type->param_count-1; i++) {
args[i] = ir_emit_conv(proc, args[i], pt->variables[i]->type); Entity *e = pt->variables[i];
if (e->kind == Entity_Variable) {
args[i] = ir_emit_conv(proc, args[i], e->type);
}
} }
if (!vari_expand) { if (!vari_expand) {
Type *variadic_type = pt->variables[i]->type; Type *variadic_type = pt->variables[i]->type;
@@ -4795,7 +4826,10 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
} }
} else { } else {
for (isize i = 0; i < type->param_count; i++) { for (isize i = 0; i < type->param_count; i++) {
args[i] = ir_emit_conv(proc, args[i], pt->variables[i]->type); Entity *e = pt->variables[i];
if (e->kind == Entity_Variable) {
args[i] = ir_emit_conv(proc, args[i], e->type);
}
} }
} }
@@ -7698,6 +7732,10 @@ void ir_gen_tree(irGen *s) {
auto *entry = &info->type_info_map.entries[type_info_map_index]; auto *entry = &info->type_info_map.entries[type_info_map_index];
Type *t = cast(Type *)entry->key.ptr; Type *t = cast(Type *)entry->key.ptr;
t = default_type(t); t = default_type(t);
if (t == t_invalid) {
continue;
}
isize entry_index = type_info_index(info, t); isize entry_index = type_info_index(info, t);
irValue *tag = NULL; irValue *tag = NULL;
@@ -7771,6 +7809,10 @@ void ir_gen_tree(irGen *s) {
case Basic_any: case Basic_any:
tag = ir_emit_conv(proc, ti_ptr, t_type_info_any_ptr); tag = ir_emit_conv(proc, ti_ptr, t_type_info_any_ptr);
break; break;
case Basic_Type:
tag = ir_emit_conv(proc, ti_ptr, t_type_info_type_ptr);
break;
} }
break; break;
+6
View File
@@ -246,6 +246,7 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) {
case Basic_uint: ir_fprintf(f, "i%lld", word_bits); return; case Basic_uint: ir_fprintf(f, "i%lld", word_bits); return;
case Basic_int: ir_fprintf(f, "i%lld", word_bits); return; case Basic_int: ir_fprintf(f, "i%lld", word_bits); return;
case Basic_any: ir_fprintf(f, "%%..any"); return; case Basic_any: ir_fprintf(f, "%%..any"); return;
case Basic_Type: ir_fprintf(f, "%%..Type"); return;
} }
break; break;
case Type_Pointer: case Type_Pointer:
@@ -1691,6 +1692,11 @@ void print_llvm_ir(irGen *ir) {
ir_print_type(f, m, t_type_info_ptr); ir_print_type(f, m, t_type_info_ptr);
ir_fprintf(f, "} ; Basic_any\n"); ir_fprintf(f, "} ; Basic_any\n");
ir_print_encoded_local(f, str_lit("..Type"));
ir_fprintf(f, " = type ");
ir_print_type(f, m, t_int);
ir_fprintf(f, " ; Basic_Type\n");
ir_fprintf(f, "declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone \n"); ir_fprintf(f, "declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone \n");
ir_fprintf(f, "\n"); ir_fprintf(f, "\n");
+1 -1
View File
@@ -138,7 +138,7 @@ Array<AstNode *> make_ast_node_array(AstFile *f, isize init_capacity = 8) {
// all the nodes and even memcpy in a different kind of node // all the nodes and even memcpy in a different kind of node
#define AST_NODE_KINDS \ #define AST_NODE_KINDS \
AST_NODE_KIND(Ident, "identifier", struct { \ AST_NODE_KIND(Ident, "identifier", struct { \
Token token; \ Token token; \
}) \ }) \
AST_NODE_KIND(Implicit, "implicit", Token) \ AST_NODE_KIND(Implicit, "implicit", Token) \
AST_NODE_KIND(Undef, "undef", Token) \ AST_NODE_KIND(Undef, "undef", Token) \
+14
View File
@@ -30,6 +30,7 @@ enum BasicKind {
Basic_rawptr, Basic_rawptr,
Basic_string, // ^u8 + int Basic_string, // ^u8 + int
Basic_any, // ^Type_Info + rawptr Basic_any, // ^Type_Info + rawptr
Basic_Type, // `int` id of the type
Basic_UntypedBool, Basic_UntypedBool,
Basic_UntypedInteger, Basic_UntypedInteger,
@@ -261,6 +262,7 @@ gb_global Type basic_types[] = {
{Type_Basic, {Basic_rawptr, BasicFlag_Pointer, -1, STR_LIT("rawptr")}}, {Type_Basic, {Basic_rawptr, BasicFlag_Pointer, -1, STR_LIT("rawptr")}},
{Type_Basic, {Basic_string, BasicFlag_String, -1, STR_LIT("string")}}, {Type_Basic, {Basic_string, BasicFlag_String, -1, STR_LIT("string")}},
{Type_Basic, {Basic_any, 0, -1, STR_LIT("any")}}, {Type_Basic, {Basic_any, 0, -1, STR_LIT("any")}},
{Type_Basic, {Basic_Type, 0, -1, STR_LIT("Type")}},
{Type_Basic, {Basic_UntypedBool, BasicFlag_Boolean | BasicFlag_Untyped, 0, STR_LIT("untyped bool")}}, {Type_Basic, {Basic_UntypedBool, BasicFlag_Boolean | BasicFlag_Untyped, 0, STR_LIT("untyped bool")}},
{Type_Basic, {Basic_UntypedInteger, BasicFlag_Integer | BasicFlag_Untyped, 0, STR_LIT("untyped integer")}}, {Type_Basic, {Basic_UntypedInteger, BasicFlag_Integer | BasicFlag_Untyped, 0, STR_LIT("untyped integer")}},
@@ -306,6 +308,7 @@ gb_global Type *t_uint = &basic_types[Basic_uint];
gb_global Type *t_rawptr = &basic_types[Basic_rawptr]; gb_global Type *t_rawptr = &basic_types[Basic_rawptr];
gb_global Type *t_string = &basic_types[Basic_string]; gb_global Type *t_string = &basic_types[Basic_string];
gb_global Type *t_any = &basic_types[Basic_any]; gb_global Type *t_any = &basic_types[Basic_any];
gb_global Type *t_type = &basic_types[Basic_Type];
gb_global Type *t_untyped_bool = &basic_types[Basic_UntypedBool]; gb_global Type *t_untyped_bool = &basic_types[Basic_UntypedBool];
gb_global Type *t_untyped_integer = &basic_types[Basic_UntypedInteger]; gb_global Type *t_untyped_integer = &basic_types[Basic_UntypedInteger];
@@ -340,6 +343,7 @@ gb_global Type *t_type_info_rune = NULL;
gb_global Type *t_type_info_float = NULL; gb_global Type *t_type_info_float = NULL;
gb_global Type *t_type_info_complex = NULL; gb_global Type *t_type_info_complex = NULL;
gb_global Type *t_type_info_any = NULL; gb_global Type *t_type_info_any = NULL;
gb_global Type *t_type_info_type = NULL;
gb_global Type *t_type_info_string = NULL; gb_global Type *t_type_info_string = NULL;
gb_global Type *t_type_info_boolean = NULL; gb_global Type *t_type_info_boolean = NULL;
gb_global Type *t_type_info_pointer = NULL; gb_global Type *t_type_info_pointer = NULL;
@@ -364,6 +368,7 @@ gb_global Type *t_type_info_float_ptr = NULL;
gb_global Type *t_type_info_complex_ptr = NULL; gb_global Type *t_type_info_complex_ptr = NULL;
gb_global Type *t_type_info_quaternion_ptr = NULL; gb_global Type *t_type_info_quaternion_ptr = NULL;
gb_global Type *t_type_info_any_ptr = NULL; gb_global Type *t_type_info_any_ptr = NULL;
gb_global Type *t_type_info_type_ptr = NULL;
gb_global Type *t_type_info_string_ptr = NULL; gb_global Type *t_type_info_string_ptr = NULL;
gb_global Type *t_type_info_boolean_ptr = NULL; gb_global Type *t_type_info_boolean_ptr = NULL;
gb_global Type *t_type_info_pointer_ptr = NULL; gb_global Type *t_type_info_pointer_ptr = NULL;
@@ -775,6 +780,12 @@ bool is_type_tuple(Type *t) {
return t->kind == Type_Tuple; return t->kind == Type_Tuple;
} }
bool is_type_type(Type *t) {
t = base_type(t);
return t->kind == Type_Basic && t->Basic.kind == Basic_Type;
}
bool is_type_int_or_uint(Type *t) { bool is_type_int_or_uint(Type *t) {
if (t->kind == Type_Basic) { if (t->kind == Type_Basic) {
@@ -1054,6 +1065,7 @@ bool is_type_comparable(Type *t) {
case Basic_any: case Basic_any:
return false; return false;
case Basic_rune: case Basic_rune:
case Basic_Type:
return true; return true;
} }
return true; return true;
@@ -1747,6 +1759,7 @@ i64 type_align_of_internal(gbAllocator allocator, Type *t, TypePath *path) {
switch (t->Basic.kind) { switch (t->Basic.kind) {
case Basic_string: return build_context.word_size; case Basic_string: return build_context.word_size;
case Basic_any: return build_context.word_size; case Basic_any: return build_context.word_size;
case Basic_Type: return build_context.word_size;
case Basic_int: case Basic_uint: case Basic_rawptr: case Basic_int: case Basic_uint: case Basic_rawptr:
return build_context.word_size; return build_context.word_size;
@@ -1972,6 +1985,7 @@ i64 type_size_of_internal(gbAllocator allocator, Type *t, TypePath *path) {
switch (kind) { switch (kind) {
case Basic_string: return 2*build_context.word_size; case Basic_string: return 2*build_context.word_size;
case Basic_any: return 2*build_context.word_size; case Basic_any: return 2*build_context.word_size;
case Basic_Type: return 1*build_context.word_size;
case Basic_int: case Basic_uint: case Basic_rawptr: case Basic_int: case Basic_uint: case Basic_rawptr:
return build_context.word_size; return build_context.word_size;