Skip to content

Commit a31b23c

Browse files
committedNov 3, 2017
more compile-time type reflection
See #383
1 parent dc8b011 commit a31b23c

File tree

4 files changed

+81
-6
lines changed

4 files changed

+81
-6
lines changed
 

‎src-self-hosted/main.zig

+9-6
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,28 @@ const io = @import("std").io;
33
const os = @import("std").os;
44
const heap = @import("std").mem;
55

6-
// TODO: OutSteam and InStream interface
7-
// TODO: move allocator to heap namespace
86
// TODO: sync up CLI with c++ code
7+
// TODO: concurrency
8+
// TODO: ability to iterate over enums at compile time (for listing targets)
99

1010
error InvalidArgument;
1111
error MissingArg0;
1212

1313
var arg0: []u8 = undefined;
1414

15+
var stderr_file: io.File = undefined;
16+
const stderr = &stderr_file.out_stream;
17+
1518
pub fn main() -> %void {
19+
stderr_file = %return io.getStdErr();
1620
if (internal_main()) |_| {
1721
return;
1822
} else |err| {
1923
if (err == error.InvalidArgument) {
20-
io.stderr.printf("\n") %% return err;
21-
printUsage(&io.stderr) %% return err;
24+
stderr.print("\n") %% return err;
25+
printUsage(stderr) %% return err;
2226
} else {
23-
io.stderr.printf("{}\n", err) %% return err;
27+
stderr.print("{}\n", err) %% return err;
2428
}
2529
return err;
2630
}
@@ -266,7 +270,6 @@ fn printUsage(outstream: &io.OutStream) -> %void {
266270
\\ --test-cmd-bin appends test binary path to test cmd args
267271
\\
268272
);
269-
%return outstream.flush();
270273
}
271274

272275
const ZIG_ZEN =

‎src/ir.cpp

+49
Original file line numberDiff line numberDiff line change
@@ -11643,6 +11643,55 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
1164311643
buf_ptr(&child_type->name), buf_ptr(field_name)));
1164411644
return ira->codegen->builtin_types.entry_invalid;
1164511645
}
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+
}
1164611695
} else {
1164711696
ir_add_error(ira, &field_ptr_instruction->base,
1164811697
buf_sprintf("type '%s' does not support field access", buf_ptr(&child_type->name)));

‎test/behavior.zig

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ comptime {
2929
_ = @import("cases/null.zig");
3030
_ = @import("cases/pub_enum/index.zig");
3131
_ = @import("cases/ref_var_in_if_after_if_2nd_switch_prong.zig");
32+
_ = @import("cases/reflection.zig");
3233
_ = @import("cases/sizeof_and_typeof.zig");
3334
_ = @import("cases/slice.zig");
3435
_ = @import("cases/struct.zig");

‎test/cases/reflection.zig

+22
Original file line numberDiff line numberDiff line change
@@ -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: ...) {}

0 commit comments

Comments
 (0)
Please sign in to comment.