Browse Source

Merge size_of and size_of_val et al.

Ginger Bill 8 years ago
parent
commit
d3c24d159f
3 changed files with 32 additions and 117 deletions
  1. 31 102
      src/check_expr.cpp
  2. 1 11
      src/checker.cpp
  3. 0 4
      src/ir.cpp

+ 31 - 102
src/check_expr.cpp

@@ -3945,54 +3945,43 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
 
 
 	case BuiltinProc_size_of: {
-		// proc size_of(Type) -> untyped int
-		Type *type = check_type(c, ce->args[0]);
-		if (type == NULL || type == t_invalid) {
-			error_node(ce->args[0], "Expected a type for `size_of`");
+		// proc size_of(Type or expr) -> untyped int
+		Operand o = {};
+		check_expr_or_type(c, &o, ce->args[0]);
+		if (o.mode == Addressing_Invalid) {
 			return false;
 		}
-
-		operand->mode = Addressing_Constant;
-		operand->value = exact_value_i64(type_size_of(c->allocator, type));
-		operand->type = t_untyped_integer;
-
-	} break;
-
-	case BuiltinProc_size_of_val:
-		// proc size_of_val(val: Type) -> untyped int
-		check_assignment(c, operand, NULL, str_lit("argument of `size_of_val`"));
-		if (operand->mode == Addressing_Invalid) {
+		Type *t = o.type;
+		if (t == NULL || t == t_invalid) {
+			error_node(ce->args[0], "Invalid argument for `size_of`");
 			return false;
 		}
+		t = default_type(t);
 
 		operand->mode = Addressing_Constant;
-		operand->value = exact_value_i64(type_size_of(c->allocator, operand->type));
+		operand->value = exact_value_i64(type_size_of(c->allocator, t));
 		operand->type = t_untyped_integer;
-		break;
+	} break;
 
 	case BuiltinProc_align_of: {
-		// proc align_of(Type) -> untyped int
-		Type *type = check_type(c, ce->args[0]);
-		if (type == NULL || type == t_invalid) {
-			error_node(ce->args[0], "Expected a type for `align_of`");
+		// proc align_of(Type or expr) -> untyped int
+		Operand o = {};
+		check_expr_or_type(c, &o, ce->args[0]);
+		if (o.mode == Addressing_Invalid) {
 			return false;
 		}
-		operand->mode = Addressing_Constant;
-		operand->value = exact_value_i64(type_align_of(c->allocator, type));
-		operand->type = t_untyped_integer;
-	} break;
-
-	case BuiltinProc_align_of_val:
-		// proc align_of_val(val: Type) -> untyped int
-		check_assignment(c, operand, NULL, str_lit("argument of `align_of_val`"));
-		if (operand->mode == Addressing_Invalid) {
+		Type *t = o.type;
+		if (t == NULL || t == t_invalid) {
+			error_node(ce->args[0], "Invalid argument for `align_of`");
 			return false;
 		}
+		t = default_type(t);
 
 		operand->mode = Addressing_Constant;
-		operand->value = exact_value_i64(type_align_of(c->allocator, operand->type));
+		operand->value = exact_value_i64(type_align_of(c->allocator, t));
 		operand->type = t_untyped_integer;
-		break;
+	} break;
+
 
 	case BuiltinProc_offset_of: {
 		// proc offset_of(Type, field) -> untyped int
@@ -4038,56 +4027,8 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
 		operand->type  = t_untyped_integer;
 	} break;
 
-	case BuiltinProc_offset_of_val: {
-		// proc offset_of_val(val: expression) -> untyped int
-		AstNode *arg = unparen_expr(ce->args[0]);
-		if (arg->kind != AstNode_SelectorExpr) {
-			gbString str = expr_to_string(arg);
-			error_node(arg, "`%s` is not a selector expression", str);
-			return false;
-		}
-		ast_node(s, SelectorExpr, arg);
-
-		check_expr(c, operand, s->expr);
-		if (operand->mode == Addressing_Invalid) {
-			return false;
-		}
 
-		Type *type = operand->type;
-		if (base_type(type)->kind == Type_Pointer) {
-			Type *p = base_type(type);
-			if (is_type_struct(p)) {
-				type = p->Pointer.elem;
-			}
-		}
-		if (is_type_array(type) || is_type_vector(type)) {
-			error_node(arg, "Invalid type for `offset_of_val`");
-			return false;
-		}
-
-		ast_node(i, Ident, s->selector);
-		Selection sel = lookup_field(c->allocator, type, i->string, operand->mode == Addressing_Type);
-		if (sel.entity == NULL) {
-			gbString type_str = type_to_string(type);
-			error_node(arg,
-			      "`%s` has no field named `%.*s`", type_str, LIT(i->string));
-			return false;
-		}
-		if (sel.indirect) {
-			gbString type_str = type_to_string(type);
-			error_node(ce->args[0],
-			      "Field `%.*s` is embedded via a pointer in `%s`", LIT(i->string), type_str);
-			gb_string_free(type_str);
-			return false;
-		}
-
-		operand->mode = Addressing_Constant;
-		// IMPORTANT TODO(bill): Fix for anonymous fields
-		operand->value = exact_value_i64(type_offset_of_from_selection(c->allocator, type, sel));
-		operand->type  = t_untyped_integer;
-	} break;
-
-	case BuiltinProc_type_of_val:
+	case BuiltinProc_type_of:
 		// proc type_of_val(val: Type) -> type(Type)
 		check_assignment(c, operand, NULL, str_lit("argument of `type_of_val`"));
 		if (operand->mode == Addressing_Invalid || operand->mode == Addressing_Builtin) {
@@ -4110,31 +4051,19 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
 		// NOTE(bill): The type information may not be setup yet
 		init_preload(c);
 		AstNode *expr = ce->args[0];
-		Type *type = check_type(c, expr);
-		if (type == NULL || type == t_invalid) {
-			error_node(expr, "Invalid argument to `type_info`");
+		Operand o = {};
+		check_expr_or_type(c, &o, ce->args[0]);
+		if (o.mode == Addressing_Invalid) {
 			return false;
 		}
-
-		add_type_info_type(c, type);
-
-		operand->mode = Addressing_Value;
-		operand->type = t_type_info_ptr;
-	} break;
-
-	case BuiltinProc_type_info_of_val: {
-		// proc type_info_of_val(val: Type) -> ^Type_Info
-		if (c->context.scope->is_global) {
-			compiler_error("`type_info` Cannot be declared within a #shared_global_scope due to how the internals of the compiler works");
+		Type *t = o.type;
+		if (t == NULL || t == t_invalid) {
+			error_node(ce->args[0], "Invalid argument for `size_of`");
+			return false;
 		}
+		t = default_type(t);
 
-		// NOTE(bill): The type information may not be setup yet
-		init_preload(c);
-		AstNode *expr = ce->args[0];
-		check_assignment(c, operand, NULL, str_lit("argument of `type_info_of_val`"));
-		if (operand->mode == Addressing_Invalid || operand->mode == Addressing_Builtin)
-			return false;
-		add_type_info_type(c, operand->type);
+		add_type_info_type(c, t);
 
 		operand->mode = Addressing_Value;
 		operand->type = t_type_info_ptr;

+ 1 - 11
src/checker.cpp

@@ -37,15 +37,10 @@ enum BuiltinProcId {
 	BuiltinProc_delete,
 
 	BuiltinProc_size_of,
-	BuiltinProc_size_of_val,
 	BuiltinProc_align_of,
-	BuiltinProc_align_of_val,
 	BuiltinProc_offset_of,
-	BuiltinProc_offset_of_val,
-	BuiltinProc_type_of_val,
-
+	BuiltinProc_type_of,
 	BuiltinProc_type_info,
-	BuiltinProc_type_info_of_val,
 
 	BuiltinProc_compile_assert,
 	BuiltinProc_assert,
@@ -88,15 +83,10 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_Count] = {
 	{STR_LIT("delete"),           2, false, Expr_Stmt},
 
 	{STR_LIT("size_of"),          1, false, Expr_Expr},
-	{STR_LIT("size_of_val"),      1, false, Expr_Expr},
 	{STR_LIT("align_of"),         1, false, Expr_Expr},
-	{STR_LIT("align_of_val"),     1, false, Expr_Expr},
 	{STR_LIT("offset_of"),        2, false, Expr_Expr},
-	{STR_LIT("offset_of_val"),    1, false, Expr_Expr},
 	{STR_LIT("type_of_val"),      1, false, Expr_Expr},
-
 	{STR_LIT("type_info"),        1, false, Expr_Expr},
-	{STR_LIT("type_info_of_val"), 1, false, Expr_Expr},
 
 	{STR_LIT("compile_assert"),   1, false, Expr_Expr},
 	{STR_LIT("assert"),           1, false, Expr_Expr},

+ 0 - 4
src/ir.cpp

@@ -3622,10 +3622,6 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
 		Type *t = default_type(type_of_expr(proc->module->info, ce->args[0]));
 		return ir_type_info(proc, t);
 	} break;
-	case BuiltinProc_type_info_of_val: {
-		Type *t = default_type(type_of_expr(proc->module->info, ce->args[0]));
-		return ir_type_info(proc, t);
-	} break;
 
 	case BuiltinProc_transmute: {
 		irValue *x = ir_build_expr(proc, ce->args[1]);