From 240da5c8e047acf14802fe1fc2a9d93fc374ca72 Mon Sep 17 00:00:00 2001 From: Ginger Bill Date: Tue, 4 Jul 2017 16:06:08 +0100 Subject: [PATCH] Allow aliasing of aliases --- code/demo.odin | 6 +----- src/check_decl.cpp | 10 +++++++-- src/check_expr.cpp | 11 ++++++++++ src/ir.cpp | 51 +++++++++++++++++++++++++++++----------------- 4 files changed, 52 insertions(+), 26 deletions(-) diff --git a/code/demo.odin b/code/demo.odin index 91f3e132e..3d263b8e8 100644 --- a/code/demo.odin +++ b/code/demo.odin @@ -250,10 +250,6 @@ explicit_parametric_polymorphic_procedures :: proc() { a, b = b, a; // Or use this syntax for this silly example case - - - - // A more complicated example using subtyping // Something like this could be used in a game Vector2 :: struct {x, y: f32}; @@ -375,7 +371,6 @@ main :: proc() { f(y = 3785.1546, x = 123); f(x = int, y = 897.513); f(x = f32); -/* general_stuff(); foreign_blocks(); default_arguments(); @@ -387,6 +382,7 @@ main :: proc() { // Command line argument(s)! // -opt=0,1,2,3 +/* program := "+ + * - /"; accumulator := 0; diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 76558e948..a1d96f548 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -212,6 +212,7 @@ void check_const_decl(Checker *c, Entity *e, AstNode *type_expr, AstNode *init, return; } break; + // NOTE(bill): Check to see if the expression it to be aliases case Addressing_Builtin: if (e->type != NULL) { error(type_expr, "A constant alias of a built-in procedure may not have a type initializer"); @@ -230,6 +231,11 @@ void check_const_decl(Checker *c, Entity *e, AstNode *type_expr, AstNode *init, if (entity != NULL) { switch (entity->kind) { + case Entity_Alias: + e->kind = Entity_Alias; + e->type = entity->type; + e->Alias.base = entity->Alias.base; + return; case Entity_Procedure: e->kind = Entity_Alias; e->type = entity->type; @@ -390,10 +396,10 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) { } #endif - bool prev_allow_polymorphic_types = c->context.allow_polymorphic_types; + auto prev_context = c->context; c->context.allow_polymorphic_types = true; check_procedure_type(c, proc_type, pl->type); - c->context.allow_polymorphic_types = prev_allow_polymorphic_types; + c->context = prev_context; bool is_foreign = (pl->tags & ProcTag_foreign) != 0; bool is_link_name = (pl->tags & ProcTag_link_name) != 0; diff --git a/src/check_expr.cpp b/src/check_expr.cpp index b2dd98fa9..9e34e2412 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -331,6 +331,17 @@ void check_assignment(Checker *c, Operand *operand, Type *type, String context_n if (operand->mode == Addressing_Invalid) { return; } + #if 0 + if (operand->mode == Addressing_Type) { + Type *t = base_type(type); + if (t->kind == Type_Pointer && + t->Pointer.elem == t_type_info) { + add_type_info_type(c, type); + return; + } + } + #endif + if (is_type_untyped(operand->type)) { Type *target_type = type; if (type == NULL || is_type_any(type)) { diff --git a/src/ir.cpp b/src/ir.cpp index ed1988a5b..8c9f950a9 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -4374,19 +4374,23 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) { TypeAndValue tv = type_and_value_of_expr(proc->module->info, expr); GB_ASSERT(tv.mode != Addressing_Invalid); + GB_ASSERT(tv.mode != Addressing_Type); + #if 0 if (tv.mode == Addressing_Type) { // // TODO(bill): Handle this correctly - // 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)); - // } + #if 0 + i32 entry_index = type_info_index(proc->module->info, tv.type, false); + if (entry_index >= 0) { + return ir_get_type_info_ptr(proc, tv.type); + // i32 id = entry_index+1; + // return ir_value_constant(proc->module->allocator, t_int, exact_value_i64(id)); + } + #endif // return v_raw_nil; return ir_value_nil(proc->module->allocator, tv.type); } + #endif if (tv.value.kind != ExactValue_Invalid) { // NOTE(bill): Edge case @@ -4672,9 +4676,12 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) { String name = fv->field->Ident.token.string; isize index = lookup_procedure_parameter(type, name); GB_ASSERT(index >= 0); - irValue *expr = ir_build_expr(proc, fv->value); - args[index] = expr; - + TypeAndValue tav = type_and_value_of_expr(proc->module->info, fv->value); + if (tav.mode == Addressing_Type) { + args[index] = ir_value_nil(proc->module->allocator, tav.type); + } else { + args[index] = ir_build_expr(proc, fv->value); + } } TypeTuple *pt = &type->params->Tuple; for (isize i = 0; i < param_count; i++) { @@ -4718,16 +4725,22 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) { bool is_c_vararg = type->c_vararg; for_array(i, ce->args) { - irValue *a = ir_build_expr(proc, ce->args[i]); - Type *at = ir_type(a); - if (at->kind == Type_Tuple) { - for (isize i = 0; i < at->Tuple.variable_count; i++) { - Entity *e = at->Tuple.variables[i]; - irValue *v = ir_emit_struct_ev(proc, a, i); - args[arg_index++] = v; - } + AstNode *arg = ce->args[i]; + TypeAndValue arg_tv = type_and_value_of_expr(proc->module->info, arg); + if (arg_tv.mode == Addressing_Type) { + args[arg_index++] = ir_value_nil(proc->module->allocator, arg_tv.type); } else { - args[arg_index++] = a; + irValue *a = ir_build_expr(proc, arg); + Type *at = ir_type(a); + if (at->kind == Type_Tuple) { + for (isize i = 0; i < at->Tuple.variable_count; i++) { + Entity *e = at->Tuple.variables[i]; + irValue *v = ir_emit_struct_ev(proc, a, i); + args[arg_index++] = v; + } + } else { + args[arg_index++] = a; + } } }