From e4a82833275acc166313ff11613bcc748309571a Mon Sep 17 00:00:00 2001 From: Ginger Bill Date: Thu, 29 Jun 2017 15:48:07 +0100 Subject: [PATCH] Remove `Type` What was I thinking?! --- code/demo.odin | 13 ------------- core/_preload.odin | 1 - src/check_expr.cpp | 44 ++++++++++++++++---------------------------- src/check_stmt.cpp | 7 ++----- src/checker.cpp | 38 +++++++++++++++----------------------- src/ir.cpp | 26 +++++++++++--------------- src/ir_print.cpp | 6 ------ src/parser.cpp | 39 +++++++++++++++++++++++++++++++++++++-- src/types.cpp | 14 -------------- 9 files changed, 81 insertions(+), 107 deletions(-) diff --git a/code/demo.odin b/code/demo.odin index 9e5b43739..919b5a0a4 100644 --- a/code/demo.odin +++ b/code/demo.odin @@ -379,19 +379,6 @@ main :: proc() { // Command line argument(s)! // -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 := "+ + * - /"; accumulator := 0; diff --git a/core/_preload.odin b/core/_preload.odin index 9c08f7153..77475de87 100644 --- a/core/_preload.odin +++ b/core/_preload.odin @@ -61,7 +61,6 @@ TypeInfo :: union { String{}, Boolean{}, Any{}, - Type{}, Pointer{ elem: ^TypeInfo, // nil -> rawptr }, diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 396a62eef..32d23431a 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -327,15 +327,6 @@ void check_assignment(Checker *c, Operand *operand, Type *type, String context_n if (operand->mode == Addressing_Invalid) { 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)) { Type *target_type = type; if (type == NULL || is_type_any(type)) { @@ -1179,6 +1170,11 @@ Type *check_get_params(Checker *c, Scope *scope, AstNode *_params, bool *is_vari } } else { type = check_type(c, type_expr); + if (p->flags&FieldFlag_dollar) { + error(type_expr, "`$` is only allowed for polymorphic type parameters at the moment"); + type = NULL; + } + } if (default_value != NULL) { @@ -1630,12 +1626,13 @@ bool check_procedure_type(Checker *c, Type *type, AstNode *proc_type_node, Array bool is_polymorphic = false; for (isize i = 0; i < param_count; i++) { Entity *e = params->Tuple.variables[i]; - if (e->type->kind == Type_Generic) { + if (e->kind != Entity_Variable) { is_polymorphic = true; + break; } } if (operands == NULL) { - GB_ASSERT(type->Proc.is_polymorphic == is_polymorphic); + // GB_ASSERT(type->Proc.is_polymorphic == is_polymorphic); } @@ -2625,18 +2622,15 @@ void check_comparison(Checker *c, Operand *x, Operand *y, TokenKind op) { x->value = exact_value_bool(comp); 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; + + defer (if (err_str != NULL) { + gb_string_free(err_str); + }); gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena); + defer (gb_temp_arena_memory_end(tmp)); + if (check_is_assignable_to(c, x, y->type) || check_is_assignable_to(c, y, x->type)) { Type *err_type = x->type; @@ -2698,10 +2692,6 @@ void check_comparison(Checker *c, Operand *x, Operand *y, TokenKind op) { } } - if (err_str != NULL) { - gb_string_free(err_str); - } - gb_temp_arena_memory_end(tmp); } void check_shift(Checker *c, Operand *x, Operand *y, AstNode *node) { @@ -3064,13 +3054,11 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) { check_expr_or_type(c, y, be->right); bool xt = x->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 (xt ^ yt) { GB_ASSERT(xt != yt); - if (xt && !yvt) error_operand_not_expression(x); - if (yt && !xvt) error_operand_not_expression(y); + if (xt) error_operand_not_expression(x); + if (yt) error_operand_not_expression(y); } } break; diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 8cbbf4c25..33cfd3dfa 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -1297,11 +1297,8 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { check_comparison(c, &a1, &b1, op); } else { Operand y = {}; - if (is_operand_a_type_value(x)) { - check_expr_or_type(c, &y, expr); - } else { - check_expr(c, &y, expr); - } + check_expr(c, &y, expr); + if (x.mode == Addressing_Invalid || y.mode == Addressing_Invalid) { continue; diff --git a/src/checker.cpp b/src/checker.cpp index c12aad9de..4ad2295f3 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -170,9 +170,6 @@ bool is_operand_value(Operand o) { bool is_operand_nil(Operand o) { 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 { @@ -1089,9 +1086,6 @@ void add_type_info_type(Checker *c, Type *t) { add_type_info_type(c, t_type_info_ptr); add_type_info_type(c, t_rawptr); break; - case Basic_Type: - add_type_info_type(c, t_type_info_type); - break; case Basic_complex64: add_type_info_type(c, t_type_info_float); @@ -1308,7 +1302,7 @@ void init_preload(Checker *c) { - if (record->variant_count != 24) { + if (record->variant_count != 23) { compiler_error("Invalid `TypeInfo` layout"); } t_type_info_named = record->variants[ 1]->type; @@ -1319,21 +1313,20 @@ void init_preload(Checker *c) { t_type_info_string = record->variants[ 6]->type; t_type_info_boolean = record->variants[ 7]->type; t_type_info_any = record->variants[ 8]->type; - t_type_info_type = record->variants[ 9]->type; - t_type_info_pointer = record->variants[10]->type; - t_type_info_atomic = record->variants[11]->type; - t_type_info_procedure = record->variants[12]->type; - t_type_info_array = record->variants[13]->type; - t_type_info_dynamic_array = record->variants[14]->type; - t_type_info_slice = record->variants[15]->type; - t_type_info_vector = record->variants[16]->type; - t_type_info_tuple = record->variants[17]->type; - t_type_info_struct = record->variants[18]->type; - t_type_info_raw_union = record->variants[19]->type; - t_type_info_union = record->variants[20]->type; - t_type_info_enum = record->variants[21]->type; - t_type_info_map = record->variants[22]->type; - t_type_info_bit_field = record->variants[23]->type; + t_type_info_pointer = record->variants[ 9]->type; + t_type_info_atomic = record->variants[10]->type; + t_type_info_procedure = record->variants[11]->type; + t_type_info_array = record->variants[12]->type; + t_type_info_dynamic_array = record->variants[13]->type; + t_type_info_slice = record->variants[14]->type; + t_type_info_vector = record->variants[15]->type; + t_type_info_tuple = record->variants[16]->type; + t_type_info_struct = record->variants[17]->type; + t_type_info_raw_union = record->variants[18]->type; + t_type_info_union = record->variants[19]->type; + t_type_info_enum = record->variants[20]->type; + t_type_info_map = record->variants[21]->type; + t_type_info_bit_field = record->variants[22]->type; 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); @@ -1343,7 +1336,6 @@ void init_preload(Checker *c) { 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_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_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); diff --git a/src/ir.cpp b/src/ir.cpp index 64dc71684..a913d2d91 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -2776,7 +2776,7 @@ irValue *ir_emit_ptr_to_int(irProcedure *proc, irValue *value, Type *t, bool all 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)); + GB_ASSERT(is_type_int_or_uint(core_type(t))); } else { GB_ASSERT(is_type_int_or_uint(core_type(t))); } @@ -2789,7 +2789,6 @@ irValue *ir_emit_int_to_ptr(irProcedure *proc, irValue *value, 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) { Type *src_type = ir_type(value); if (are_types_identical(t, src_type)) { @@ -4405,15 +4404,16 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) { GB_ASSERT(tv.mode != Addressing_Invalid); 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)); - } - return v_raw_nil; + // // 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)); + // } + // return v_raw_nil; + return ir_value_nil(proc->module->allocator, tv.type); } if (tv.value.kind != ExactValue_Invalid) { @@ -7809,10 +7809,6 @@ void ir_gen_tree(irGen *s) { case Basic_any: tag = ir_emit_conv(proc, ti_ptr, t_type_info_any_ptr); break; - - case Basic_Type: - tag = ir_emit_conv(proc, ti_ptr, t_type_info_type_ptr); - break; } break; diff --git a/src/ir_print.cpp b/src/ir_print.cpp index c5456edf4..b9bccc91c 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -246,7 +246,6 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) { case Basic_uint: 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_Type: ir_fprintf(f, "%%..Type"); return; } break; case Type_Pointer: @@ -1692,11 +1691,6 @@ void print_llvm_ir(irGen *ir) { ir_print_type(f, m, t_type_info_ptr); 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, "\n"); diff --git a/src/parser.cpp b/src/parser.cpp index c4b9aa0e7..7368b81e8 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -114,8 +114,9 @@ enum FieldFlag { FieldFlag_using = 1<<1, FieldFlag_no_alias = 1<<2, FieldFlag_c_vararg = 1<<3, + FieldFlag_dollar = 1<<4, - FieldFlag_Signature = FieldFlag_ellipsis|FieldFlag_using|FieldFlag_no_alias|FieldFlag_c_vararg, + FieldFlag_Signature = FieldFlag_ellipsis|FieldFlag_using|FieldFlag_no_alias|FieldFlag_c_vararg|FieldFlag_dollar, }; enum StmtAllowFlag { @@ -377,6 +378,10 @@ AST_NODE_KIND(_TypeBegin, "", i32) \ AST_NODE_KIND(HelperType, "type", struct { \ Token token; \ }) \ + AST_NODE_KIND(PolyType, "polymorphic type", struct { \ + Token token; \ + AstNode *type; \ + }) \ AST_NODE_KIND(ProcType, "procedure type", struct { \ Token token; \ AstNode *params; \ @@ -581,6 +586,7 @@ Token ast_node_token(AstNode *node) { return ast_node_token(node->UnionField.name); case AstNode_HelperType: return node->HelperType.token; + case AstNode_PolyType: return node->PolyType.token; case AstNode_ProcType: return node->ProcType.token; case AstNode_PointerType: return node->PointerType.token; case AstNode_AtomicType: return node->AtomicType.token; @@ -1359,6 +1365,13 @@ AstNode *ast_helper_type(AstFile *f, Token token) { return result; } +AstNode *ast_poly_type(AstFile *f, Token token, AstNode *type) { + AstNode *result = make_ast_node(f, AstNode_PolyType); + result->PolyType.token = token; + result->PolyType.type = type; + return result; +} + AstNode *ast_proc_type(AstFile *f, Token token, AstNode *params, AstNode *results, u64 tags, ProcCallingConvention calling_convention, bool generic) { AstNode *result = make_ast_node(f, AstNode_ProcType); @@ -3116,6 +3129,10 @@ AstNode *parse_proc_type(AstFile *f, Token proc_token, String *link_name_) { for_array(i, params->FieldList.list) { AstNode *param = params->FieldList.list[i]; ast_node(f, Field, param); + if (f->flags&FieldFlag_dollar) { + is_generic = true; + break; + } if (f->type != NULL && f->type->kind == AstNode_HelperType) { is_generic = true; @@ -3160,6 +3177,7 @@ enum FieldPrefixKind { FieldPrefix_Using, FieldPrefix_NoAlias, FieldPrefix_CVarArg, + FieldPrefix_Dollar, }; FieldPrefixKind is_token_field_prefix(AstFile *f) { @@ -3170,6 +3188,9 @@ FieldPrefixKind is_token_field_prefix(AstFile *f) { case Token_using: return FieldPrefix_Using; + case Token_Dollar: + return FieldPrefix_Dollar; + case Token_Hash: { next_token(f); switch (f->curr_token.kind) { @@ -3192,6 +3213,7 @@ u32 parse_field_prefixes(AstFile *f) { i32 using_count = 0; i32 no_alias_count = 0; i32 c_vararg_count = 0; + i32 dollar_count = 0; for (;;) { FieldPrefixKind kind = is_token_field_prefix(f); @@ -3202,17 +3224,20 @@ u32 parse_field_prefixes(AstFile *f) { case FieldPrefix_Using: using_count += 1; next_token(f); break; case FieldPrefix_NoAlias: no_alias_count += 1; next_token(f); break; case FieldPrefix_CVarArg: c_vararg_count += 1; next_token(f); break; + case FieldPrefix_Dollar: dollar_count += 1; next_token(f); break; } } - if (using_count > 1) syntax_error(f->curr_token, "Multiple `using` in this field list"); + if (using_count > 1) syntax_error(f->curr_token, "Multiple `using` in this field list"); if (no_alias_count > 1) syntax_error(f->curr_token, "Multiple `#no_alias` in this field list"); if (c_vararg_count > 1) syntax_error(f->curr_token, "Multiple `#c_vararg` in this field list"); + if (dollar_count > 1) syntax_error(f->curr_token, "Multiple `$` in this field list"); u32 field_flags = 0; if (using_count > 0) field_flags |= FieldFlag_using; if (no_alias_count > 0) field_flags |= FieldFlag_no_alias; if (c_vararg_count > 0) field_flags |= FieldFlag_c_vararg; + if (dollar_count > 0) field_flags |= FieldFlag_dollar; return field_flags; } @@ -3234,6 +3259,10 @@ u32 check_field_prefixes(AstFile *f, isize name_count, u32 allowed_flags, u32 se syntax_error(f->curr_token, "`#c_vararg` is not allowed within this field list"); set_flags &= ~FieldFlag_c_vararg; } + if ((allowed_flags&FieldFlag_dollar) == 0 && (set_flags&FieldFlag_dollar)) { + syntax_error(f->curr_token, "`$` is only allowed within procedures"); + set_flags &= ~FieldFlag_dollar; + } return set_flags; } @@ -3417,6 +3446,12 @@ AstNode *parse_type_or_ident(AstFile *f) { AstNode *type = NULL; switch (f->curr_token.kind) { + case Token_Dollar: { + Token token = expect_token(f, Token_Dollar); + AstNode *type = parse_ident(f); + return ast_poly_type(f, token, type); + } break; + case Token_Ident: { AstNode *e = parse_ident(f); diff --git a/src/types.cpp b/src/types.cpp index ce20bfdc6..db957a21f 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -30,7 +30,6 @@ enum BasicKind { Basic_rawptr, Basic_string, // ^u8 + int Basic_any, // ^Type_Info + rawptr - Basic_Type, // `int` id of the type Basic_UntypedBool, Basic_UntypedInteger, @@ -262,7 +261,6 @@ gb_global Type basic_types[] = { {Type_Basic, {Basic_rawptr, BasicFlag_Pointer, -1, STR_LIT("rawptr")}}, {Type_Basic, {Basic_string, BasicFlag_String, -1, STR_LIT("string")}}, {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_UntypedInteger, BasicFlag_Integer | BasicFlag_Untyped, 0, STR_LIT("untyped integer")}}, @@ -308,7 +306,6 @@ gb_global Type *t_uint = &basic_types[Basic_uint]; gb_global Type *t_rawptr = &basic_types[Basic_rawptr]; gb_global Type *t_string = &basic_types[Basic_string]; 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_integer = &basic_types[Basic_UntypedInteger]; @@ -343,7 +340,6 @@ gb_global Type *t_type_info_rune = NULL; gb_global Type *t_type_info_float = NULL; gb_global Type *t_type_info_complex = 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_boolean = NULL; gb_global Type *t_type_info_pointer = NULL; @@ -368,7 +364,6 @@ gb_global Type *t_type_info_float_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_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_boolean_ptr = NULL; gb_global Type *t_type_info_pointer_ptr = NULL; @@ -780,12 +775,6 @@ bool is_type_tuple(Type *t) { 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) { if (t->kind == Type_Basic) { @@ -1065,7 +1054,6 @@ bool is_type_comparable(Type *t) { case Basic_any: return false; case Basic_rune: - case Basic_Type: return true; } return true; @@ -1759,7 +1747,6 @@ i64 type_align_of_internal(gbAllocator allocator, Type *t, TypePath *path) { switch (t->Basic.kind) { case Basic_string: 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: return build_context.word_size; @@ -1985,7 +1972,6 @@ i64 type_size_of_internal(gbAllocator allocator, Type *t, TypePath *path) { switch (kind) { case Basic_string: 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: return build_context.word_size;