| author | |
| committer | |
| log | aa56f016f73063371431b8b2587538c79af97bd9 |
| tree | 30ab1eecc5161a9cf60971735537c29af484b187 |
| parent | 5a8822c714e4ee2d442e76f36213d119530f0fea |
6 files changed, 52 insertions(+), 9 deletions(-)
example/structs/structs.zig+13-2| ... | ... | @@ -11,6 +11,13 @@ export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { |
| 11 | 11 | |
| 12 | 12 | test_foo(foo); |
| 13 | 13 | |
| 14 | modify_foo(&foo); | |
| 15 | ||
| 16 | if foo.c != 100 { | |
| 17 | print_str("BAD\n"); | |
| 18 | } | |
| 19 | ||
| 20 | print_str("OK\n"); | |
| 14 | 21 | return 0; |
| 15 | 22 | } |
| 16 | 23 | |
| ... | ... | @@ -21,7 +28,11 @@ struct Foo { |
| 21 | 28 | } |
| 22 | 29 | |
| 23 | 30 | fn test_foo(foo : Foo) { |
| 24 | if foo.b { | |
| 25 | print_str("OK\n" as string); | |
| 31 | if !foo.b { | |
| 32 | print_str("BAD\n"); | |
| 26 | 33 | } |
| 27 | 34 | } |
| 35 | ||
| 36 | fn modify_foo(foo : &Foo) { | |
| 37 | foo.c = 100; | |
| 38 | } |
src/analyze.cpp+14-2| ... | ... | @@ -116,6 +116,9 @@ TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool |
| 116 | 116 | entry->align_in_bits = g->pointer_size_bytes * 8; |
| 117 | 117 | entry->di_type = LLVMZigCreateDebugPointerType(g->dbuilder, child_type->di_type, |
| 118 | 118 | entry->size_in_bits, entry->align_in_bits, buf_ptr(&entry->name)); |
| 119 | entry->data.pointer.child_type = child_type; | |
| 120 | entry->data.pointer.is_const = is_const; | |
| 121 | ||
| 119 | 122 | g->type_table.put(&entry->name, entry); |
| 120 | 123 | *parent_pointer = entry; |
| 121 | 124 | return entry; |
| ... | ... | @@ -575,6 +578,10 @@ static bool num_lit_fits_in_other_type(CodeGen *g, TypeTableEntry *literal_type, |
| 575 | 578 | case TypeTableEntryIdFloat: |
| 576 | 579 | if (is_num_lit_float(num_lit)) { |
| 577 | 580 | return lit_size_in_bits <= other_type->size_in_bits; |
| 581 | } else if (other_type->size_in_bits == 32) { | |
| 582 | return lit_size_in_bits < 24; | |
| 583 | } else if (other_type->size_in_bits == 64) { | |
| 584 | return lit_size_in_bits < 53; | |
| 578 | 585 | } else { |
| 579 | 586 | return false; |
| 580 | 587 | } |
| ... | ... | @@ -810,14 +817,19 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i |
| 810 | 817 | |
| 811 | 818 | TypeTableEntry *return_type; |
| 812 | 819 | |
| 813 | if (struct_type->id == TypeTableEntryIdStruct) { | |
| 820 | if (struct_type->id == TypeTableEntryIdStruct || (struct_type->id == TypeTableEntryIdPointer && | |
| 821 | struct_type->data.pointer.child_type->id == TypeTableEntryIdStruct)) | |
| 822 | { | |
| 814 | 823 | assert(node->codegen_node); |
| 815 | 824 | FieldAccessNode *codegen_field_access = &node->codegen_node->data.field_access_node; |
| 816 | 825 | assert(codegen_field_access); |
| 817 | 826 | |
| 818 | 827 | Buf *field_name = &node->data.field_access_expr.field_name; |
| 819 | 828 | |
| 820 | get_struct_field(struct_type, field_name, | |
| 829 | TypeTableEntry *bare_struct_type = (struct_type->id == TypeTableEntryIdStruct) ? | |
| 830 | struct_type : struct_type->data.pointer.child_type; | |
| 831 | ||
| 832 | get_struct_field(bare_struct_type, field_name, | |
| 821 | 833 | &codegen_field_access->type_struct_field, |
| 822 | 834 | &codegen_field_access->field_index); |
| 823 | 835 | if (codegen_field_access->type_struct_field) { |
src/analyze.hpp+2-2| ... | ... | @@ -20,8 +20,8 @@ struct VariableTableEntry; |
| 20 | 20 | struct CastNode; |
| 21 | 21 | |
| 22 | 22 | struct TypeTableEntryPointer { |
| 23 | TypeTableEntry *pointer_child; | |
| 24 | bool pointer_is_const; | |
| 23 | TypeTableEntry *child_type; | |
| 24 | bool is_const; | |
| 25 | 25 | }; |
| 26 | 26 | |
| 27 | 27 | struct TypeTableEntryInt { |
src/codegen.cpp+2| ... | ... | @@ -248,6 +248,8 @@ static LLVMValueRef gen_field_access_expr(CodeGen *g, AstNode *node) { |
| 248 | 248 | TypeTableEntry *type_entry; |
| 249 | 249 | LLVMValueRef ptr = gen_field_ptr(g, node, &type_entry); |
| 250 | 250 | return LLVMBuildLoad(g->builder, ptr, ""); |
| 251 | } else if (struct_type->id == TypeTableEntryIdPointer) { | |
| 252 | zig_panic("TODO struct pointer access"); | |
| 251 | 253 | } else { |
| 252 | 254 | zig_panic("gen_field_access_expr bad struct type"); |
| 253 | 255 | } |
src/parser.cpp+11-1| ... | ... | @@ -1153,12 +1153,13 @@ static PrefixOp tok_to_prefix_op(Token *token) { |
| 1153 | 1153 | case TokenIdBang: return PrefixOpBoolNot; |
| 1154 | 1154 | case TokenIdDash: return PrefixOpNegation; |
| 1155 | 1155 | case TokenIdTilde: return PrefixOpBinNot; |
| 1156 | case TokenIdAmpersand: return PrefixOpAddressOf; | |
| 1156 | 1157 | default: return PrefixOpInvalid; |
| 1157 | 1158 | } |
| 1158 | 1159 | } |
| 1159 | 1160 | |
| 1160 | 1161 | /* |
| 1161 | PrefixOp : token(Not) | token(Dash) | token(Tilde) | |
| 1162 | PrefixOp : token(Not) | token(Dash) | token(Tilde) | (token(Ampersand) option(token(Const))) | |
| 1162 | 1163 | */ |
| 1163 | 1164 | static PrefixOp ast_parse_prefix_op(ParseContext *pc, int *token_index, bool mandatory) { |
| 1164 | 1165 | Token *token = &pc->tokens->at(*token_index); |
| ... | ... | @@ -1171,6 +1172,15 @@ static PrefixOp ast_parse_prefix_op(ParseContext *pc, int *token_index, bool man |
| 1171 | 1172 | } |
| 1172 | 1173 | } |
| 1173 | 1174 | *token_index += 1; |
| 1175 | ||
| 1176 | if (result == PrefixOpAddressOf) { | |
| 1177 | Token *token = &pc->tokens->at(*token_index); | |
| 1178 | if (token->id == TokenIdKeywordConst) { | |
| 1179 | *token_index += 1; | |
| 1180 | result = PrefixOpConstAddressOf; | |
| 1181 | } | |
| 1182 | } | |
| 1183 | ||
| 1174 | 1184 | return result; |
| 1175 | 1185 | } |
| 1176 | 1186 |
test/run_tests.cpp+10-2| ... | ... | @@ -569,6 +569,11 @@ export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { |
| 569 | 569 | foo.a += 1; |
| 570 | 570 | foo.b = foo.a == 1; |
| 571 | 571 | test_foo(foo); |
| 572 | test_mutation(&foo); | |
| 573 | if foo.c != 100 { | |
| 574 | print_str("BAD\n"); | |
| 575 | } | |
| 576 | print_str("OK\n"); | |
| 572 | 577 | return 0; |
| 573 | 578 | } |
| 574 | 579 | struct Foo { |
| ... | ... | @@ -577,9 +582,12 @@ struct Foo { |
| 577 | 582 | c : f32, |
| 578 | 583 | } |
| 579 | 584 | fn test_foo(foo : Foo) { |
| 580 | if foo.b { | |
| 581 | print_str("OK\n"); | |
| 585 | if !foo.b { | |
| 586 | print_str("BAD\n"); | |
| 582 | 587 | } |
| 588 | } | |
| 589 | fn test_mutation(foo : &Foo) { | |
| 590 | foo.c = 100; | |
| 583 | 591 | } |
| 584 | 592 | )SOURCE", "OK\n"); |
| 585 | 593 |