Browse Source

Allow aliasing of aliases

Ginger Bill 8 years ago
parent
commit
240da5c8e0
4 changed files with 52 additions and 26 deletions
  1. 1 5
      code/demo.odin
  2. 8 2
      src/check_decl.cpp
  3. 11 0
      src/check_expr.cpp
  4. 32 19
      src/ir.cpp

+ 1 - 5
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;
 

+ 8 - 2
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;

+ 11 - 0
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)) {

+ 32 - 19
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;
+				}
 			}
 		}