authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-05-17 12:26:35-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-05-17 12:26:35-04:00
logb483db486842c6d7d348b28ca09e56673e1bd800
tree72c392366154f45f0c657bd7650d65d9f7d9e86d
parent9851a943ed0360433c9612449ed065a6800adc51

typeId builtin instead of isInteger, isFloat, etc

closes #373

10 files changed, 329 insertions(+), 137 deletions(-)

src/all_types.hpp+8-10
......@@ -1194,8 +1194,6 @@ enum BuiltinFnId {
11941194 BuiltinFnIdIntType,
11951195 BuiltinFnIdSetDebugSafety,
11961196 BuiltinFnIdTypeName,
1197 BuiltinFnIdIsInteger,
1198 BuiltinFnIdIsFloat,
11991197 BuiltinFnIdCanImplicitCast,
12001198 BuiltinFnIdSetGlobalAlign,
12011199 BuiltinFnIdSetGlobalSection,
......@@ -1207,6 +1205,7 @@ enum BuiltinFnId {
12071205 BuiltinFnIdFieldParentPtr,
12081206 BuiltinFnIdOffsetOf,
12091207 BuiltinFnIdInlineCall,
1208 BuiltinFnIdTypeId,
12101209};
12111210
12121211struct BuiltinFnEntry {
......@@ -1775,7 +1774,6 @@ enum IrInstructionId {
17751774 IrInstructionIdErrToInt,
17761775 IrInstructionIdCheckSwitchProngs,
17771776 IrInstructionIdCheckStatementIsVoid,
1778 IrInstructionIdTestType,
17791777 IrInstructionIdTypeName,
17801778 IrInstructionIdCanImplicitCast,
17811779 IrInstructionIdSetGlobalAlign,
......@@ -1786,6 +1784,7 @@ enum IrInstructionId {
17861784 IrInstructionIdEnumTagName,
17871785 IrInstructionIdFieldParentPtr,
17881786 IrInstructionIdOffsetOf,
1787 IrInstructionIdTypeId,
17891788};
17901789
17911790struct IrInstruction {
......@@ -2464,13 +2463,6 @@ struct IrInstructionCheckStatementIsVoid {
24642463 IrInstruction *statement_value;
24652464};
24662465
2467struct IrInstructionTestType {
2468 IrInstruction base;
2469
2470 IrInstruction *type_value;
2471 TypeTableEntryId type_id;
2472};
2473
24742466struct IrInstructionTypeName {
24752467 IrInstruction base;
24762468
......@@ -2540,6 +2532,12 @@ struct IrInstructionOffsetOf {
25402532 IrInstruction *field_name;
25412533};
25422534
2535struct IrInstructionTypeId {
2536 IrInstruction base;
2537
2538 IrInstruction *type_value;
2539};
2540
25432541static const size_t slice_ptr_index = 0;
25442542static const size_t slice_len_index = 1;
25452543
src/analyze.cpp+154
......@@ -4340,3 +4340,157 @@ FnTableEntry *get_extern_panic_fn(CodeGen *g) {
43404340 return g->extern_panic_fn;
43414341}
43424342
4343static const TypeTableEntryId all_type_ids[] = {
4344 TypeTableEntryIdMetaType,
4345 TypeTableEntryIdVoid,
4346 TypeTableEntryIdBool,
4347 TypeTableEntryIdUnreachable,
4348 TypeTableEntryIdInt,
4349 TypeTableEntryIdFloat,
4350 TypeTableEntryIdPointer,
4351 TypeTableEntryIdArray,
4352 TypeTableEntryIdStruct,
4353 TypeTableEntryIdNumLitFloat,
4354 TypeTableEntryIdNumLitInt,
4355 TypeTableEntryIdUndefLit,
4356 TypeTableEntryIdNullLit,
4357 TypeTableEntryIdMaybe,
4358 TypeTableEntryIdErrorUnion,
4359 TypeTableEntryIdPureError,
4360 TypeTableEntryIdEnum,
4361 TypeTableEntryIdEnumTag,
4362 TypeTableEntryIdUnion,
4363 TypeTableEntryIdFn,
4364 TypeTableEntryIdNamespace,
4365 TypeTableEntryIdBlock,
4366 TypeTableEntryIdBoundFn,
4367 TypeTableEntryIdArgTuple,
4368 TypeTableEntryIdOpaque,
4369};
4370
4371TypeTableEntryId type_id_at_index(size_t index) {
4372 assert(index < array_length(all_type_ids));
4373 return all_type_ids[index];
4374}
4375
4376size_t type_id_len() {
4377 return array_length(all_type_ids);
4378}
4379
4380size_t type_id_index(TypeTableEntryId id) {
4381 switch (id) {
4382 case TypeTableEntryIdInvalid:
4383 case TypeTableEntryIdVar:
4384 zig_unreachable();
4385 case TypeTableEntryIdMetaType:
4386 return 0;
4387 case TypeTableEntryIdVoid:
4388 return 1;
4389 case TypeTableEntryIdBool:
4390 return 2;
4391 case TypeTableEntryIdUnreachable:
4392 return 3;
4393 case TypeTableEntryIdInt:
4394 return 4;
4395 case TypeTableEntryIdFloat:
4396 return 5;
4397 case TypeTableEntryIdPointer:
4398 return 6;
4399 case TypeTableEntryIdArray:
4400 return 7;
4401 case TypeTableEntryIdStruct:
4402 return 8;
4403 case TypeTableEntryIdNumLitFloat:
4404 return 9;
4405 case TypeTableEntryIdNumLitInt:
4406 return 10;
4407 case TypeTableEntryIdUndefLit:
4408 return 11;
4409 case TypeTableEntryIdNullLit:
4410 return 12;
4411 case TypeTableEntryIdMaybe:
4412 return 13;
4413 case TypeTableEntryIdErrorUnion:
4414 return 14;
4415 case TypeTableEntryIdPureError:
4416 return 15;
4417 case TypeTableEntryIdEnum:
4418 return 16;
4419 case TypeTableEntryIdEnumTag:
4420 return 17;
4421 case TypeTableEntryIdUnion:
4422 return 18;
4423 case TypeTableEntryIdFn:
4424 return 19;
4425 case TypeTableEntryIdNamespace:
4426 return 20;
4427 case TypeTableEntryIdBlock:
4428 return 21;
4429 case TypeTableEntryIdBoundFn:
4430 return 22;
4431 case TypeTableEntryIdArgTuple:
4432 return 23;
4433 case TypeTableEntryIdOpaque:
4434 return 24;
4435 }
4436 zig_unreachable();
4437}
4438
4439const char *type_id_name(TypeTableEntryId id) {
4440 switch (id) {
4441 case TypeTableEntryIdInvalid:
4442 case TypeTableEntryIdVar:
4443 zig_unreachable();
4444 case TypeTableEntryIdMetaType:
4445 return "Type";
4446 case TypeTableEntryIdVoid:
4447 return "Void";
4448 case TypeTableEntryIdBool:
4449 return "Bool";
4450 case TypeTableEntryIdUnreachable:
4451 return "NoReturn";
4452 case TypeTableEntryIdInt:
4453 return "Int";
4454 case TypeTableEntryIdFloat:
4455 return "Float";
4456 case TypeTableEntryIdPointer:
4457 return "Pointer";
4458 case TypeTableEntryIdArray:
4459 return "Array";
4460 case TypeTableEntryIdStruct:
4461 return "Struct";
4462 case TypeTableEntryIdNumLitFloat:
4463 return "FloatLiteral";
4464 case TypeTableEntryIdNumLitInt:
4465 return "IntLiteral";
4466 case TypeTableEntryIdUndefLit:
4467 return "UndefinedLiteral";
4468 case TypeTableEntryIdNullLit:
4469 return "NullLiteral";
4470 case TypeTableEntryIdMaybe:
4471 return "Nullable";
4472 case TypeTableEntryIdErrorUnion:
4473 return "ErrorUnion";
4474 case TypeTableEntryIdPureError:
4475 return "Error";
4476 case TypeTableEntryIdEnum:
4477 return "Enum";
4478 case TypeTableEntryIdEnumTag:
4479 return "EnumTag";
4480 case TypeTableEntryIdUnion:
4481 return "Union";
4482 case TypeTableEntryIdFn:
4483 return "Fn";
4484 case TypeTableEntryIdNamespace:
4485 return "Namespace";
4486 case TypeTableEntryIdBlock:
4487 return "Block";
4488 case TypeTableEntryIdBoundFn:
4489 return "BoundFn";
4490 case TypeTableEntryIdArgTuple:
4491 return "ArgTuple";
4492 case TypeTableEntryIdOpaque:
4493 return "Opaque";
4494 }
4495 zig_unreachable();
4496}
src/analyze.hpp+5
......@@ -160,4 +160,9 @@ TypeTableEntry *create_enum_tag_type(CodeGen *g, TypeTableEntry *enum_type, Type
160160void expand_undef_array(CodeGen *g, ConstExprValue *const_val);
161161void update_compile_var(CodeGen *g, Buf *name, ConstExprValue *value);
162162
163const char *type_id_name(TypeTableEntryId id);
164TypeTableEntryId type_id_at_index(size_t index);
165size_t type_id_len();
166size_t type_id_index(TypeTableEntryId id);
167
163168#endif
src/codegen.cpp+11-3
......@@ -3009,7 +3009,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
30093009 case IrInstructionIdTestComptime:
30103010 case IrInstructionIdCheckSwitchProngs:
30113011 case IrInstructionIdCheckStatementIsVoid:
3012 case IrInstructionIdTestType:
30133012 case IrInstructionIdTypeName:
30143013 case IrInstructionIdCanImplicitCast:
30153014 case IrInstructionIdSetGlobalAlign:
......@@ -3018,6 +3017,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
30183017 case IrInstructionIdDeclRef:
30193018 case IrInstructionIdSwitchVar:
30203019 case IrInstructionIdOffsetOf:
3020 case IrInstructionIdTypeId:
30213021 zig_unreachable();
30223022 case IrInstructionIdReturn:
30233023 return ir_render_return(g, executable, (IrInstructionReturn *)instruction);
......@@ -4423,8 +4423,6 @@ static void define_builtin_fns(CodeGen *g) {
44234423 create_builtin_fn(g, BuiltinFnIdCImport, "cImport", 1);
44244424 create_builtin_fn(g, BuiltinFnIdErrName, "errorName", 1);
44254425 create_builtin_fn(g, BuiltinFnIdTypeName, "typeName", 1);
4426 create_builtin_fn(g, BuiltinFnIdIsInteger, "isInteger", 1);
4427 create_builtin_fn(g, BuiltinFnIdIsFloat, "isFloat", 1);
44284426 create_builtin_fn(g, BuiltinFnIdCanImplicitCast, "canImplicitCast", 2);
44294427 create_builtin_fn(g, BuiltinFnIdEmbedFile, "embedFile", 1);
44304428 create_builtin_fn(g, BuiltinFnIdCmpExchange, "cmpxchg", 5);
......@@ -4449,6 +4447,7 @@ static void define_builtin_fns(CodeGen *g) {
44494447 create_builtin_fn(g, BuiltinFnIdRem, "rem", 2);
44504448 create_builtin_fn(g, BuiltinFnIdMod, "mod", 2);
44514449 create_builtin_fn(g, BuiltinFnIdInlineCall, "inlineCall", SIZE_MAX);
4450 create_builtin_fn(g, BuiltinFnIdTypeId, "typeId", 1);
44524451}
44534452
44544453static const char *bool_to_str(bool b) {
......@@ -4580,6 +4579,15 @@ static void define_builtin_compile_vars(CodeGen *g) {
45804579 " ReleaseFast,\n"
45814580 "};\n\n");
45824581 }
4582 {
4583 buf_appendf(contents, "pub const TypeId = enum {\n");
4584 size_t field_count = type_id_len();
4585 for (size_t i = 0; i < field_count; i += 1) {
4586 const TypeTableEntryId id = type_id_at_index(i);
4587 buf_appendf(contents, " %s,\n", type_id_name(id));
4588 }
4589 buf_appendf(contents, "};\n\n");
4590 }
45834591 buf_appendf(contents, "pub const is_big_endian = %s;\n", bool_to_str(g->is_big_endian));
45844592 buf_appendf(contents, "pub const is_test = %s;\n", bool_to_str(g->is_test_build));
45854593 buf_appendf(contents, "pub const os = Os.%s;\n", cur_os);
src/ir.cpp+57-56
......@@ -517,10 +517,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckStatementIs
517517 return IrInstructionIdCheckStatementIsVoid;
518518}
519519
520static constexpr IrInstructionId ir_instruction_id(IrInstructionTestType *) {
521 return IrInstructionIdTestType;
522}
523
524520static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeName *) {
525521 return IrInstructionIdTypeName;
526522}
......@@ -561,6 +557,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionOffsetOf *) {
561557 return IrInstructionIdOffsetOf;
562558}
563559
560static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeId *) {
561 return IrInstructionIdTypeId;
562}
563
564564template<typename T>
565565static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {
566566 T *special_instruction = allocate<T>(1);
......@@ -2027,19 +2027,6 @@ static IrInstruction *ir_build_check_statement_is_void(IrBuilder *irb, Scope *sc
20272027 return &instruction->base;
20282028}
20292029
2030static IrInstruction *ir_build_test_type(IrBuilder *irb, Scope *scope, AstNode *source_node,
2031 IrInstruction *type_value, TypeTableEntryId type_id)
2032{
2033 IrInstructionTestType *instruction = ir_build_instruction<IrInstructionTestType>(
2034 irb, scope, source_node);
2035 instruction->type_value = type_value;
2036 instruction->type_id = type_id;
2037
2038 ir_ref_instruction(type_value, irb->current_basic_block);
2039
2040 return &instruction->base;
2041}
2042
20432030static IrInstruction *ir_build_type_name(IrBuilder *irb, Scope *scope, AstNode *source_node,
20442031 IrInstruction *type_value)
20452032{
......@@ -2168,6 +2155,17 @@ static IrInstruction *ir_build_offset_of(IrBuilder *irb, Scope *scope, AstNode *
21682155 return &instruction->base;
21692156}
21702157
2158static IrInstruction *ir_build_type_id(IrBuilder *irb, Scope *scope, AstNode *source_node,
2159 IrInstruction *type_value)
2160{
2161 IrInstructionTypeId *instruction = ir_build_instruction<IrInstructionTypeId>(irb, scope, source_node);
2162 instruction->type_value = type_value;
2163
2164 ir_ref_instruction(type_value, irb->current_basic_block);
2165
2166 return &instruction->base;
2167}
2168
21712169static IrInstruction *ir_instruction_br_get_dep(IrInstructionBr *instruction, size_t index) {
21722170 return nullptr;
21732171}
......@@ -2761,13 +2759,6 @@ static IrInstruction *ir_instruction_checkstatementisvoid_get_dep(IrInstructionC
27612759 }
27622760}
27632761
2764static IrInstruction *ir_instruction_testtype_get_dep(IrInstructionTestType *instruction, size_t index) {
2765 switch (index) {
2766 case 0: return instruction->type_value;
2767 default: return nullptr;
2768 }
2769}
2770
27712762static IrInstruction *ir_instruction_typename_get_dep(IrInstructionTypeName *instruction, size_t index) {
27722763 switch (index) {
27732764 case 0: return instruction->type_value;
......@@ -2839,6 +2830,13 @@ static IrInstruction *ir_instruction_offsetof_get_dep(IrInstructionOffsetOf *ins
28392830 }
28402831}
28412832
2833static IrInstruction *ir_instruction_typeid_get_dep(IrInstructionTypeId *instruction, size_t index) {
2834 switch (index) {
2835 case 0: return instruction->type_value;
2836 default: return nullptr;
2837 }
2838}
2839
28422840static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t index) {
28432841 switch (instruction->id) {
28442842 case IrInstructionIdInvalid:
......@@ -3007,8 +3005,6 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t
30073005 return ir_instruction_checkswitchprongs_get_dep((IrInstructionCheckSwitchProngs *) instruction, index);
30083006 case IrInstructionIdCheckStatementIsVoid:
30093007 return ir_instruction_checkstatementisvoid_get_dep((IrInstructionCheckStatementIsVoid *) instruction, index);
3010 case IrInstructionIdTestType:
3011 return ir_instruction_testtype_get_dep((IrInstructionTestType *) instruction, index);
30123008 case IrInstructionIdTypeName:
30133009 return ir_instruction_typename_get_dep((IrInstructionTypeName *) instruction, index);
30143010 case IrInstructionIdCanImplicitCast:
......@@ -3029,6 +3025,8 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t
30293025 return ir_instruction_fieldparentptr_get_dep((IrInstructionFieldParentPtr *) instruction, index);
30303026 case IrInstructionIdOffsetOf:
30313027 return ir_instruction_offsetof_get_dep((IrInstructionOffsetOf *) instruction, index);
3028 case IrInstructionIdTypeId:
3029 return ir_instruction_typeid_get_dep((IrInstructionTypeId *) instruction, index);
30323030 }
30333031 zig_unreachable();
30343032}
......@@ -3793,18 +3791,6 @@ static IrInstruction *ir_gen_overflow_op(IrBuilder *irb, Scope *scope, AstNode *
37933791 return ir_build_overflow_op(irb, scope, node, op, type_value, op1, op2, result_ptr, nullptr);
37943792}
37953793
3796static IrInstruction *ir_gen_test_type(IrBuilder *irb, Scope *scope, AstNode *node, TypeTableEntryId type_id) {
3797 assert(node->type == NodeTypeFnCallExpr);
3798
3799 AstNode *type_node = node->data.fn_call_expr.params.at(0);
3800
3801 IrInstruction *type_value = ir_gen_node(irb, type_node, scope);
3802 if (type_value == irb->codegen->invalid_instruction)
3803 return irb->codegen->invalid_instruction;
3804
3805 return ir_build_test_type(irb, scope, node, type_value, type_id);
3806}
3807
38083794static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNode *node) {
38093795 assert(node->type == NodeTypeFnCallExpr);
38103796
......@@ -4217,10 +4203,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
42174203
42184204 return ir_build_type_name(irb, scope, node, arg0_value);
42194205 }
4220 case BuiltinFnIdIsInteger:
4221 return ir_gen_test_type(irb, scope, node, TypeTableEntryIdInt);
4222 case BuiltinFnIdIsFloat:
4223 return ir_gen_test_type(irb, scope, node, TypeTableEntryIdFloat);
42244206 case BuiltinFnIdCanImplicitCast:
42254207 {
42264208 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
......@@ -4375,6 +4357,15 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
43754357
43764358 return ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, true);
43774359 }
4360 case BuiltinFnIdTypeId:
4361 {
4362 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4363 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
4364 if (arg0_value == irb->codegen->invalid_instruction)
4365 return arg0_value;
4366
4367 return ir_build_type_id(irb, scope, node, arg0_value);
4368 }
43784369 }
43794370 zig_unreachable();
43804371}
......@@ -11865,6 +11856,27 @@ static TypeTableEntry *ir_analyze_instruction_offset_of(IrAnalyze *ira,
1186511856 return ira->codegen->builtin_types.entry_num_lit_int;
1186611857}
1186711858
11859static TypeTableEntry *ir_analyze_instruction_type_id(IrAnalyze *ira,
11860 IrInstructionTypeId *instruction)
11861{
11862 IrInstruction *type_value = instruction->type_value->other;
11863 TypeTableEntry *type_entry = ir_resolve_type(ira, type_value);
11864 if (type_is_invalid(type_entry))
11865 return ira->codegen->builtin_types.entry_invalid;
11866
11867 Tld *tld = ira->codegen->compile_var_import->decls_scope->decl_table.get(buf_create_from_str("TypeId"));
11868 resolve_top_level_decl(ira->codegen, tld, false);
11869 assert(tld->id == TldIdVar);
11870 TldVar *tld_var = (TldVar *)tld;
11871 ConstExprValue *var_value = tld_var->var->value;
11872 assert(var_value->type->id == TypeTableEntryIdMetaType);
11873 TypeTableEntry *result_type = var_value->data.x_type;
11874
11875 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
11876 out_val->data.x_enum.tag = type_id_index(type_entry->id);
11877 return result_type;
11878}
11879
1186811880static TypeTableEntry *ir_analyze_instruction_type_name(IrAnalyze *ira, IrInstructionTypeName *instruction) {
1186911881 IrInstruction *type_value = instruction->type_value->other;
1187011882 TypeTableEntry *type_entry = ir_resolve_type(ira, type_value);
......@@ -13025,17 +13037,6 @@ static TypeTableEntry *ir_analyze_instruction_check_statement_is_void(IrAnalyze
1302513037 return ira->codegen->builtin_types.entry_void;
1302613038}
1302713039
13028static TypeTableEntry *ir_analyze_instruction_test_type(IrAnalyze *ira, IrInstructionTestType *instruction) {
13029 IrInstruction *type_value = instruction->type_value->other;
13030 TypeTableEntry *type_entry = ir_resolve_type(ira, type_value);
13031 if (type_is_invalid(type_entry))
13032 return ira->codegen->builtin_types.entry_invalid;
13033
13034 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
13035 out_val->data.x_bool = (type_entry->id == instruction->type_id);
13036 return ira->codegen->builtin_types.entry_bool;
13037}
13038
1303913040static TypeTableEntry *ir_analyze_instruction_can_implicit_cast(IrAnalyze *ira,
1304013041 IrInstructionCanImplicitCast *instruction)
1304113042{
......@@ -13368,8 +13369,6 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
1336813369 return ir_analyze_instruction_check_switch_prongs(ira, (IrInstructionCheckSwitchProngs *)instruction);
1336913370 case IrInstructionIdCheckStatementIsVoid:
1337013371 return ir_analyze_instruction_check_statement_is_void(ira, (IrInstructionCheckStatementIsVoid *)instruction);
13371 case IrInstructionIdTestType:
13372 return ir_analyze_instruction_test_type(ira, (IrInstructionTestType *)instruction);
1337313372 case IrInstructionIdCanImplicitCast:
1337413373 return ir_analyze_instruction_can_implicit_cast(ira, (IrInstructionCanImplicitCast *)instruction);
1337513374 case IrInstructionIdDeclRef:
......@@ -13386,6 +13385,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
1338613385 return ir_analyze_instruction_field_parent_ptr(ira, (IrInstructionFieldParentPtr *)instruction);
1338713386 case IrInstructionIdOffsetOf:
1338813387 return ir_analyze_instruction_offset_of(ira, (IrInstructionOffsetOf *)instruction);
13388 case IrInstructionIdTypeId:
13389 return ir_analyze_instruction_type_id(ira, (IrInstructionTypeId *)instruction);
1338913390 case IrInstructionIdMaybeWrap:
1339013391 case IrInstructionIdErrWrapCode:
1339113392 case IrInstructionIdErrWrapPayload:
......@@ -13556,7 +13557,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
1355613557 case IrInstructionIdIntToEnum:
1355713558 case IrInstructionIdIntToErr:
1355813559 case IrInstructionIdErrToInt:
13559 case IrInstructionIdTestType:
1356013560 case IrInstructionIdCanImplicitCast:
1356113561 case IrInstructionIdDeclRef:
1356213562 case IrInstructionIdErrName:
......@@ -13564,6 +13564,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
1356413564 case IrInstructionIdEnumTagName:
1356513565 case IrInstructionIdFieldParentPtr:
1356613566 case IrInstructionIdOffsetOf:
13567 case IrInstructionIdTypeId:
1356713568 return false;
1356813569 case IrInstructionIdAsm:
1356913570 {
src/ir_print.cpp+9-8
......@@ -811,11 +811,6 @@ static void ir_print_check_statement_is_void(IrPrint *irp, IrInstructionCheckSta
811811 fprintf(irp->f, ")");
812812}
813813
814static void ir_print_test_type(IrPrint *irp, IrInstructionTestType *instruction) {
815 fprintf(irp->f, "testtype ");
816 ir_print_other_instruction(irp, instruction->type_value);
817}
818
819814static void ir_print_type_name(IrPrint *irp, IrInstructionTypeName *instruction) {
820815 fprintf(irp->f, "typename ");
821816 ir_print_other_instruction(irp, instruction->type_value);
......@@ -884,6 +879,12 @@ static void ir_print_offset_of(IrPrint *irp, IrInstructionOffsetOf *instruction)
884879 fprintf(irp->f, ")");
885880}
886881
882static void ir_print_type_id(IrPrint *irp, IrInstructionTypeId *instruction) {
883 fprintf(irp->f, "@typeId(");
884 ir_print_other_instruction(irp, instruction->type_value);
885 fprintf(irp->f, ")");
886}
887
887888static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
888889 ir_print_prefix(irp, instruction);
889890 switch (instruction->id) {
......@@ -1135,9 +1136,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
11351136 case IrInstructionIdCheckStatementIsVoid:
11361137 ir_print_check_statement_is_void(irp, (IrInstructionCheckStatementIsVoid *)instruction);
11371138 break;
1138 case IrInstructionIdTestType:
1139 ir_print_test_type(irp, (IrInstructionTestType *)instruction);
1140 break;
11411139 case IrInstructionIdTypeName:
11421140 ir_print_type_name(irp, (IrInstructionTypeName *)instruction);
11431141 break;
......@@ -1168,6 +1166,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
11681166 case IrInstructionIdOffsetOf:
11691167 ir_print_offset_of(irp, (IrInstructionOffsetOf *)instruction);
11701168 break;
1169 case IrInstructionIdTypeId:
1170 ir_print_type_id(irp, (IrInstructionTypeId *)instruction);
1171 break;
11711172 }
11721173 fprintf(irp->f, "\n");
11731174}
std/build.zig+9-9
......@@ -488,15 +488,15 @@ pub const Builder = struct {
488488 }
489489
490490 fn typeToEnum(comptime T: type) -> TypeId {
491 if (@isInteger(T)) {
492 TypeId.Int
493 } else if (@isFloat(T)) {
494 TypeId.Float
495 } else switch (T) {
496 bool => TypeId.Bool,
497 []const u8 => TypeId.String,
498 []const []const u8 => TypeId.List,
499 else => @compileError("Unsupported type: " ++ @typeName(T)),
491 switch (@typeId(T)) {
492 builtin.TypeId.Int => TypeId.Int,
493 builtin.TypeId.Float => TypeId.Float,
494 builtin.TypeId.Bool => TypeId.Bool,
495 else => switch (T) {
496 []const u8 => TypeId.String,
497 []const []const u8 => TypeId.List,
498 else => @compileError("Unsupported type: " ++ @typeName(T)),
499 },
500500 }
501501 }
502502
std/fmt.zig+20-13
......@@ -2,6 +2,7 @@ const math = @import("math.zig");
22const debug = @import("debug.zig");
33const assert = debug.assert;
44const mem = @import("mem.zig");
5const builtin = @import("builtin");
56
67const max_f64_digits = 65;
78const max_int_digits = 65;
......@@ -174,19 +175,25 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->bool,
174175
175176pub fn formatValue(value: var, context: var, output: fn(@typeOf(context), []const u8)->bool) -> bool {
176177 const T = @typeOf(value);
177 if (@isInteger(T)) {
178 return formatInt(value, 10, false, 0, context, output);
179 } else if (@isFloat(T)) {
180 @compileError("TODO implement formatFloat");
181 } else if (@canImplicitCast([]const u8, value)) {
182 const casted_value = ([]const u8)(value);
183 return output(context, casted_value);
184 } else if (T == void) {
185 return output(context, "void");
186 } else if (T == bool) {
187 return output(context, if (value) "true" else "false");
188 } else {
189 @compileError("Unable to format type '" ++ @typeName(T) ++ "'");
178 switch (@typeId(T)) {
179 builtin.TypeId.Int => {
180 return formatInt(value, 10, false, 0, context, output);
181 },
182 builtin.TypeId.Float => {
183 @compileError("TODO implement formatFloat");
184 },
185 builtin.TypeId.Void => {
186 return output(context, "void");
187 },
188 builtin.TypeId.Bool => {
189 return output(context, if (value) "true" else "false");
190 },
191 else => if (@canImplicitCast([]const u8, value)) {
192 const casted_value = ([]const u8)(value);
193 return output(context, casted_value);
194 } else {
195 @compileError("Unable to format type '" ++ @typeName(T) ++ "'");
196 },
190197 }
191198}
192199
std/math.zig+22-17
......@@ -1,4 +1,5 @@
11const assert = @import("debug.zig").assert;
2const builtin = @import("builtin");
23
34pub const Cmp = enum {
45 Less,
......@@ -61,23 +62,27 @@ fn testOverflow() {
6162
6263pub fn log(comptime base: usize, value: var) -> @typeOf(value) {
6364 const T = @typeOf(value);
64 if (@isInteger(T)) {
65 if (base == 2) {
66 return T.bit_count - 1 - @clz(value);
67 } else {
68 @compileError("TODO implement log for non base 2 integers");
69 }
70 } else if (@isFloat(T)) {
71 @compileError("TODO implement log for floats");
72 } else {
73 @compileError("log expects integer or float, found '" ++ @typeName(T) ++ "'");
65 switch (@typeId(T)) {
66 builtin.TypeId.Int => {
67 if (base == 2) {
68 return T.bit_count - 1 - @clz(value);
69 } else {
70 @compileError("TODO implement log for non base 2 integers");
71 }
72 },
73 builtin.TypeId.Float => {
74 @compileError("TODO implement log for floats");
75 },
76 else => {
77 @compileError("log expects integer or float, found '" ++ @typeName(T) ++ "'");
78 },
7479 }
7580}
7681
7782error Overflow;
7883pub fn absInt(x: var) -> %@typeOf(x) {
7984 const T = @typeOf(x);
80 comptime assert(@isInteger(T)); // must pass an integer to absInt
85 comptime assert(@typeId(T) == builtin.TypeId.Int); // must pass an integer to absInt
8186 comptime assert(T.is_signed); // must pass a signed integer to absInt
8287 if (x == @minValue(@typeOf(x)))
8388 return error.Overflow;
......@@ -97,7 +102,7 @@ fn testAbsInt() {
97102}
98103
99104pub fn absFloat(x: var) -> @typeOf(x) {
100 comptime assert(@isFloat(@typeOf(x)));
105 comptime assert(@typeId(@typeOf(x)) == builtin.TypeId.Float);
101106 return if (x < 0) -x else x;
102107}
103108
......@@ -116,7 +121,7 @@ pub fn divTrunc(comptime T: type, numerator: T, denominator: T) -> %T {
116121 @setDebugSafety(this, false);
117122 if (denominator == 0)
118123 return error.DivisionByZero;
119 if (@isInteger(T) and T.is_signed and numerator == @minValue(T) and denominator == -1)
124 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1)
120125 return error.Overflow;
121126 return @divTrunc(numerator, denominator);
122127}
......@@ -141,7 +146,7 @@ pub fn divFloor(comptime T: type, numerator: T, denominator: T) -> %T {
141146 @setDebugSafety(this, false);
142147 if (denominator == 0)
143148 return error.DivisionByZero;
144 if (@isInteger(T) and T.is_signed and numerator == @minValue(T) and denominator == -1)
149 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1)
145150 return error.Overflow;
146151 return @divFloor(numerator, denominator);
147152}
......@@ -167,7 +172,7 @@ pub fn divExact(comptime T: type, numerator: T, denominator: T) -> %T {
167172 @setDebugSafety(this, false);
168173 if (denominator == 0)
169174 return error.DivisionByZero;
170 if (@isInteger(T) and T.is_signed and numerator == @minValue(T) and denominator == -1)
175 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1)
171176 return error.Overflow;
172177 const result = @divTrunc(numerator, denominator);
173178 if (result * denominator != numerator)
......@@ -246,7 +251,7 @@ fn testRem() {
246251}
247252
248253fn isNan(comptime T: type, x: T) -> bool {
249 assert(@isFloat(T));
254 assert(@typeId(T) == builtin.TypeId.Float);
250255 const bits = floatBits(x);
251256 if (T == f32) {
252257 return (bits & 0x7fffffff) > 0x7f800000;
......@@ -258,7 +263,7 @@ fn isNan(comptime T: type, x: T) -> bool {
258263}
259264
260265fn floatBits(comptime T: type, x: T) -> @IntType(false, T.bit_count) {
261 assert(@isFloat(T));
266 assert(@typeId(T) == builtin.TypeId.Float);
262267 const uint = @IntType(false, T.bit_count);
263268 return *@intToPtr(&const uint, &x);
264269}
test/cases/misc.zig+34-21
......@@ -446,29 +446,42 @@ fn testArray2DConstDoublePtr(ptr: &const f32) {
446446 assert(ptr[1] == 2.0);
447447}
448448
449test "@isInteger" {
450 comptime {
451 assert(@isInteger(i8));
452 assert(@isInteger(u8));
453 assert(@isInteger(i64));
454 assert(@isInteger(u64));
455 assert(!@isInteger(f32));
456 assert(!@isInteger(f64));
457 assert(!@isInteger(bool));
458 assert(!@isInteger(&i32));
459 }
460}
449const Tid = builtin.TypeId;
450const AStruct = struct { x: i32, };
451const AnEnum = enum { One, Two, };
452const AnEnumWithPayload = enum { One: i32, Two, };
461453
462test "@isFloat" {
454test "@typeId" {
463455 comptime {
464 assert(!@isFloat(i8));
465 assert(!@isFloat(u8));
466 assert(!@isFloat(i64));
467 assert(!@isFloat(u64));
468 assert(@isFloat(f32));
469 assert(@isFloat(f64));
470 assert(!@isFloat(bool));
471 assert(!@isFloat(&f32));
456 assert(@typeId(type) == Tid.Type);
457 assert(@typeId(void) == Tid.Void);
458 assert(@typeId(bool) == Tid.Bool);
459 assert(@typeId(noreturn) == Tid.NoReturn);
460 assert(@typeId(i8) == Tid.Int);
461 assert(@typeId(u8) == Tid.Int);
462 assert(@typeId(i64) == Tid.Int);
463 assert(@typeId(u64) == Tid.Int);
464 assert(@typeId(f32) == Tid.Float);
465 assert(@typeId(f64) == Tid.Float);
466 assert(@typeId(&f32) == Tid.Pointer);
467 assert(@typeId([2]u8) == Tid.Array);
468 assert(@typeId(AStruct) == Tid.Struct);
469 assert(@typeId(@typeOf(1)) == Tid.IntLiteral);
470 assert(@typeId(@typeOf(1.0)) == Tid.FloatLiteral);
471 assert(@typeId(@typeOf(undefined)) == Tid.UndefinedLiteral);
472 assert(@typeId(@typeOf(null)) == Tid.NullLiteral);
473 assert(@typeId(?i32) == Tid.Nullable);
474 assert(@typeId(%i32) == Tid.ErrorUnion);
475 assert(@typeId(error) == Tid.Error);
476 assert(@typeId(AnEnum) == Tid.Enum);
477 assert(@typeId(@typeOf(AnEnumWithPayload.One)) == Tid.EnumTag);
478 // TODO union
479 assert(@typeId(fn()) == Tid.Fn);
480 assert(@typeId(@typeOf(builtin)) == Tid.Namespace);
481 assert(@typeId(@typeOf({this})) == Tid.Block);
482 // TODO bound fn
483 // TODO arg tuple
484 // TODO opaque
472485 }
473486}
474487