This commit is contained in:
nub31
2025-07-03 18:57:37 +02:00
parent 8889f984d6
commit 66d47b9100
2 changed files with 57 additions and 28 deletions

View File

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

View File

@@ -1,4 +1,5 @@
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Text;
using Syntax;
@@ -219,8 +220,9 @@ public static class QBEGenerator
return false;
}
private static void EmitCopyOrMoveInto(BoundExpressionNode source, string destinationPointer)
private static void EmitCopyIntoOrInitialize(BoundExpressionNode source, string destinationPointer)
{
// If the source is a value which is not used yet such as an array/struct initializer or literal, we can skip copying
if (EmitTryMoveInto(source, destinationPointer))
{
return;
@@ -276,8 +278,33 @@ public static class QBEGenerator
}
}
private static string EmitCopy(NubType type, string source)
private static bool EmitTryCreateWithoutCopy(BoundExpressionNode source, [NotNullWhen(true)] out string? destination)
{
switch (source)
{
case BoundArrayInitializerNode:
case BoundStructInitializerNode:
case BoundLiteralNode { Kind: LiteralKind.String }:
{
destination = EmitUnwrap(EmitExpression(source));
return true;
}
}
destination = null;
return false;
}
private static string EmitCreateCopyOrInitialize(NubType type, BoundExpressionNode source)
{
// If the source is a value which is not used yet such as an array/struct initializer or literal, we can skip copying
if (EmitTryCreateWithoutCopy(source, out var uncopiedValue))
{
return uncopiedValue;
}
var value = EmitUnwrap(EmitExpression(source));
switch (type)
{
case NubComplexType complexType:
@@ -286,20 +313,20 @@ public static class QBEGenerator
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))
};
_builder.AppendLine($" {destination} =l alloc8 {size}");
EmitMemcpy(source, destination, size);
EmitMemcpy(value, destination, size);
return destination;
}
case NubSimpleType:
{
return source;
return value;
}
default:
{
@@ -601,7 +628,7 @@ public static class QBEGenerator
{
var destination = EmitExpression(assignment.Expression);
Debug.Assert(destination.Kind == ValKind.Pointer);
EmitCopyOrMoveInto(assignment.Value, destination.Name);
EmitCopyIntoOrInitialize(assignment.Value, destination.Name);
}
private static void EmitBlock(BoundBlockNode block, List<Variable>? variables = null)
@@ -1039,7 +1066,7 @@ public static class QBEGenerator
var offset = VarName();
_builder.AppendLine($" {offset} =l add {destination}, {OffsetOf(structDefinition, field.Name)}");
EmitCopyOrMoveInto(valueExpression, offset);
EmitCopyIntoOrInitialize(valueExpression, offset);
}
return new Val(destination, structInitializer.StructType, ValKind.Direct);
@@ -1169,7 +1196,7 @@ public static class QBEGenerator
_ => throw new NotSupportedException($"'{parameter.Type}' type cannot be used in function calls")
};
var copy = EmitCopy(parameter.Type, EmitUnwrap(EmitExpression(parameter)));
var copy = EmitCreateCopyOrInitialize(parameter.Type, parameter);
parameterStrings.Add($"{qbeType} {copy}");
}