Commit aa56f016f7
Changed files (6)
example/structs/structs.zig
@@ -11,6 +11,13 @@ export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 {
test_foo(foo);
+ modify_foo(&foo);
+
+ if foo.c != 100 {
+ print_str("BAD\n");
+ }
+
+ print_str("OK\n");
return 0;
}
@@ -21,7 +28,11 @@ struct Foo {
}
fn test_foo(foo : Foo) {
- if foo.b {
- print_str("OK\n" as string);
+ if !foo.b {
+ print_str("BAD\n");
}
}
+
+fn modify_foo(foo : &Foo) {
+ foo.c = 100;
+}
src/analyze.cpp
@@ -116,6 +116,9 @@ TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool
entry->align_in_bits = g->pointer_size_bytes * 8;
entry->di_type = LLVMZigCreateDebugPointerType(g->dbuilder, child_type->di_type,
entry->size_in_bits, entry->align_in_bits, buf_ptr(&entry->name));
+ entry->data.pointer.child_type = child_type;
+ entry->data.pointer.is_const = is_const;
+
g->type_table.put(&entry->name, entry);
*parent_pointer = entry;
return entry;
@@ -575,6 +578,10 @@ static bool num_lit_fits_in_other_type(CodeGen *g, TypeTableEntry *literal_type,
case TypeTableEntryIdFloat:
if (is_num_lit_float(num_lit)) {
return lit_size_in_bits <= other_type->size_in_bits;
+ } else if (other_type->size_in_bits == 32) {
+ return lit_size_in_bits < 24;
+ } else if (other_type->size_in_bits == 64) {
+ return lit_size_in_bits < 53;
} else {
return false;
}
@@ -810,14 +817,19 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i
TypeTableEntry *return_type;
- if (struct_type->id == TypeTableEntryIdStruct) {
+ if (struct_type->id == TypeTableEntryIdStruct || (struct_type->id == TypeTableEntryIdPointer &&
+ struct_type->data.pointer.child_type->id == TypeTableEntryIdStruct))
+ {
assert(node->codegen_node);
FieldAccessNode *codegen_field_access = &node->codegen_node->data.field_access_node;
assert(codegen_field_access);
Buf *field_name = &node->data.field_access_expr.field_name;
- get_struct_field(struct_type, field_name,
+ TypeTableEntry *bare_struct_type = (struct_type->id == TypeTableEntryIdStruct) ?
+ struct_type : struct_type->data.pointer.child_type;
+
+ get_struct_field(bare_struct_type, field_name,
&codegen_field_access->type_struct_field,
&codegen_field_access->field_index);
if (codegen_field_access->type_struct_field) {
src/analyze.hpp
@@ -20,8 +20,8 @@ struct VariableTableEntry;
struct CastNode;
struct TypeTableEntryPointer {
- TypeTableEntry *pointer_child;
- bool pointer_is_const;
+ TypeTableEntry *child_type;
+ bool is_const;
};
struct TypeTableEntryInt {
src/codegen.cpp
@@ -248,6 +248,8 @@ static LLVMValueRef gen_field_access_expr(CodeGen *g, AstNode *node) {
TypeTableEntry *type_entry;
LLVMValueRef ptr = gen_field_ptr(g, node, &type_entry);
return LLVMBuildLoad(g->builder, ptr, "");
+ } else if (struct_type->id == TypeTableEntryIdPointer) {
+ zig_panic("TODO struct pointer access");
} else {
zig_panic("gen_field_access_expr bad struct type");
}
src/parser.cpp
@@ -1153,12 +1153,13 @@ static PrefixOp tok_to_prefix_op(Token *token) {
case TokenIdBang: return PrefixOpBoolNot;
case TokenIdDash: return PrefixOpNegation;
case TokenIdTilde: return PrefixOpBinNot;
+ case TokenIdAmpersand: return PrefixOpAddressOf;
default: return PrefixOpInvalid;
}
}
/*
-PrefixOp : token(Not) | token(Dash) | token(Tilde)
+PrefixOp : token(Not) | token(Dash) | token(Tilde) | (token(Ampersand) option(token(Const)))
*/
static PrefixOp ast_parse_prefix_op(ParseContext *pc, int *token_index, bool mandatory) {
Token *token = &pc->tokens->at(*token_index);
@@ -1171,6 +1172,15 @@ static PrefixOp ast_parse_prefix_op(ParseContext *pc, int *token_index, bool man
}
}
*token_index += 1;
+
+ if (result == PrefixOpAddressOf) {
+ Token *token = &pc->tokens->at(*token_index);
+ if (token->id == TokenIdKeywordConst) {
+ *token_index += 1;
+ result = PrefixOpConstAddressOf;
+ }
+ }
+
return result;
}
test/run_tests.cpp
@@ -569,6 +569,11 @@ export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 {
foo.a += 1;
foo.b = foo.a == 1;
test_foo(foo);
+ test_mutation(&foo);
+ if foo.c != 100 {
+ print_str("BAD\n");
+ }
+ print_str("OK\n");
return 0;
}
struct Foo {
@@ -577,9 +582,12 @@ struct Foo {
c : f32,
}
fn test_foo(foo : Foo) {
- if foo.b {
- print_str("OK\n");
+ if !foo.b {
+ print_str("BAD\n");
}
+}
+fn test_mutation(foo : &Foo) {
+ foo.c = 100;
}
)SOURCE", "OK\n");