| author | |
| committer | |
| log | b483db486842c6d7d348b28ca09e56673e1bd800 |
| tree | 72c392366154f45f0c657bd7650d65d9f7d9e86d |
| parent | 9851a943ed0360433c9612449ed065a6800adc51 |
closes #37310 files changed, 329 insertions(+), 137 deletions(-)
src/all_types.hpp+8-10| ... | @@ -1194,8 +1194,6 @@ enum BuiltinFnId { | ... | @@ -1194,8 +1194,6 @@ enum BuiltinFnId { |
| 1194 | BuiltinFnIdIntType, | 1194 | BuiltinFnIdIntType, |
| 1195 | BuiltinFnIdSetDebugSafety, | 1195 | BuiltinFnIdSetDebugSafety, |
| 1196 | BuiltinFnIdTypeName, | 1196 | BuiltinFnIdTypeName, |
| 1197 | BuiltinFnIdIsInteger, | ||
| 1198 | BuiltinFnIdIsFloat, | ||
| 1199 | BuiltinFnIdCanImplicitCast, | 1197 | BuiltinFnIdCanImplicitCast, |
| 1200 | BuiltinFnIdSetGlobalAlign, | 1198 | BuiltinFnIdSetGlobalAlign, |
| 1201 | BuiltinFnIdSetGlobalSection, | 1199 | BuiltinFnIdSetGlobalSection, |
| ... | @@ -1207,6 +1205,7 @@ enum BuiltinFnId { | ... | @@ -1207,6 +1205,7 @@ enum BuiltinFnId { |
| 1207 | BuiltinFnIdFieldParentPtr, | 1205 | BuiltinFnIdFieldParentPtr, |
| 1208 | BuiltinFnIdOffsetOf, | 1206 | BuiltinFnIdOffsetOf, |
| 1209 | BuiltinFnIdInlineCall, | 1207 | BuiltinFnIdInlineCall, |
| 1208 | BuiltinFnIdTypeId, | ||
| 1210 | }; | 1209 | }; |
| 1211 | 1210 | ||
| 1212 | struct BuiltinFnEntry { | 1211 | struct BuiltinFnEntry { |
| ... | @@ -1775,7 +1774,6 @@ enum IrInstructionId { | ... | @@ -1775,7 +1774,6 @@ enum IrInstructionId { |
| 1775 | IrInstructionIdErrToInt, | 1774 | IrInstructionIdErrToInt, |
| 1776 | IrInstructionIdCheckSwitchProngs, | 1775 | IrInstructionIdCheckSwitchProngs, |
| 1777 | IrInstructionIdCheckStatementIsVoid, | 1776 | IrInstructionIdCheckStatementIsVoid, |
| 1778 | IrInstructionIdTestType, | ||
| 1779 | IrInstructionIdTypeName, | 1777 | IrInstructionIdTypeName, |
| 1780 | IrInstructionIdCanImplicitCast, | 1778 | IrInstructionIdCanImplicitCast, |
| 1781 | IrInstructionIdSetGlobalAlign, | 1779 | IrInstructionIdSetGlobalAlign, |
| ... | @@ -1786,6 +1784,7 @@ enum IrInstructionId { | ... | @@ -1786,6 +1784,7 @@ enum IrInstructionId { |
| 1786 | IrInstructionIdEnumTagName, | 1784 | IrInstructionIdEnumTagName, |
| 1787 | IrInstructionIdFieldParentPtr, | 1785 | IrInstructionIdFieldParentPtr, |
| 1788 | IrInstructionIdOffsetOf, | 1786 | IrInstructionIdOffsetOf, |
| 1787 | IrInstructionIdTypeId, | ||
| 1789 | }; | 1788 | }; |
| 1790 | 1789 | ||
| 1791 | struct IrInstruction { | 1790 | struct IrInstruction { |
| ... | @@ -2464,13 +2463,6 @@ struct IrInstructionCheckStatementIsVoid { | ... | @@ -2464,13 +2463,6 @@ struct IrInstructionCheckStatementIsVoid { |
| 2464 | IrInstruction *statement_value; | 2463 | IrInstruction *statement_value; |
| 2465 | }; | 2464 | }; |
| 2466 | 2465 | ||
| 2467 | struct IrInstructionTestType { | ||
| 2468 | IrInstruction base; | ||
| 2469 | |||
| 2470 | IrInstruction *type_value; | ||
| 2471 | TypeTableEntryId type_id; | ||
| 2472 | }; | ||
| 2473 | |||
| 2474 | struct IrInstructionTypeName { | 2466 | struct IrInstructionTypeName { |
| 2475 | IrInstruction base; | 2467 | IrInstruction base; |
| 2476 | 2468 | ||
| ... | @@ -2540,6 +2532,12 @@ struct IrInstructionOffsetOf { | ... | @@ -2540,6 +2532,12 @@ struct IrInstructionOffsetOf { |
| 2540 | IrInstruction *field_name; | 2532 | IrInstruction *field_name; |
| 2541 | }; | 2533 | }; |
| 2542 | 2534 | ||
| 2535 | struct IrInstructionTypeId { | ||
| 2536 | IrInstruction base; | ||
| 2537 | |||
| 2538 | IrInstruction *type_value; | ||
| 2539 | }; | ||
| 2540 | |||
| 2543 | static const size_t slice_ptr_index = 0; | 2541 | static const size_t slice_ptr_index = 0; |
| 2544 | static const size_t slice_len_index = 1; | 2542 | static const size_t slice_len_index = 1; |
| 2545 | 2543 |
src/analyze.cpp+154| ... | @@ -4340,3 +4340,157 @@ FnTableEntry *get_extern_panic_fn(CodeGen *g) { | ... | @@ -4340,3 +4340,157 @@ FnTableEntry *get_extern_panic_fn(CodeGen *g) { |
| 4340 | return g->extern_panic_fn; | 4340 | return g->extern_panic_fn; |
| 4341 | } | 4341 | } |
| 4342 | 4342 | ||
| 4343 | static 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 | |||
| 4371 | TypeTableEntryId type_id_at_index(size_t index) { | ||
| 4372 | assert(index < array_length(all_type_ids)); | ||
| 4373 | return all_type_ids[index]; | ||
| 4374 | } | ||
| 4375 | |||
| 4376 | size_t type_id_len() { | ||
| 4377 | return array_length(all_type_ids); | ||
| 4378 | } | ||
| 4379 | |||
| 4380 | size_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 | |||
| 4439 | const 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 | ... | @@ -160,4 +160,9 @@ TypeTableEntry *create_enum_tag_type(CodeGen *g, TypeTableEntry *enum_type, Type |
| 160 | void expand_undef_array(CodeGen *g, ConstExprValue *const_val); | 160 | void expand_undef_array(CodeGen *g, ConstExprValue *const_val); |
| 161 | void update_compile_var(CodeGen *g, Buf *name, ConstExprValue *value); | 161 | void update_compile_var(CodeGen *g, Buf *name, ConstExprValue *value); |
| 162 | 162 | ||
| 163 | const char *type_id_name(TypeTableEntryId id); | ||
| 164 | TypeTableEntryId type_id_at_index(size_t index); | ||
| 165 | size_t type_id_len(); | ||
| 166 | size_t type_id_index(TypeTableEntryId id); | ||
| 167 | |||
| 163 | #endif | 168 | #endif |
src/codegen.cpp+11-3| ... | @@ -3009,7 +3009,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, | ... | @@ -3009,7 +3009,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, |
| 3009 | case IrInstructionIdTestComptime: | 3009 | case IrInstructionIdTestComptime: |
| 3010 | case IrInstructionIdCheckSwitchProngs: | 3010 | case IrInstructionIdCheckSwitchProngs: |
| 3011 | case IrInstructionIdCheckStatementIsVoid: | 3011 | case IrInstructionIdCheckStatementIsVoid: |
| 3012 | case IrInstructionIdTestType: | ||
| 3013 | case IrInstructionIdTypeName: | 3012 | case IrInstructionIdTypeName: |
| 3014 | case IrInstructionIdCanImplicitCast: | 3013 | case IrInstructionIdCanImplicitCast: |
| 3015 | case IrInstructionIdSetGlobalAlign: | 3014 | case IrInstructionIdSetGlobalAlign: |
| ... | @@ -3018,6 +3017,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, | ... | @@ -3018,6 +3017,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, |
| 3018 | case IrInstructionIdDeclRef: | 3017 | case IrInstructionIdDeclRef: |
| 3019 | case IrInstructionIdSwitchVar: | 3018 | case IrInstructionIdSwitchVar: |
| 3020 | case IrInstructionIdOffsetOf: | 3019 | case IrInstructionIdOffsetOf: |
| 3020 | case IrInstructionIdTypeId: | ||
| 3021 | zig_unreachable(); | 3021 | zig_unreachable(); |
| 3022 | case IrInstructionIdReturn: | 3022 | case IrInstructionIdReturn: |
| 3023 | return ir_render_return(g, executable, (IrInstructionReturn *)instruction); | 3023 | return ir_render_return(g, executable, (IrInstructionReturn *)instruction); |
| ... | @@ -4423,8 +4423,6 @@ static void define_builtin_fns(CodeGen *g) { | ... | @@ -4423,8 +4423,6 @@ static void define_builtin_fns(CodeGen *g) { |
| 4423 | create_builtin_fn(g, BuiltinFnIdCImport, "cImport", 1); | 4423 | create_builtin_fn(g, BuiltinFnIdCImport, "cImport", 1); |
| 4424 | create_builtin_fn(g, BuiltinFnIdErrName, "errorName", 1); | 4424 | create_builtin_fn(g, BuiltinFnIdErrName, "errorName", 1); |
| 4425 | create_builtin_fn(g, BuiltinFnIdTypeName, "typeName", 1); | 4425 | create_builtin_fn(g, BuiltinFnIdTypeName, "typeName", 1); |
| 4426 | create_builtin_fn(g, BuiltinFnIdIsInteger, "isInteger", 1); | ||
| 4427 | create_builtin_fn(g, BuiltinFnIdIsFloat, "isFloat", 1); | ||
| 4428 | create_builtin_fn(g, BuiltinFnIdCanImplicitCast, "canImplicitCast", 2); | 4426 | create_builtin_fn(g, BuiltinFnIdCanImplicitCast, "canImplicitCast", 2); |
| 4429 | create_builtin_fn(g, BuiltinFnIdEmbedFile, "embedFile", 1); | 4427 | create_builtin_fn(g, BuiltinFnIdEmbedFile, "embedFile", 1); |
| 4430 | create_builtin_fn(g, BuiltinFnIdCmpExchange, "cmpxchg", 5); | 4428 | create_builtin_fn(g, BuiltinFnIdCmpExchange, "cmpxchg", 5); |
| ... | @@ -4449,6 +4447,7 @@ static void define_builtin_fns(CodeGen *g) { | ... | @@ -4449,6 +4447,7 @@ static void define_builtin_fns(CodeGen *g) { |
| 4449 | create_builtin_fn(g, BuiltinFnIdRem, "rem", 2); | 4447 | create_builtin_fn(g, BuiltinFnIdRem, "rem", 2); |
| 4450 | create_builtin_fn(g, BuiltinFnIdMod, "mod", 2); | 4448 | create_builtin_fn(g, BuiltinFnIdMod, "mod", 2); |
| 4451 | create_builtin_fn(g, BuiltinFnIdInlineCall, "inlineCall", SIZE_MAX); | 4449 | create_builtin_fn(g, BuiltinFnIdInlineCall, "inlineCall", SIZE_MAX); |
| 4450 | create_builtin_fn(g, BuiltinFnIdTypeId, "typeId", 1); | ||
| 4452 | } | 4451 | } |
| 4453 | 4452 | ||
| 4454 | static const char *bool_to_str(bool b) { | 4453 | static const char *bool_to_str(bool b) { |
| ... | @@ -4580,6 +4579,15 @@ static void define_builtin_compile_vars(CodeGen *g) { | ... | @@ -4580,6 +4579,15 @@ static void define_builtin_compile_vars(CodeGen *g) { |
| 4580 | " ReleaseFast,\n" | 4579 | " ReleaseFast,\n" |
| 4581 | "};\n\n"); | 4580 | "};\n\n"); |
| 4582 | } | 4581 | } |
| 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 | } | ||
| 4583 | buf_appendf(contents, "pub const is_big_endian = %s;\n", bool_to_str(g->is_big_endian)); | 4591 | buf_appendf(contents, "pub const is_big_endian = %s;\n", bool_to_str(g->is_big_endian)); |
| 4584 | buf_appendf(contents, "pub const is_test = %s;\n", bool_to_str(g->is_test_build)); | 4592 | buf_appendf(contents, "pub const is_test = %s;\n", bool_to_str(g->is_test_build)); |
| 4585 | buf_appendf(contents, "pub const os = Os.%s;\n", cur_os); | 4593 | 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 | ... | @@ -517,10 +517,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckStatementIs |
| 517 | return IrInstructionIdCheckStatementIsVoid; | 517 | return IrInstructionIdCheckStatementIsVoid; |
| 518 | } | 518 | } |
| 519 | 519 | ||
| 520 | static constexpr IrInstructionId ir_instruction_id(IrInstructionTestType *) { | ||
| 521 | return IrInstructionIdTestType; | ||
| 522 | } | ||
| 523 | |||
| 524 | static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeName *) { | 520 | static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeName *) { |
| 525 | return IrInstructionIdTypeName; | 521 | return IrInstructionIdTypeName; |
| 526 | } | 522 | } |
| ... | @@ -561,6 +557,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionOffsetOf *) { | ... | @@ -561,6 +557,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionOffsetOf *) { |
| 561 | return IrInstructionIdOffsetOf; | 557 | return IrInstructionIdOffsetOf; |
| 562 | } | 558 | } |
| 563 | 559 | ||
| 560 | static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeId *) { | ||
| 561 | return IrInstructionIdTypeId; | ||
| 562 | } | ||
| 563 | |||
| 564 | template<typename T> | 564 | template<typename T> |
| 565 | static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { | 565 | static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { |
| 566 | T *special_instruction = allocate<T>(1); | 566 | T *special_instruction = allocate<T>(1); |
| ... | @@ -2027,19 +2027,6 @@ static IrInstruction *ir_build_check_statement_is_void(IrBuilder *irb, Scope *sc | ... | @@ -2027,19 +2027,6 @@ static IrInstruction *ir_build_check_statement_is_void(IrBuilder *irb, Scope *sc |
| 2027 | return &instruction->base; | 2027 | return &instruction->base; |
| 2028 | } | 2028 | } |
| 2029 | 2029 | ||
| 2030 | static 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 | |||
| 2043 | static IrInstruction *ir_build_type_name(IrBuilder *irb, Scope *scope, AstNode *source_node, | 2030 | static IrInstruction *ir_build_type_name(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2044 | IrInstruction *type_value) | 2031 | IrInstruction *type_value) |
| 2045 | { | 2032 | { |
| ... | @@ -2168,6 +2155,17 @@ static IrInstruction *ir_build_offset_of(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -2168,6 +2155,17 @@ static IrInstruction *ir_build_offset_of(IrBuilder *irb, Scope *scope, AstNode * |
| 2168 | return &instruction->base; | 2155 | return &instruction->base; |
| 2169 | } | 2156 | } |
| 2170 | 2157 | ||
| 2158 | static 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 | |||
| 2171 | static IrInstruction *ir_instruction_br_get_dep(IrInstructionBr *instruction, size_t index) { | 2169 | static IrInstruction *ir_instruction_br_get_dep(IrInstructionBr *instruction, size_t index) { |
| 2172 | return nullptr; | 2170 | return nullptr; |
| 2173 | } | 2171 | } |
| ... | @@ -2761,13 +2759,6 @@ static IrInstruction *ir_instruction_checkstatementisvoid_get_dep(IrInstructionC | ... | @@ -2761,13 +2759,6 @@ static IrInstruction *ir_instruction_checkstatementisvoid_get_dep(IrInstructionC |
| 2761 | } | 2759 | } |
| 2762 | } | 2760 | } |
| 2763 | 2761 | ||
| 2764 | static 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 | |||
| 2771 | static IrInstruction *ir_instruction_typename_get_dep(IrInstructionTypeName *instruction, size_t index) { | 2762 | static IrInstruction *ir_instruction_typename_get_dep(IrInstructionTypeName *instruction, size_t index) { |
| 2772 | switch (index) { | 2763 | switch (index) { |
| 2773 | case 0: return instruction->type_value; | 2764 | case 0: return instruction->type_value; |
| ... | @@ -2839,6 +2830,13 @@ static IrInstruction *ir_instruction_offsetof_get_dep(IrInstructionOffsetOf *ins | ... | @@ -2839,6 +2830,13 @@ static IrInstruction *ir_instruction_offsetof_get_dep(IrInstructionOffsetOf *ins |
| 2839 | } | 2830 | } |
| 2840 | } | 2831 | } |
| 2841 | 2832 | ||
| 2833 | static 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 | |||
| 2842 | static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t index) { | 2840 | static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t index) { |
| 2843 | switch (instruction->id) { | 2841 | switch (instruction->id) { |
| 2844 | case IrInstructionIdInvalid: | 2842 | case IrInstructionIdInvalid: |
| ... | @@ -3007,8 +3005,6 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t | ... | @@ -3007,8 +3005,6 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t |
| 3007 | return ir_instruction_checkswitchprongs_get_dep((IrInstructionCheckSwitchProngs *) instruction, index); | 3005 | return ir_instruction_checkswitchprongs_get_dep((IrInstructionCheckSwitchProngs *) instruction, index); |
| 3008 | case IrInstructionIdCheckStatementIsVoid: | 3006 | case IrInstructionIdCheckStatementIsVoid: |
| 3009 | return ir_instruction_checkstatementisvoid_get_dep((IrInstructionCheckStatementIsVoid *) instruction, index); | 3007 | return ir_instruction_checkstatementisvoid_get_dep((IrInstructionCheckStatementIsVoid *) instruction, index); |
| 3010 | case IrInstructionIdTestType: | ||
| 3011 | return ir_instruction_testtype_get_dep((IrInstructionTestType *) instruction, index); | ||
| 3012 | case IrInstructionIdTypeName: | 3008 | case IrInstructionIdTypeName: |
| 3013 | return ir_instruction_typename_get_dep((IrInstructionTypeName *) instruction, index); | 3009 | return ir_instruction_typename_get_dep((IrInstructionTypeName *) instruction, index); |
| 3014 | case IrInstructionIdCanImplicitCast: | 3010 | case IrInstructionIdCanImplicitCast: |
| ... | @@ -3029,6 +3025,8 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t | ... | @@ -3029,6 +3025,8 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t |
| 3029 | return ir_instruction_fieldparentptr_get_dep((IrInstructionFieldParentPtr *) instruction, index); | 3025 | return ir_instruction_fieldparentptr_get_dep((IrInstructionFieldParentPtr *) instruction, index); |
| 3030 | case IrInstructionIdOffsetOf: | 3026 | case IrInstructionIdOffsetOf: |
| 3031 | return ir_instruction_offsetof_get_dep((IrInstructionOffsetOf *) instruction, index); | 3027 | return ir_instruction_offsetof_get_dep((IrInstructionOffsetOf *) instruction, index); |
| 3028 | case IrInstructionIdTypeId: | ||
| 3029 | return ir_instruction_typeid_get_dep((IrInstructionTypeId *) instruction, index); | ||
| 3032 | } | 3030 | } |
| 3033 | zig_unreachable(); | 3031 | zig_unreachable(); |
| 3034 | } | 3032 | } |
| ... | @@ -3793,18 +3791,6 @@ static IrInstruction *ir_gen_overflow_op(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -3793,18 +3791,6 @@ static IrInstruction *ir_gen_overflow_op(IrBuilder *irb, Scope *scope, AstNode * |
| 3793 | return ir_build_overflow_op(irb, scope, node, op, type_value, op1, op2, result_ptr, nullptr); | 3791 | return ir_build_overflow_op(irb, scope, node, op, type_value, op1, op2, result_ptr, nullptr); |
| 3794 | } | 3792 | } |
| 3795 | 3793 | ||
| 3796 | static 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 | |||
| 3808 | static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNode *node) { | 3794 | static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNode *node) { |
| 3809 | assert(node->type == NodeTypeFnCallExpr); | 3795 | assert(node->type == NodeTypeFnCallExpr); |
| 3810 | 3796 | ||
| ... | @@ -4217,10 +4203,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4217,10 +4203,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4217 | 4203 | ||
| 4218 | return ir_build_type_name(irb, scope, node, arg0_value); | 4204 | return ir_build_type_name(irb, scope, node, arg0_value); |
| 4219 | } | 4205 | } |
| 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); | ||
| 4224 | case BuiltinFnIdCanImplicitCast: | 4206 | case BuiltinFnIdCanImplicitCast: |
| 4225 | { | 4207 | { |
| 4226 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | 4208 | 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 | ... | @@ -4375,6 +4357,15 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4375 | 4357 | ||
| 4376 | return ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, true); | 4358 | return ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, true); |
| 4377 | } | 4359 | } |
| 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 | } | ||
| 4378 | } | 4369 | } |
| 4379 | zig_unreachable(); | 4370 | zig_unreachable(); |
| 4380 | } | 4371 | } |
| ... | @@ -11865,6 +11856,27 @@ static TypeTableEntry *ir_analyze_instruction_offset_of(IrAnalyze *ira, | ... | @@ -11865,6 +11856,27 @@ static TypeTableEntry *ir_analyze_instruction_offset_of(IrAnalyze *ira, |
| 11865 | return ira->codegen->builtin_types.entry_num_lit_int; | 11856 | return ira->codegen->builtin_types.entry_num_lit_int; |
| 11866 | } | 11857 | } |
| 11867 | 11858 | ||
| 11859 | static 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 | |||
| 11868 | static TypeTableEntry *ir_analyze_instruction_type_name(IrAnalyze *ira, IrInstructionTypeName *instruction) { | 11880 | static TypeTableEntry *ir_analyze_instruction_type_name(IrAnalyze *ira, IrInstructionTypeName *instruction) { |
| 11869 | IrInstruction *type_value = instruction->type_value->other; | 11881 | IrInstruction *type_value = instruction->type_value->other; |
| 11870 | TypeTableEntry *type_entry = ir_resolve_type(ira, type_value); | 11882 | TypeTableEntry *type_entry = ir_resolve_type(ira, type_value); |
| ... | @@ -13025,17 +13037,6 @@ static TypeTableEntry *ir_analyze_instruction_check_statement_is_void(IrAnalyze | ... | @@ -13025,17 +13037,6 @@ static TypeTableEntry *ir_analyze_instruction_check_statement_is_void(IrAnalyze |
| 13025 | return ira->codegen->builtin_types.entry_void; | 13037 | return ira->codegen->builtin_types.entry_void; |
| 13026 | } | 13038 | } |
| 13027 | 13039 | ||
| 13028 | static 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 | |||
| 13039 | static TypeTableEntry *ir_analyze_instruction_can_implicit_cast(IrAnalyze *ira, | 13040 | static TypeTableEntry *ir_analyze_instruction_can_implicit_cast(IrAnalyze *ira, |
| 13040 | IrInstructionCanImplicitCast *instruction) | 13041 | IrInstructionCanImplicitCast *instruction) |
| 13041 | { | 13042 | { |
| ... | @@ -13368,8 +13369,6 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi | ... | @@ -13368,8 +13369,6 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 13368 | return ir_analyze_instruction_check_switch_prongs(ira, (IrInstructionCheckSwitchProngs *)instruction); | 13369 | return ir_analyze_instruction_check_switch_prongs(ira, (IrInstructionCheckSwitchProngs *)instruction); |
| 13369 | case IrInstructionIdCheckStatementIsVoid: | 13370 | case IrInstructionIdCheckStatementIsVoid: |
| 13370 | return ir_analyze_instruction_check_statement_is_void(ira, (IrInstructionCheckStatementIsVoid *)instruction); | 13371 | return ir_analyze_instruction_check_statement_is_void(ira, (IrInstructionCheckStatementIsVoid *)instruction); |
| 13371 | case IrInstructionIdTestType: | ||
| 13372 | return ir_analyze_instruction_test_type(ira, (IrInstructionTestType *)instruction); | ||
| 13373 | case IrInstructionIdCanImplicitCast: | 13372 | case IrInstructionIdCanImplicitCast: |
| 13374 | return ir_analyze_instruction_can_implicit_cast(ira, (IrInstructionCanImplicitCast *)instruction); | 13373 | return ir_analyze_instruction_can_implicit_cast(ira, (IrInstructionCanImplicitCast *)instruction); |
| 13375 | case IrInstructionIdDeclRef: | 13374 | case IrInstructionIdDeclRef: |
| ... | @@ -13386,6 +13385,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi | ... | @@ -13386,6 +13385,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 13386 | return ir_analyze_instruction_field_parent_ptr(ira, (IrInstructionFieldParentPtr *)instruction); | 13385 | return ir_analyze_instruction_field_parent_ptr(ira, (IrInstructionFieldParentPtr *)instruction); |
| 13387 | case IrInstructionIdOffsetOf: | 13386 | case IrInstructionIdOffsetOf: |
| 13388 | return ir_analyze_instruction_offset_of(ira, (IrInstructionOffsetOf *)instruction); | 13387 | return ir_analyze_instruction_offset_of(ira, (IrInstructionOffsetOf *)instruction); |
| 13388 | case IrInstructionIdTypeId: | ||
| 13389 | return ir_analyze_instruction_type_id(ira, (IrInstructionTypeId *)instruction); | ||
| 13389 | case IrInstructionIdMaybeWrap: | 13390 | case IrInstructionIdMaybeWrap: |
| 13390 | case IrInstructionIdErrWrapCode: | 13391 | case IrInstructionIdErrWrapCode: |
| 13391 | case IrInstructionIdErrWrapPayload: | 13392 | case IrInstructionIdErrWrapPayload: |
| ... | @@ -13556,7 +13557,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -13556,7 +13557,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 13556 | case IrInstructionIdIntToEnum: | 13557 | case IrInstructionIdIntToEnum: |
| 13557 | case IrInstructionIdIntToErr: | 13558 | case IrInstructionIdIntToErr: |
| 13558 | case IrInstructionIdErrToInt: | 13559 | case IrInstructionIdErrToInt: |
| 13559 | case IrInstructionIdTestType: | ||
| 13560 | case IrInstructionIdCanImplicitCast: | 13560 | case IrInstructionIdCanImplicitCast: |
| 13561 | case IrInstructionIdDeclRef: | 13561 | case IrInstructionIdDeclRef: |
| 13562 | case IrInstructionIdErrName: | 13562 | case IrInstructionIdErrName: |
| ... | @@ -13564,6 +13564,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -13564,6 +13564,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 13564 | case IrInstructionIdEnumTagName: | 13564 | case IrInstructionIdEnumTagName: |
| 13565 | case IrInstructionIdFieldParentPtr: | 13565 | case IrInstructionIdFieldParentPtr: |
| 13566 | case IrInstructionIdOffsetOf: | 13566 | case IrInstructionIdOffsetOf: |
| 13567 | case IrInstructionIdTypeId: | ||
| 13567 | return false; | 13568 | return false; |
| 13568 | case IrInstructionIdAsm: | 13569 | case IrInstructionIdAsm: |
| 13569 | { | 13570 | { |
src/ir_print.cpp+9-8| ... | @@ -811,11 +811,6 @@ static void ir_print_check_statement_is_void(IrPrint *irp, IrInstructionCheckSta | ... | @@ -811,11 +811,6 @@ static void ir_print_check_statement_is_void(IrPrint *irp, IrInstructionCheckSta |
| 811 | fprintf(irp->f, ")"); | 811 | fprintf(irp->f, ")"); |
| 812 | } | 812 | } |
| 813 | 813 | ||
| 814 | static 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 | |||
| 819 | static void ir_print_type_name(IrPrint *irp, IrInstructionTypeName *instruction) { | 814 | static void ir_print_type_name(IrPrint *irp, IrInstructionTypeName *instruction) { |
| 820 | fprintf(irp->f, "typename "); | 815 | fprintf(irp->f, "typename "); |
| 821 | ir_print_other_instruction(irp, instruction->type_value); | 816 | ir_print_other_instruction(irp, instruction->type_value); |
| ... | @@ -884,6 +879,12 @@ static void ir_print_offset_of(IrPrint *irp, IrInstructionOffsetOf *instruction) | ... | @@ -884,6 +879,12 @@ static void ir_print_offset_of(IrPrint *irp, IrInstructionOffsetOf *instruction) |
| 884 | fprintf(irp->f, ")"); | 879 | fprintf(irp->f, ")"); |
| 885 | } | 880 | } |
| 886 | 881 | ||
| 882 | static 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 | |||
| 887 | static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { | 888 | static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 888 | ir_print_prefix(irp, instruction); | 889 | ir_print_prefix(irp, instruction); |
| 889 | switch (instruction->id) { | 890 | switch (instruction->id) { |
| ... | @@ -1135,9 +1136,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { | ... | @@ -1135,9 +1136,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 1135 | case IrInstructionIdCheckStatementIsVoid: | 1136 | case IrInstructionIdCheckStatementIsVoid: |
| 1136 | ir_print_check_statement_is_void(irp, (IrInstructionCheckStatementIsVoid *)instruction); | 1137 | ir_print_check_statement_is_void(irp, (IrInstructionCheckStatementIsVoid *)instruction); |
| 1137 | break; | 1138 | break; |
| 1138 | case IrInstructionIdTestType: | ||
| 1139 | ir_print_test_type(irp, (IrInstructionTestType *)instruction); | ||
| 1140 | break; | ||
| 1141 | case IrInstructionIdTypeName: | 1139 | case IrInstructionIdTypeName: |
| 1142 | ir_print_type_name(irp, (IrInstructionTypeName *)instruction); | 1140 | ir_print_type_name(irp, (IrInstructionTypeName *)instruction); |
| 1143 | break; | 1141 | break; |
| ... | @@ -1168,6 +1166,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { | ... | @@ -1168,6 +1166,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 1168 | case IrInstructionIdOffsetOf: | 1166 | case IrInstructionIdOffsetOf: |
| 1169 | ir_print_offset_of(irp, (IrInstructionOffsetOf *)instruction); | 1167 | ir_print_offset_of(irp, (IrInstructionOffsetOf *)instruction); |
| 1170 | break; | 1168 | break; |
| 1169 | case IrInstructionIdTypeId: | ||
| 1170 | ir_print_type_id(irp, (IrInstructionTypeId *)instruction); | ||
| 1171 | break; | ||
| 1171 | } | 1172 | } |
| 1172 | fprintf(irp->f, "\n"); | 1173 | fprintf(irp->f, "\n"); |
| 1173 | } | 1174 | } |
std/build.zig+9-9| ... | @@ -488,15 +488,15 @@ pub const Builder = struct { | ... | @@ -488,15 +488,15 @@ pub const Builder = struct { |
| 488 | } | 488 | } |
| 489 | 489 | ||
| 490 | fn typeToEnum(comptime T: type) -> TypeId { | 490 | fn typeToEnum(comptime T: type) -> TypeId { |
| 491 | if (@isInteger(T)) { | 491 | switch (@typeId(T)) { |
| 492 | TypeId.Int | 492 | builtin.TypeId.Int => TypeId.Int, |
| 493 | } else if (@isFloat(T)) { | 493 | builtin.TypeId.Float => TypeId.Float, |
| 494 | TypeId.Float | 494 | builtin.TypeId.Bool => TypeId.Bool, |
| 495 | } else switch (T) { | 495 | else => switch (T) { |
| 496 | bool => TypeId.Bool, | 496 | []const u8 => TypeId.String, |
| 497 | []const u8 => TypeId.String, | 497 | []const []const u8 => TypeId.List, |
| 498 | []const []const u8 => TypeId.List, | 498 | else => @compileError("Unsupported type: " ++ @typeName(T)), |
| 499 | else => @compileError("Unsupported type: " ++ @typeName(T)), | 499 | }, |
| 500 | } | 500 | } |
| 501 | } | 501 | } |
| 502 | 502 |
std/fmt.zig+20-13| ... | @@ -2,6 +2,7 @@ const math = @import("math.zig"); | ... | @@ -2,6 +2,7 @@ const math = @import("math.zig"); |
| 2 | const debug = @import("debug.zig"); | 2 | const debug = @import("debug.zig"); |
| 3 | const assert = debug.assert; | 3 | const assert = debug.assert; |
| 4 | const mem = @import("mem.zig"); | 4 | const mem = @import("mem.zig"); |
| 5 | const builtin = @import("builtin"); | ||
| 5 | 6 | ||
| 6 | const max_f64_digits = 65; | 7 | const max_f64_digits = 65; |
| 7 | const max_int_digits = 65; | 8 | const max_int_digits = 65; |
| ... | @@ -174,19 +175,25 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->bool, | ... | @@ -174,19 +175,25 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->bool, |
| 174 | 175 | ||
| 175 | pub fn formatValue(value: var, context: var, output: fn(@typeOf(context), []const u8)->bool) -> bool { | 176 | pub fn formatValue(value: var, context: var, output: fn(@typeOf(context), []const u8)->bool) -> bool { |
| 176 | const T = @typeOf(value); | 177 | const T = @typeOf(value); |
| 177 | if (@isInteger(T)) { | 178 | switch (@typeId(T)) { |
| 178 | return formatInt(value, 10, false, 0, context, output); | 179 | builtin.TypeId.Int => { |
| 179 | } else if (@isFloat(T)) { | 180 | return formatInt(value, 10, false, 0, context, output); |
| 180 | @compileError("TODO implement formatFloat"); | 181 | }, |
| 181 | } else if (@canImplicitCast([]const u8, value)) { | 182 | builtin.TypeId.Float => { |
| 182 | const casted_value = ([]const u8)(value); | 183 | @compileError("TODO implement formatFloat"); |
| 183 | return output(context, casted_value); | 184 | }, |
| 184 | } else if (T == void) { | 185 | builtin.TypeId.Void => { |
| 185 | return output(context, "void"); | 186 | return output(context, "void"); |
| 186 | } else if (T == bool) { | 187 | }, |
| 187 | return output(context, if (value) "true" else "false"); | 188 | builtin.TypeId.Bool => { |
| 188 | } else { | 189 | return output(context, if (value) "true" else "false"); |
| 189 | @compileError("Unable to format type '" ++ @typeName(T) ++ "'"); | 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 | }, | ||
| 190 | } | 197 | } |
| 191 | } | 198 | } |
| 192 | 199 |
std/math.zig+22-17| ... | @@ -1,4 +1,5 @@ | ... | @@ -1,4 +1,5 @@ |
| 1 | const assert = @import("debug.zig").assert; | 1 | const assert = @import("debug.zig").assert; |
| 2 | const builtin = @import("builtin"); | ||
| 2 | 3 | ||
| 3 | pub const Cmp = enum { | 4 | pub const Cmp = enum { |
| 4 | Less, | 5 | Less, |
| ... | @@ -61,23 +62,27 @@ fn testOverflow() { | ... | @@ -61,23 +62,27 @@ fn testOverflow() { |
| 61 | 62 | ||
| 62 | pub fn log(comptime base: usize, value: var) -> @typeOf(value) { | 63 | pub fn log(comptime base: usize, value: var) -> @typeOf(value) { |
| 63 | const T = @typeOf(value); | 64 | const T = @typeOf(value); |
| 64 | if (@isInteger(T)) { | 65 | switch (@typeId(T)) { |
| 65 | if (base == 2) { | 66 | builtin.TypeId.Int => { |
| 66 | return T.bit_count - 1 - @clz(value); | 67 | if (base == 2) { |
| 67 | } else { | 68 | return T.bit_count - 1 - @clz(value); |
| 68 | @compileError("TODO implement log for non base 2 integers"); | 69 | } else { |
| 69 | } | 70 | @compileError("TODO implement log for non base 2 integers"); |
| 70 | } else if (@isFloat(T)) { | 71 | } |
| 71 | @compileError("TODO implement log for floats"); | 72 | }, |
| 72 | } else { | 73 | builtin.TypeId.Float => { |
| 73 | @compileError("log expects integer or float, found '" ++ @typeName(T) ++ "'"); | 74 | @compileError("TODO implement log for floats"); |
| 75 | }, | ||
| 76 | else => { | ||
| 77 | @compileError("log expects integer or float, found '" ++ @typeName(T) ++ "'"); | ||
| 78 | }, | ||
| 74 | } | 79 | } |
| 75 | } | 80 | } |
| 76 | 81 | ||
| 77 | error Overflow; | 82 | error Overflow; |
| 78 | pub fn absInt(x: var) -> %@typeOf(x) { | 83 | pub fn absInt(x: var) -> %@typeOf(x) { |
| 79 | const T = @typeOf(x); | 84 | 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 |
| 81 | comptime assert(T.is_signed); // must pass a signed integer to absInt | 86 | comptime assert(T.is_signed); // must pass a signed integer to absInt |
| 82 | if (x == @minValue(@typeOf(x))) | 87 | if (x == @minValue(@typeOf(x))) |
| 83 | return error.Overflow; | 88 | return error.Overflow; |
| ... | @@ -97,7 +102,7 @@ fn testAbsInt() { | ... | @@ -97,7 +102,7 @@ fn testAbsInt() { |
| 97 | } | 102 | } |
| 98 | 103 | ||
| 99 | pub fn absFloat(x: var) -> @typeOf(x) { | 104 | pub fn absFloat(x: var) -> @typeOf(x) { |
| 100 | comptime assert(@isFloat(@typeOf(x))); | 105 | comptime assert(@typeId(@typeOf(x)) == builtin.TypeId.Float); |
| 101 | return if (x < 0) -x else x; | 106 | return if (x < 0) -x else x; |
| 102 | } | 107 | } |
| 103 | 108 | ||
| ... | @@ -116,7 +121,7 @@ pub fn divTrunc(comptime T: type, numerator: T, denominator: T) -> %T { | ... | @@ -116,7 +121,7 @@ pub fn divTrunc(comptime T: type, numerator: T, denominator: T) -> %T { |
| 116 | @setDebugSafety(this, false); | 121 | @setDebugSafety(this, false); |
| 117 | if (denominator == 0) | 122 | if (denominator == 0) |
| 118 | return error.DivisionByZero; | 123 | 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) |
| 120 | return error.Overflow; | 125 | return error.Overflow; |
| 121 | return @divTrunc(numerator, denominator); | 126 | return @divTrunc(numerator, denominator); |
| 122 | } | 127 | } |
| ... | @@ -141,7 +146,7 @@ pub fn divFloor(comptime T: type, numerator: T, denominator: T) -> %T { | ... | @@ -141,7 +146,7 @@ pub fn divFloor(comptime T: type, numerator: T, denominator: T) -> %T { |
| 141 | @setDebugSafety(this, false); | 146 | @setDebugSafety(this, false); |
| 142 | if (denominator == 0) | 147 | if (denominator == 0) |
| 143 | return error.DivisionByZero; | 148 | 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) |
| 145 | return error.Overflow; | 150 | return error.Overflow; |
| 146 | return @divFloor(numerator, denominator); | 151 | return @divFloor(numerator, denominator); |
| 147 | } | 152 | } |
| ... | @@ -167,7 +172,7 @@ pub fn divExact(comptime T: type, numerator: T, denominator: T) -> %T { | ... | @@ -167,7 +172,7 @@ pub fn divExact(comptime T: type, numerator: T, denominator: T) -> %T { |
| 167 | @setDebugSafety(this, false); | 172 | @setDebugSafety(this, false); |
| 168 | if (denominator == 0) | 173 | if (denominator == 0) |
| 169 | return error.DivisionByZero; | 174 | 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) |
| 171 | return error.Overflow; | 176 | return error.Overflow; |
| 172 | const result = @divTrunc(numerator, denominator); | 177 | const result = @divTrunc(numerator, denominator); |
| 173 | if (result * denominator != numerator) | 178 | if (result * denominator != numerator) |
| ... | @@ -246,7 +251,7 @@ fn testRem() { | ... | @@ -246,7 +251,7 @@ fn testRem() { |
| 246 | } | 251 | } |
| 247 | 252 | ||
| 248 | fn isNan(comptime T: type, x: T) -> bool { | 253 | fn isNan(comptime T: type, x: T) -> bool { |
| 249 | assert(@isFloat(T)); | 254 | assert(@typeId(T) == builtin.TypeId.Float); |
| 250 | const bits = floatBits(x); | 255 | const bits = floatBits(x); |
| 251 | if (T == f32) { | 256 | if (T == f32) { |
| 252 | return (bits & 0x7fffffff) > 0x7f800000; | 257 | return (bits & 0x7fffffff) > 0x7f800000; |
| ... | @@ -258,7 +263,7 @@ fn isNan(comptime T: type, x: T) -> bool { | ... | @@ -258,7 +263,7 @@ fn isNan(comptime T: type, x: T) -> bool { |
| 258 | } | 263 | } |
| 259 | 264 | ||
| 260 | fn floatBits(comptime T: type, x: T) -> @IntType(false, T.bit_count) { | 265 | fn floatBits(comptime T: type, x: T) -> @IntType(false, T.bit_count) { |
| 261 | assert(@isFloat(T)); | 266 | assert(@typeId(T) == builtin.TypeId.Float); |
| 262 | const uint = @IntType(false, T.bit_count); | 267 | const uint = @IntType(false, T.bit_count); |
| 263 | return *@intToPtr(&const uint, &x); | 268 | return *@intToPtr(&const uint, &x); |
| 264 | } | 269 | } |
test/cases/misc.zig+34-21| ... | @@ -446,29 +446,42 @@ fn testArray2DConstDoublePtr(ptr: &const f32) { | ... | @@ -446,29 +446,42 @@ fn testArray2DConstDoublePtr(ptr: &const f32) { |
| 446 | assert(ptr[1] == 2.0); | 446 | assert(ptr[1] == 2.0); |
| 447 | } | 447 | } |
| 448 | 448 | ||
| 449 | test "@isInteger" { | 449 | const Tid = builtin.TypeId; |
| 450 | comptime { | 450 | const AStruct = struct { x: i32, }; |
| 451 | assert(@isInteger(i8)); | 451 | const AnEnum = enum { One, Two, }; |
| 452 | assert(@isInteger(u8)); | 452 | const AnEnumWithPayload = enum { One: i32, Two, }; |
| 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 | } | ||
| 461 | 453 | ||
| 462 | test "@isFloat" { | 454 | test "@typeId" { |
| 463 | comptime { | 455 | comptime { |
| 464 | assert(!@isFloat(i8)); | 456 | assert(@typeId(type) == Tid.Type); |
| 465 | assert(!@isFloat(u8)); | 457 | assert(@typeId(void) == Tid.Void); |
| 466 | assert(!@isFloat(i64)); | 458 | assert(@typeId(bool) == Tid.Bool); |
| 467 | assert(!@isFloat(u64)); | 459 | assert(@typeId(noreturn) == Tid.NoReturn); |
| 468 | assert(@isFloat(f32)); | 460 | assert(@typeId(i8) == Tid.Int); |
| 469 | assert(@isFloat(f64)); | 461 | assert(@typeId(u8) == Tid.Int); |
| 470 | assert(!@isFloat(bool)); | 462 | assert(@typeId(i64) == Tid.Int); |
| 471 | assert(!@isFloat(&f32)); | 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 | ||
| 472 | } | 485 | } |
| 473 | } | 486 | } |
| 474 | 487 |