authorgravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-04-19 20:11:16+02:00
committergravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-04-19 20:11:16+02:00
log6b4f6ebd89c4788fde09dd5cde17f3cb54c6c656
tree890e2c1ad40f4baee0d5728afe3eecf5685f2ccf
parent06909ceaab8ecb33d1f41049870797a3ae721610

Added field builtin function


5 files changed, 63 insertions(+), 7 deletions(-)

src/all_types.hpp+2-1
......@@ -1292,6 +1292,7 @@ enum BuiltinFnId {
12921292 BuiltinFnIdMemberCount,
12931293 BuiltinFnIdMemberType,
12941294 BuiltinFnIdMemberName,
1295 BuiltinFnIdField,
12951296 BuiltinFnIdTypeof,
12961297 BuiltinFnIdAddWithOverflow,
12971298 BuiltinFnIdSubWithOverflow,
......@@ -2225,7 +2226,7 @@ struct IrInstructionFieldPtr {
22252226 IrInstruction base;
22262227
22272228 IrInstruction *container_ptr;
2228 Buf *field_name;
2229 IrInstruction *field_name_expr;
22292230 bool is_const;
22302231};
22312232
src/codegen.cpp+1-1
......@@ -6114,6 +6114,7 @@ static void define_builtin_fns(CodeGen *g) {
61146114 create_builtin_fn(g, BuiltinFnIdMemberCount, "memberCount", 1);
61156115 create_builtin_fn(g, BuiltinFnIdMemberType, "memberType", 2);
61166116 create_builtin_fn(g, BuiltinFnIdMemberName, "memberName", 2);
6117 create_builtin_fn(g, BuiltinFnIdField, "field", 2);
61176118 create_builtin_fn(g, BuiltinFnIdTypeof, "typeOf", 1); // TODO rename to TypeOf
61186119 create_builtin_fn(g, BuiltinFnIdAddWithOverflow, "addWithOverflow", 4);
61196120 create_builtin_fn(g, BuiltinFnIdSubWithOverflow, "subWithOverflow", 4);
......@@ -7185,4 +7186,3 @@ PackageTableEntry *codegen_create_package(CodeGen *g, const char *root_src_dir,
71857186 }
71867187 return pkg;
71877188}
7188
src/ir.cpp+34-4
......@@ -1033,18 +1033,26 @@ static IrInstruction *ir_build_elem_ptr_from(IrBuilder *irb, IrInstruction *old_
10331033 return new_instruction;
10341034}
10351035
1036static IrInstruction *ir_build_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,
1037 IrInstruction *container_ptr, Buf *field_name)
1036static IrInstruction *ir_build_field_ptr_inner(IrBuilder *irb, Scope *scope, AstNode *source_node,
1037 IrInstruction *container_ptr, IrInstruction *field_name_expr)
10381038{
10391039 IrInstructionFieldPtr *instruction = ir_build_instruction<IrInstructionFieldPtr>(irb, scope, source_node);
10401040 instruction->container_ptr = container_ptr;
1041 instruction->field_name = field_name;
1041 instruction->field_name_expr = field_name_expr;
10421042
10431043 ir_ref_instruction(container_ptr, irb->current_basic_block);
1044 ir_ref_instruction(field_name_expr, irb->current_basic_block);
10441045
10451046 return &instruction->base;
10461047}
10471048
1049static IrInstruction *ir_build_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,
1050 IrInstruction *container_ptr, Buf *field_name)
1051{
1052 IrInstruction *field_name_expr = ir_build_const_str_lit(irb, scope, source_node, field_name);
1053 return ir_build_field_ptr_inner(irb, scope, source_node, container_ptr, field_name_expr);
1054}
1055
10481056static IrInstruction *ir_build_struct_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,
10491057 IrInstruction *struct_ptr, TypeStructField *field)
10501058{
......@@ -4015,6 +4023,24 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
40154023
40164024 return ir_build_member_name(irb, scope, node, arg0_value, arg1_value);
40174025 }
4026 case BuiltinFnIdField:
4027 {
4028 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4029 IrInstruction *arg0_value = ir_gen_node_extra(irb, arg0_node, scope, LVAL_PTR);
4030 if (arg0_value == irb->codegen->invalid_instruction)
4031 return arg0_value;
4032
4033 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4034 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);
4035 if (arg1_value == irb->codegen->invalid_instruction)
4036 return arg1_value;
4037
4038 IrInstruction *ptr_instruction = ir_build_field_ptr_inner(irb, scope, node, arg0_value, arg1_value);
4039 //if (lval.is_ptr)
4040 // return ptr_instruction;
4041
4042 return ir_build_load_ptr(irb, scope, node, ptr_instruction);
4043 }
40184044 case BuiltinFnIdBreakpoint:
40194045 return ir_build_breakpoint(irb, scope, node);
40204046 case BuiltinFnIdReturnAddress:
......@@ -13458,7 +13484,11 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
1345813484 zig_unreachable();
1345913485 }
1346013486
13461 Buf *field_name = field_ptr_instruction->field_name;
13487 IrInstruction *field_name_expr = field_ptr_instruction->field_name_expr->other;
13488 Buf *field_name = ir_resolve_str(ira, field_name_expr);
13489 if (!field_name)
13490 return ira->codegen->builtin_types.entry_invalid;
13491
1346213492 AstNode *source_node = field_ptr_instruction->base.source_node;
1346313493
1346413494 if (type_is_invalid(container_type)) {
src/ir_print.cpp+2-1
......@@ -360,7 +360,8 @@ static void ir_print_ptr_type_child(IrPrint *irp, IrInstructionPtrTypeChild *ins
360360static void ir_print_field_ptr(IrPrint *irp, IrInstructionFieldPtr *instruction) {
361361 fprintf(irp->f, "fieldptr ");
362362 ir_print_other_instruction(irp, instruction->container_ptr);
363 fprintf(irp->f, ".%s", buf_ptr(instruction->field_name));
363 fprintf(irp->f, ".");
364 ir_print_other_instruction(irp, instruction->field_name_expr);
364365}
365366
366367static void ir_print_struct_field_ptr(IrPrint *irp, IrInstructionStructFieldPtr *instruction) {
test/cases/reflection.zig+24
......@@ -1,5 +1,6 @@
11const assert = @import("std").debug.assert;
22const mem = @import("std").mem;
3const reflection = this;
34
45test "reflection: array, pointer, nullable, error union type child" {
56 comptime {
......@@ -56,7 +57,30 @@ test "reflection: enum member types and names" {
5657
5758}
5859
60test "reflection: @field" {
61 const f = Foo {
62 .one = 42,
63 .two = true,
64 .three = void{},
65 };
66
67 assert(f.one == f.one);
68 assert(@field(f, "o" ++ "ne") == f.one);
69 assert(@field(f, "t" ++ "wo") == f.two);
70 assert(@field(f, "th" ++ "ree") == f.three);
71 assert(@field(Foo, "const" ++ "ant") == Foo.constant);
72 assert(@field(Bar, "O" ++ "ne") == Bar.One);
73 assert(@field(Bar, "O" ++ "ne") == Bar.One);
74 assert(@field(Bar, "O" ++ "ne") == Bar.One);
75 assert(@field(Bar, "T" ++ "wo") == Bar.Two);
76 assert(@field(Bar, "Th" ++ "ree") == Bar.Three);
77 assert(@field(Bar, "F" ++ "our") == Bar.Four);
78 assert(@field(reflection, "dum" ++ "my")(true, 1, 2) == dummy(true, 1, 2));
79}
80
5981const Foo = struct {
82 const constant = 52;
83
6084 one: i32,
6185 two: bool,
6286 three: void,