This commit is contained in:
nub31
2025-07-03 18:29:33 +02:00
parent 792afd0442
commit 9babcd0b41
2 changed files with 50 additions and 38 deletions

View File

@@ -1,8 +1,13 @@
namespace main
struct Name {
first: cstring
last: cstring
}
struct Human
{
name: cstring
name: Name
age: i64
}
@@ -11,11 +16,14 @@ export func main(args: []cstring): i64
let x: Human
x = alloc Human {
name = "john"
name = alloc Name {
first = "john"
last = "doe"
}
age = 23
}
c::puts(x.name)
c::puts(x.name.last)
return 0
}

View File

@@ -195,17 +195,43 @@ public static class QBEGenerator
return size;
}
private static void EmitCopyInto(NubType type, string source, string destinationPointer)
private static bool EmitTryMoveInto(BoundExpressionNode source, string destinationPointer)
{
switch (type)
switch (source)
{
case BoundArrayInitializerNode arrayInitializer:
{
EmitStore(source.Type, EmitUnwrap(EmitArrayInitializer(arrayInitializer)), destinationPointer);
return true;
}
case BoundStructInitializerNode structInitializer:
{
EmitStructInitializer(structInitializer, destinationPointer);
return true;
}
}
return false;
}
private static void EmitCopyOrMoveInto(BoundExpressionNode source, string destinationPointer)
{
if (EmitTryMoveInto(source, destinationPointer))
{
return;
}
var value = EmitUnwrap(EmitExpression(source));
switch (source.Type)
{
case NubComplexType complexType:
{
var size = complexType switch
{
NubArrayType nubArrayType => EmitArraySizeInBytes(nubArrayType, source),
NubCStringType => EmitCStringSizeInBytes(source),
NubStringType => EmitStringSizeInBytes(source),
NubArrayType nubArrayType => EmitArraySizeInBytes(nubArrayType, value),
NubCStringType => EmitCStringSizeInBytes(value),
NubStringType => EmitStringSizeInBytes(value),
NubStructType nubStructType => SizeOf(nubStructType).ToString(),
_ => throw new ArgumentOutOfRangeException(nameof(complexType))
};
@@ -218,13 +244,13 @@ public static class QBEGenerator
{
var buffer = VarName();
_builder.AppendLine($" {buffer} =l alloc8 {size}");
EmitMemcpy(source, buffer, size);
EmitStore(type, buffer, destinationPointer);
EmitMemcpy(value, buffer, size);
EmitStore(source.Type, buffer, destinationPointer);
return;
}
case NubStructType:
{
EmitMemcpy(source, destinationPointer, size);
EmitMemcpy(value, destinationPointer, size);
return;
}
default:
@@ -235,12 +261,12 @@ public static class QBEGenerator
}
case NubSimpleType simpleType:
{
EmitStore(simpleType, source, destinationPointer);
EmitStore(simpleType, value, destinationPointer);
return;
}
default:
{
throw new ArgumentOutOfRangeException(nameof(type));
throw new ArgumentOutOfRangeException(nameof(source.Type));
}
}
}
@@ -570,28 +596,7 @@ public static class QBEGenerator
{
var destination = EmitExpression(assignment.Expression);
Debug.Assert(destination.Kind == ValKind.Pointer);
// 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;
}
}
EmitCopyOrMoveInto(assignment.Value, destination.Name);
}
private static void EmitBlock(BoundBlockNode block, List<Variable>? variables = null)
@@ -1029,8 +1034,7 @@ public static class QBEGenerator
var offset = VarName();
_builder.AppendLine($" {offset} =l add {destination}, {OffsetOf(structDefinition, field.Name)}");
var source = EmitUnwrap(EmitExpression(valueExpression));
EmitCopyInto(valueExpression.Type, source, offset);
EmitCopyOrMoveInto(valueExpression, offset);
}
return new Val(destination, structInitializer.StructType, ValKind.Direct);