...
This commit is contained in:
@@ -1,29 +1,31 @@
|
|||||||
namespace main
|
namespace main
|
||||||
|
|
||||||
struct Name {
|
// struct Name {
|
||||||
first: cstring
|
// first: cstring
|
||||||
last: cstring
|
// last: cstring
|
||||||
}
|
// }
|
||||||
|
|
||||||
struct Human
|
// struct Human
|
||||||
{
|
// {
|
||||||
name: Name
|
// name: Name
|
||||||
age: i64
|
// age: i64
|
||||||
}
|
// }
|
||||||
|
|
||||||
export func main(args: []cstring): i64
|
export func main(args: []cstring): i64
|
||||||
{
|
{
|
||||||
let x: Human
|
// let x: Human
|
||||||
|
|
||||||
x = alloc Human {
|
// x = alloc Human {
|
||||||
name = alloc Name {
|
// name = alloc Name {
|
||||||
first = "john"
|
// first = "john"
|
||||||
last = "doe"
|
// last = "doe"
|
||||||
}
|
// }
|
||||||
age = 23
|
// age = 23
|
||||||
}
|
// }
|
||||||
|
|
||||||
c::puts(x.name.last)
|
// c::puts(x.name.last)
|
||||||
|
|
||||||
|
c::puts("test")
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Syntax;
|
using Syntax;
|
||||||
@@ -219,8 +220,9 @@ public static class QBEGenerator
|
|||||||
return false;
|
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))
|
if (EmitTryMoveInto(source, destinationPointer))
|
||||||
{
|
{
|
||||||
return;
|
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)
|
switch (type)
|
||||||
{
|
{
|
||||||
case NubComplexType complexType:
|
case NubComplexType complexType:
|
||||||
@@ -286,20 +313,20 @@ public static class QBEGenerator
|
|||||||
|
|
||||||
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))
|
||||||
};
|
};
|
||||||
|
|
||||||
_builder.AppendLine($" {destination} =l alloc8 {size}");
|
_builder.AppendLine($" {destination} =l alloc8 {size}");
|
||||||
EmitMemcpy(source, destination, size);
|
EmitMemcpy(value, destination, size);
|
||||||
return destination;
|
return destination;
|
||||||
}
|
}
|
||||||
case NubSimpleType:
|
case NubSimpleType:
|
||||||
{
|
{
|
||||||
return source;
|
return value;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
@@ -601,7 +628,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);
|
EmitCopyIntoOrInitialize(assignment.Value, destination.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void EmitBlock(BoundBlockNode block, List<Variable>? variables = null)
|
private static void EmitBlock(BoundBlockNode block, List<Variable>? variables = null)
|
||||||
@@ -1039,7 +1066,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)}");
|
||||||
EmitCopyOrMoveInto(valueExpression, offset);
|
EmitCopyIntoOrInitialize(valueExpression, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Val(destination, structInitializer.StructType, ValKind.Direct);
|
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")
|
_ => 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}");
|
parameterStrings.Add($"{qbeType} {copy}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user