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 {...@@ -1292,6 +1292,7 @@ enum BuiltinFnId {
1292 BuiltinFnIdMemberCount,1292 BuiltinFnIdMemberCount,
1293 BuiltinFnIdMemberType,1293 BuiltinFnIdMemberType,
1294 BuiltinFnIdMemberName,1294 BuiltinFnIdMemberName,
1295 BuiltinFnIdField,
1295 BuiltinFnIdTypeof,1296 BuiltinFnIdTypeof,
1296 BuiltinFnIdAddWithOverflow,1297 BuiltinFnIdAddWithOverflow,
1297 BuiltinFnIdSubWithOverflow,1298 BuiltinFnIdSubWithOverflow,
...@@ -2225,7 +2226,7 @@ struct IrInstructionFieldPtr {...@@ -2225,7 +2226,7 @@ struct IrInstructionFieldPtr {
2225 IrInstruction base;2226 IrInstruction base;
22262227
2227 IrInstruction *container_ptr;2228 IrInstruction *container_ptr;
2228 Buf *field_name;2229 IrInstruction *field_name_expr;
2229 bool is_const;2230 bool is_const;
2230};2231};
22312232
src/codegen.cpp+1-1
...@@ -6114,6 +6114,7 @@ static void define_builtin_fns(CodeGen *g) {...@@ -6114,6 +6114,7 @@ static void define_builtin_fns(CodeGen *g) {
6114 create_builtin_fn(g, BuiltinFnIdMemberCount, "memberCount", 1);6114 create_builtin_fn(g, BuiltinFnIdMemberCount, "memberCount", 1);
6115 create_builtin_fn(g, BuiltinFnIdMemberType, "memberType", 2);6115 create_builtin_fn(g, BuiltinFnIdMemberType, "memberType", 2);
6116 create_builtin_fn(g, BuiltinFnIdMemberName, "memberName", 2);6116 create_builtin_fn(g, BuiltinFnIdMemberName, "memberName", 2);
6117 create_builtin_fn(g, BuiltinFnIdField, "field", 2);
6117 create_builtin_fn(g, BuiltinFnIdTypeof, "typeOf", 1); // TODO rename to TypeOf6118 create_builtin_fn(g, BuiltinFnIdTypeof, "typeOf", 1); // TODO rename to TypeOf
6118 create_builtin_fn(g, BuiltinFnIdAddWithOverflow, "addWithOverflow", 4);6119 create_builtin_fn(g, BuiltinFnIdAddWithOverflow, "addWithOverflow", 4);
6119 create_builtin_fn(g, BuiltinFnIdSubWithOverflow, "subWithOverflow", 4);6120 create_builtin_fn(g, BuiltinFnIdSubWithOverflow, "subWithOverflow", 4);
...@@ -7185,4 +7186,3 @@ PackageTableEntry *codegen_create_package(CodeGen *g, const char *root_src_dir,...@@ -7185,4 +7186,3 @@ PackageTableEntry *codegen_create_package(CodeGen *g, const char *root_src_dir,
7185 }7186 }
7186 return pkg;7187 return pkg;
7187}7188}
7188
src/ir.cpp+34-4
...@@ -1033,18 +1033,26 @@ static IrInstruction *ir_build_elem_ptr_from(IrBuilder *irb, IrInstruction *old_...@@ -1033,18 +1033,26 @@ static IrInstruction *ir_build_elem_ptr_from(IrBuilder *irb, IrInstruction *old_
1033 return new_instruction;1033 return new_instruction;
1034}1034}
10351035
1036static IrInstruction *ir_build_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,1036static IrInstruction *ir_build_field_ptr_inner(IrBuilder *irb, Scope *scope, AstNode *source_node,
1037 IrInstruction *container_ptr, Buf *field_name)1037 IrInstruction *container_ptr, IrInstruction *field_name_expr)
1038{1038{
1039 IrInstructionFieldPtr *instruction = ir_build_instruction<IrInstructionFieldPtr>(irb, scope, source_node);1039 IrInstructionFieldPtr *instruction = ir_build_instruction<IrInstructionFieldPtr>(irb, scope, source_node);
1040 instruction->container_ptr = container_ptr;1040 instruction->container_ptr = container_ptr;
1041 instruction->field_name = field_name;1041 instruction->field_name_expr = field_name_expr;
10421042
1043 ir_ref_instruction(container_ptr, irb->current_basic_block);1043 ir_ref_instruction(container_ptr, irb->current_basic_block);
1044 ir_ref_instruction(field_name_expr, irb->current_basic_block);
10441045
1045 return &instruction->base;1046 return &instruction->base;
1046}1047}
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
1048static IrInstruction *ir_build_struct_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,1056static IrInstruction *ir_build_struct_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,
1049 IrInstruction *struct_ptr, TypeStructField *field)1057 IrInstruction *struct_ptr, TypeStructField *field)
1050{1058{
...@@ -4015,6 +4023,24 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4015,6 +4023,24 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
40154023
4016 return ir_build_member_name(irb, scope, node, arg0_value, arg1_value);4024 return ir_build_member_name(irb, scope, node, arg0_value, arg1_value);
4017 }4025 }
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 }
4018 case BuiltinFnIdBreakpoint:4044 case BuiltinFnIdBreakpoint:
4019 return ir_build_breakpoint(irb, scope, node);4045 return ir_build_breakpoint(irb, scope, node);
4020 case BuiltinFnIdReturnAddress:4046 case BuiltinFnIdReturnAddress:
...@@ -13458,7 +13484,11 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru...@@ -13458,7 +13484,11 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
13458 zig_unreachable();13484 zig_unreachable();
13459 }13485 }
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
13462 AstNode *source_node = field_ptr_instruction->base.source_node;13492 AstNode *source_node = field_ptr_instruction->base.source_node;
1346313493
13464 if (type_is_invalid(container_type)) {13494 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...@@ -360,7 +360,8 @@ static void ir_print_ptr_type_child(IrPrint *irp, IrInstructionPtrTypeChild *ins
360static void ir_print_field_ptr(IrPrint *irp, IrInstructionFieldPtr *instruction) {360static void ir_print_field_ptr(IrPrint *irp, IrInstructionFieldPtr *instruction) {
361 fprintf(irp->f, "fieldptr ");361 fprintf(irp->f, "fieldptr ");
362 ir_print_other_instruction(irp, instruction->container_ptr);362 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);
364}365}
365366
366static void ir_print_struct_field_ptr(IrPrint *irp, IrInstructionStructFieldPtr *instruction) {367static void ir_print_struct_field_ptr(IrPrint *irp, IrInstructionStructFieldPtr *instruction) {
test/cases/reflection.zig+24
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1const assert = @import("std").debug.assert;1const assert = @import("std").debug.assert;
2const mem = @import("std").mem;2const mem = @import("std").mem;
3const reflection = this;
34
4test "reflection: array, pointer, nullable, error union type child" {5test "reflection: array, pointer, nullable, error union type child" {
5 comptime {6 comptime {
...@@ -56,7 +57,30 @@ test "reflection: enum member types and names" {...@@ -56,7 +57,30 @@ test "reflection: enum member types and names" {
5657
57}58}
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
59const Foo = struct {81const Foo = struct {
82 const constant = 52;
83
60 one: i32,84 one: i32,
61 two: bool,85 two: bool,
62 three: void,86 three: void,