From 792afd044294f8ce7a56c6b440c67612c7e7fd89 Mon Sep 17 00:00:00 2001 From: nub31 Date: Thu, 3 Jul 2025 18:19:15 +0200 Subject: [PATCH] ... --- example/src/main.nub | 16 +++---- src/compiler/Generation/QBE/QBEGenerator.cs | 48 +++++++++++++++------ 2 files changed, 40 insertions(+), 24 deletions(-) diff --git a/example/src/main.nub b/example/src/main.nub index 20a3676..29e5532 100644 --- a/example/src/main.nub +++ b/example/src/main.nub @@ -8,18 +8,14 @@ struct Human export func main(args: []cstring): i64 { - let x: i64 + let x: Human - x = 23 + x = alloc Human { + name = "john" + age = 23 + } - if (x == 23) - { - c::printf("true\n") - } - else - { - c::printf("false\n") - } + c::puts(x.name) return 0 } diff --git a/src/compiler/Generation/QBE/QBEGenerator.cs b/src/compiler/Generation/QBE/QBEGenerator.cs index 0bba87f..a2dd1af 100644 --- a/src/compiler/Generation/QBE/QBEGenerator.cs +++ b/src/compiler/Generation/QBE/QBEGenerator.cs @@ -570,9 +570,28 @@ public static class QBEGenerator { var destination = EmitExpression(assignment.Expression); Debug.Assert(destination.Kind == ValKind.Pointer); - - var source = EmitUnwrap(EmitExpression(assignment.Value)); - EmitCopyInto(assignment.Value.Type, source, destination.Name); + + // Initializers will be created in place to prevent a + switch (assignment.Value) + { + case BoundArrayInitializerNode arrayInitializer: + { + var value = EmitUnwrap(EmitArrayInitializer(arrayInitializer)); + EmitStore(assignment.Value.Type, value, destination.Name); + break; + } + case BoundStructInitializerNode structInitializer: + { + EmitStructInitializer(structInitializer, destination.Name); + break; + } + default: + { + var value = EmitUnwrap(EmitExpression(assignment.Value)); + EmitCopyInto(assignment.Value.Type, value, destination.Name); + break; + } + } } private static void EmitBlock(BoundBlockNode block, List? variables = null) @@ -988,18 +1007,19 @@ public static class QBEGenerator throw new NotSupportedException($"Cannot create literal of kind '{literal.Kind}' for type {literal.Type}"); } - private static Val EmitStructInitializer(BoundStructInitializerNode structInitializer) + private static Val EmitStructInitializer(BoundStructInitializerNode structInitializer, string? destination = null) { var structDefinition = _definitionTable.LookupStruct(structInitializer.StructType.Namespace, structInitializer.StructType.Name).GetValue(); - var output = VarName(); - var size = SizeOf(structInitializer.StructType); - _builder.AppendLine($" {output} =l alloc8 {size}"); - + if (destination == null) + { + destination = VarName(); + var size = SizeOf(structInitializer.StructType); + _builder.AppendLine($" {destination} =l alloc8 {size}"); + } + foreach (var field in structDefinition.Fields) { - var offset = OffsetOf(structDefinition, field.Name); - if (!structInitializer.Initializers.TryGetValue(field.Name, out var valueExpression)) { valueExpression = field.Value.Value; @@ -1007,13 +1027,13 @@ public static class QBEGenerator Debug.Assert(valueExpression != null); - var destination = VarName(); - _builder.AppendLine($" {destination} =l add {output}, {offset}"); + var offset = VarName(); + _builder.AppendLine($" {offset} =l add {destination}, {OffsetOf(structDefinition, field.Name)}"); var source = EmitUnwrap(EmitExpression(valueExpression)); - EmitCopyInto(valueExpression.Type, source, destination); + EmitCopyInto(valueExpression.Type, source, offset); } - return new Val(output, structInitializer.StructType, ValKind.Direct); + return new Val(destination, structInitializer.StructType, ValKind.Direct); } private static Val EmitUnaryExpression(BoundUnaryExpressionNode unaryExpression)