diff --git a/example/src/main.nub b/example/src/main.nub index bd2611d..b6e7b71 100644 --- a/example/src/main.nub +++ b/example/src/main.nub @@ -13,9 +13,19 @@ struct Human export func main(args: []cstring): i64 { - let x: cstring = "test" - - c::puts(x) + let x = alloc Human + { + name = alloc Name { + first = "john" + last = "doe" + } + age = 23 + } + print_name(x&) return 0 } + +func print_name(human: ^Human) { + c::puts(human^.name.last) +} diff --git a/src/compiler/Generation/QBE/QBEGenerator.cs b/src/compiler/Generation/QBE/QBEGenerator.cs index f4326ed..7fc4095 100644 --- a/src/compiler/Generation/QBE/QBEGenerator.cs +++ b/src/compiler/Generation/QBE/QBEGenerator.cs @@ -827,13 +827,24 @@ public static class QBEGenerator private static Val EmitDereference(BoundDereferenceNode dereference) { - var result = EmitUnwrap(EmitExpression(dereference.Expression)); - return EmitLoad(dereference.Type, result); + var pointerType = (NubPointerType)dereference.Expression.Type; + + var pointer = EmitExpression(dereference.Expression); + + // Complex types are already pointers, so no need to load them + if (pointerType.BaseType is NubComplexType) + { + return pointer; + } + + return EmitLoad(dereference.Type, EmitUnwrap(pointer)); } private static Val EmitAddressOf(BoundAddressOfNode addressOf) { - throw new NotImplementedException(); + var value = EmitExpression(addressOf.Expression); + Debug.Assert(value.Kind == ValKind.Pointer); + return new Val(value.Name, addressOf.Type, ValKind.Direct); } private static Val EmitBinaryExpression(BoundBinaryExpressionNode binaryExpression)