| author | |
| committer | |
| log | a31b23c46ba2a8c28df01adc1aa0b4d878b9a5cf |
| tree | b9f978f1c930a4c251e876ea850b380de13bfa4b |
| parent | dc8b011d616991da166ad83795bf0b7e90471bd3 |
See #3834 files changed, 81 insertions(+), 6 deletions(-)
src-self-hosted/main.zig+9-6| ... | @@ -3,24 +3,28 @@ const io = @import("std").io; | ... | @@ -3,24 +3,28 @@ const io = @import("std").io; |
| 3 | const os = @import("std").os; | 3 | const os = @import("std").os; |
| 4 | const heap = @import("std").mem; | 4 | const heap = @import("std").mem; |
| 5 | 5 | ||
| 6 | // TODO: OutSteam and InStream interface | ||
| 7 | // TODO: move allocator to heap namespace | ||
| 8 | // TODO: sync up CLI with c++ code | 6 | // TODO: sync up CLI with c++ code |
| 7 | // TODO: concurrency | ||
| 8 | // TODO: ability to iterate over enums at compile time (for listing targets) | ||
| 9 | 9 | ||
| 10 | error InvalidArgument; | 10 | error InvalidArgument; |
| 11 | error MissingArg0; | 11 | error MissingArg0; |
| 12 | 12 | ||
| 13 | var arg0: []u8 = undefined; | 13 | var arg0: []u8 = undefined; |
| 14 | 14 | ||
| 15 | var stderr_file: io.File = undefined; | ||
| 16 | const stderr = &stderr_file.out_stream; | ||
| 17 | |||
| 15 | pub fn main() -> %void { | 18 | pub fn main() -> %void { |
| 19 | stderr_file = %return io.getStdErr(); | ||
| 16 | if (internal_main()) |_| { | 20 | if (internal_main()) |_| { |
| 17 | return; | 21 | return; |
| 18 | } else |err| { | 22 | } else |err| { |
| 19 | if (err == error.InvalidArgument) { | 23 | if (err == error.InvalidArgument) { |
| 20 | io.stderr.printf("\n") %% return err; | 24 | stderr.print("\n") %% return err; |
| 21 | printUsage(&io.stderr) %% return err; | 25 | printUsage(stderr) %% return err; |
| 22 | } else { | 26 | } else { |
| 23 | io.stderr.printf("{}\n", err) %% return err; | 27 | stderr.print("{}\n", err) %% return err; |
| 24 | } | 28 | } |
| 25 | return err; | 29 | return err; |
| 26 | } | 30 | } |
| ... | @@ -266,7 +270,6 @@ fn printUsage(outstream: &io.OutStream) -> %void { | ... | @@ -266,7 +270,6 @@ fn printUsage(outstream: &io.OutStream) -> %void { |
| 266 | \\ --test-cmd-bin appends test binary path to test cmd args | 270 | \\ --test-cmd-bin appends test binary path to test cmd args |
| 267 | \\ | 271 | \\ |
| 268 | ); | 272 | ); |
| 269 | %return outstream.flush(); | ||
| 270 | } | 273 | } |
| 271 | 274 | ||
| 272 | const ZIG_ZEN = | 275 | const ZIG_ZEN = |
src/ir.cpp+49| ... | @@ -11643,6 +11643,55 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru | ... | @@ -11643,6 +11643,55 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru |
| 11643 | buf_ptr(&child_type->name), buf_ptr(field_name))); | 11643 | buf_ptr(&child_type->name), buf_ptr(field_name))); |
| 11644 | return ira->codegen->builtin_types.entry_invalid; | 11644 | return ira->codegen->builtin_types.entry_invalid; |
| 11645 | } | 11645 | } |
| 11646 | } else if (child_type->id == TypeTableEntryIdErrorUnion) { | ||
| 11647 | if (buf_eql_str(field_name, "Child")) { | ||
| 11648 | bool ptr_is_const = true; | ||
| 11649 | bool ptr_is_volatile = false; | ||
| 11650 | return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, | ||
| 11651 | create_const_type(ira->codegen, child_type->data.error.child_type), | ||
| 11652 | ira->codegen->builtin_types.entry_type, | ||
| 11653 | ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile); | ||
| 11654 | } else { | ||
| 11655 | ir_add_error(ira, &field_ptr_instruction->base, | ||
| 11656 | buf_sprintf("type '%s' has no member called '%s'", | ||
| 11657 | buf_ptr(&child_type->name), buf_ptr(field_name))); | ||
| 11658 | return ira->codegen->builtin_types.entry_invalid; | ||
| 11659 | } | ||
| 11660 | } else if (child_type->id == TypeTableEntryIdMaybe) { | ||
| 11661 | if (buf_eql_str(field_name, "Child")) { | ||
| 11662 | bool ptr_is_const = true; | ||
| 11663 | bool ptr_is_volatile = false; | ||
| 11664 | return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, | ||
| 11665 | create_const_type(ira->codegen, child_type->data.maybe.child_type), | ||
| 11666 | ira->codegen->builtin_types.entry_type, | ||
| 11667 | ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile); | ||
| 11668 | } else { | ||
| 11669 | ir_add_error(ira, &field_ptr_instruction->base, | ||
| 11670 | buf_sprintf("type '%s' has no member called '%s'", | ||
| 11671 | buf_ptr(&child_type->name), buf_ptr(field_name))); | ||
| 11672 | return ira->codegen->builtin_types.entry_invalid; | ||
| 11673 | } | ||
| 11674 | } else if (child_type->id == TypeTableEntryIdFn) { | ||
| 11675 | if (buf_eql_str(field_name, "ReturnType")) { | ||
| 11676 | bool ptr_is_const = true; | ||
| 11677 | bool ptr_is_volatile = false; | ||
| 11678 | return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, | ||
| 11679 | create_const_type(ira->codegen, child_type->data.fn.fn_type_id.return_type), | ||
| 11680 | ira->codegen->builtin_types.entry_type, | ||
| 11681 | ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile); | ||
| 11682 | } else if (buf_eql_str(field_name, "is_var_args")) { | ||
| 11683 | bool ptr_is_const = true; | ||
| 11684 | bool ptr_is_volatile = false; | ||
| 11685 | return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, | ||
| 11686 | create_const_bool(ira->codegen, child_type->data.fn.fn_type_id.is_var_args), | ||
| 11687 | ira->codegen->builtin_types.entry_bool, | ||
| 11688 | ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile); | ||
| 11689 | } else { | ||
| 11690 | ir_add_error(ira, &field_ptr_instruction->base, | ||
| 11691 | buf_sprintf("type '%s' has no member called '%s'", | ||
| 11692 | buf_ptr(&child_type->name), buf_ptr(field_name))); | ||
| 11693 | return ira->codegen->builtin_types.entry_invalid; | ||
| 11694 | } | ||
| 11646 | } else { | 11695 | } else { |
| 11647 | ir_add_error(ira, &field_ptr_instruction->base, | 11696 | ir_add_error(ira, &field_ptr_instruction->base, |
| 11648 | buf_sprintf("type '%s' does not support field access", buf_ptr(&child_type->name))); | 11697 | buf_sprintf("type '%s' does not support field access", buf_ptr(&child_type->name))); |
test/behavior.zig+1| ... | @@ -29,6 +29,7 @@ comptime { | ... | @@ -29,6 +29,7 @@ comptime { |
| 29 | _ = @import("cases/null.zig"); | 29 | _ = @import("cases/null.zig"); |
| 30 | _ = @import("cases/pub_enum/index.zig"); | 30 | _ = @import("cases/pub_enum/index.zig"); |
| 31 | _ = @import("cases/ref_var_in_if_after_if_2nd_switch_prong.zig"); | 31 | _ = @import("cases/ref_var_in_if_after_if_2nd_switch_prong.zig"); |
| 32 | _ = @import("cases/reflection.zig"); | ||
| 32 | _ = @import("cases/sizeof_and_typeof.zig"); | 33 | _ = @import("cases/sizeof_and_typeof.zig"); |
| 33 | _ = @import("cases/slice.zig"); | 34 | _ = @import("cases/slice.zig"); |
| 34 | _ = @import("cases/struct.zig"); | 35 | _ = @import("cases/struct.zig"); |
test/cases/reflection.zig created+22| ... | @@ -0,0 +1,22 @@ | ||
| 1 | const assert = @import("std").debug.assert; | ||
| 2 | const mem = @import("std").mem; | ||
| 3 | |||
| 4 | test "reflection: array, pointer, nullable, error union type child" { | ||
| 5 | comptime { | ||
| 6 | assert(([10]u8).Child == u8); | ||
| 7 | assert((&u8).Child == u8); | ||
| 8 | assert((%u8).Child == u8); | ||
| 9 | assert((?u8).Child == u8); | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | test "reflection: function return type and var args" { | ||
| 14 | comptime { | ||
| 15 | assert(@typeOf(dummy).ReturnType == i32); | ||
| 16 | assert(!@typeOf(dummy).is_var_args); | ||
| 17 | assert(@typeOf(dummy_varargs).is_var_args); | ||
| 18 | } | ||
| 19 | } | ||
| 20 | |||
| 21 | fn dummy() -> i32 { 1234 } | ||
| 22 | fn dummy_varargs(args: ...) {} | ||