...
This commit is contained in:
@@ -1,8 +1,13 @@
|
|||||||
namespace main
|
namespace main
|
||||||
|
|
||||||
|
struct Name {
|
||||||
|
first: cstring
|
||||||
|
last: cstring
|
||||||
|
}
|
||||||
|
|
||||||
struct Human
|
struct Human
|
||||||
{
|
{
|
||||||
name: cstring
|
name: Name
|
||||||
age: i64
|
age: i64
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -11,11 +16,14 @@ export func main(args: []cstring): i64
|
|||||||
let x: Human
|
let x: Human
|
||||||
|
|
||||||
x = alloc Human {
|
x = alloc Human {
|
||||||
name = "john"
|
name = alloc Name {
|
||||||
|
first = "john"
|
||||||
|
last = "doe"
|
||||||
|
}
|
||||||
age = 23
|
age = 23
|
||||||
}
|
}
|
||||||
|
|
||||||
c::puts(x.name)
|
c::puts(x.name.last)
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -195,17 +195,43 @@ public static class QBEGenerator
|
|||||||
return size;
|
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:
|
case NubComplexType complexType:
|
||||||
{
|
{
|
||||||
var size = complexType switch
|
var size = complexType switch
|
||||||
{
|
{
|
||||||
NubArrayType nubArrayType => EmitArraySizeInBytes(nubArrayType, source),
|
NubArrayType nubArrayType => EmitArraySizeInBytes(nubArrayType, value),
|
||||||
NubCStringType => EmitCStringSizeInBytes(source),
|
NubCStringType => EmitCStringSizeInBytes(value),
|
||||||
NubStringType => EmitStringSizeInBytes(source),
|
NubStringType => EmitStringSizeInBytes(value),
|
||||||
NubStructType nubStructType => SizeOf(nubStructType).ToString(),
|
NubStructType nubStructType => SizeOf(nubStructType).ToString(),
|
||||||
_ => throw new ArgumentOutOfRangeException(nameof(complexType))
|
_ => throw new ArgumentOutOfRangeException(nameof(complexType))
|
||||||
};
|
};
|
||||||
@@ -218,13 +244,13 @@ public static class QBEGenerator
|
|||||||
{
|
{
|
||||||
var buffer = VarName();
|
var buffer = VarName();
|
||||||
_builder.AppendLine($" {buffer} =l alloc8 {size}");
|
_builder.AppendLine($" {buffer} =l alloc8 {size}");
|
||||||
EmitMemcpy(source, buffer, size);
|
EmitMemcpy(value, buffer, size);
|
||||||
EmitStore(type, buffer, destinationPointer);
|
EmitStore(source.Type, buffer, destinationPointer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case NubStructType:
|
case NubStructType:
|
||||||
{
|
{
|
||||||
EmitMemcpy(source, destinationPointer, size);
|
EmitMemcpy(value, destinationPointer, size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -235,12 +261,12 @@ public static class QBEGenerator
|
|||||||
}
|
}
|
||||||
case NubSimpleType simpleType:
|
case NubSimpleType simpleType:
|
||||||
{
|
{
|
||||||
EmitStore(simpleType, source, destinationPointer);
|
EmitStore(simpleType, value, destinationPointer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
default:
|
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);
|
var destination = EmitExpression(assignment.Expression);
|
||||||
Debug.Assert(destination.Kind == ValKind.Pointer);
|
Debug.Assert(destination.Kind == ValKind.Pointer);
|
||||||
|
EmitCopyOrMoveInto(assignment.Value, 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<Variable>? variables = null)
|
private static void EmitBlock(BoundBlockNode block, List<Variable>? variables = null)
|
||||||
@@ -1017,7 +1022,7 @@ public static class QBEGenerator
|
|||||||
var size = SizeOf(structInitializer.StructType);
|
var size = SizeOf(structInitializer.StructType);
|
||||||
_builder.AppendLine($" {destination} =l alloc8 {size}");
|
_builder.AppendLine($" {destination} =l alloc8 {size}");
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var field in structDefinition.Fields)
|
foreach (var field in structDefinition.Fields)
|
||||||
{
|
{
|
||||||
if (!structInitializer.Initializers.TryGetValue(field.Name, out var valueExpression))
|
if (!structInitializer.Initializers.TryGetValue(field.Name, out var valueExpression))
|
||||||
@@ -1029,8 +1034,7 @@ public static class QBEGenerator
|
|||||||
|
|
||||||
var offset = VarName();
|
var offset = VarName();
|
||||||
_builder.AppendLine($" {offset} =l add {destination}, {OffsetOf(structDefinition, field.Name)}");
|
_builder.AppendLine($" {offset} =l add {destination}, {OffsetOf(structDefinition, field.Name)}");
|
||||||
var source = EmitUnwrap(EmitExpression(valueExpression));
|
EmitCopyOrMoveInto(valueExpression, offset);
|
||||||
EmitCopyInto(valueExpression.Type, source, offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Val(destination, structInitializer.StructType, ValKind.Direct);
|
return new Val(destination, structInitializer.StructType, ValKind.Direct);
|
||||||
|
|||||||
Reference in New Issue
Block a user