diff --git a/src/compiler/Generation/QBE/QBEGenerator.cs b/src/compiler/Generation/QBE/QBEGenerator.cs index a248a04..0bba87f 100644 --- a/src/compiler/Generation/QBE/QBEGenerator.cs +++ b/src/compiler/Generation/QBE/QBEGenerator.cs @@ -195,105 +195,86 @@ public static class QBEGenerator return size; } - private static void EmitCopyInto(NubType type, string source, string destination) + private static void EmitCopyInto(NubType type, string source, string destinationPointer) { switch (type) { - case NubArrayType nubArrayType: + case NubComplexType complexType: { - var size = EmitArraySizeInBytes(nubArrayType, source); - var buffer = VarName(); - _builder.AppendLine($" {buffer} =l alloc8 {size}"); - EmitMemcpy(source, buffer, size); - EmitStore(type, buffer, destination); - break; + var size = complexType switch + { + NubArrayType nubArrayType => EmitArraySizeInBytes(nubArrayType, source), + NubCStringType => EmitCStringSizeInBytes(source), + NubStringType => EmitStringSizeInBytes(source), + NubStructType nubStructType => SizeOf(nubStructType).ToString(), + _ => throw new ArgumentOutOfRangeException(nameof(complexType)) + }; + + switch (complexType) + { + case NubArrayType: + case NubCStringType: + case NubStringType: + { + var buffer = VarName(); + _builder.AppendLine($" {buffer} =l alloc8 {size}"); + EmitMemcpy(source, buffer, size); + EmitStore(type, buffer, destinationPointer); + return; + } + case NubStructType: + { + EmitMemcpy(source, destinationPointer, size); + return; + } + default: + { + throw new ArgumentOutOfRangeException(nameof(complexType)); + } + } } - case NubCStringType: + case NubSimpleType simpleType: { - var size = EmitCStringSizeInBytes(source); - var buffer = VarName(); - _builder.AppendLine($" {buffer} =l alloc8 {size}"); - EmitMemcpy(source, buffer, size); - EmitStore(type, buffer, destination); - break; + EmitStore(simpleType, source, destinationPointer); + return; } - case NubStringType: - { - var size = EmitStringSizeInBytes(source); - var buffer = VarName(); - _builder.AppendLine($" {buffer} =l alloc8 {size}"); - EmitMemcpy(source, buffer, size); - EmitStore(type, buffer, destination); - break; - } - case NubStructType nubStructType: - { - var size = SizeOf(nubStructType); - EmitMemcpy(source, destination, size.ToString()); - break; - } - case NubPointerType: - case NubPrimitiveType: - { - EmitStore(type, source, destination); - break; - } - case NubVoidType: - case NubFuncType: - case NubAnyType: - throw new NotSupportedException($"Cannot copy type '{type}'"); default: + { throw new ArgumentOutOfRangeException(nameof(type)); + } } } private static string EmitCopy(NubType type, string source) { - var destination = VarName(); switch (type) { - case NubArrayType nubArrayType: + case NubComplexType complexType: { - var size = EmitArraySizeInBytes(nubArrayType, source); + var destination = VarName(); + + var size = complexType switch + { + NubArrayType nubArrayType => EmitArraySizeInBytes(nubArrayType, source), + NubCStringType => EmitCStringSizeInBytes(source), + NubStringType => EmitStringSizeInBytes(source), + NubStructType nubStructType => SizeOf(nubStructType).ToString(), + _ => throw new ArgumentOutOfRangeException(nameof(complexType)) + }; + _builder.AppendLine($" {destination} =l alloc8 {size}"); EmitMemcpy(source, destination, size); - break; + return destination; } - case NubCStringType: - { - var size = EmitCStringSizeInBytes(source); - _builder.AppendLine($" {destination} =l alloc8 {size}"); - EmitMemcpy(source, destination, size); - break; - } - case NubStringType: - { - var size = EmitStringSizeInBytes(source); - _builder.AppendLine($" {destination} =l alloc8 {size}"); - EmitMemcpy(source, destination, size); - break; - } - case NubStructType nubStructType: - { - var size = SizeOf(nubStructType); - _builder.AppendLine($" {destination} =l alloc8 {size}"); - EmitMemcpy(source, destination, size.ToString()); - break; - } - case NubPointerType: - case NubPrimitiveType: + case NubSimpleType: { return source; } - case NubVoidType: - case NubFuncType: - case NubAnyType: - throw new NotSupportedException($"Cannot copy type '{type}'"); default: + { throw new ArgumentOutOfRangeException(nameof(type)); + } } - - return destination; } private static string QBEAssign(NubType type) diff --git a/src/compiler/Syntax/Typing/NubType.cs b/src/compiler/Syntax/Typing/NubType.cs index 5cd508a..fd92f65 100644 --- a/src/compiler/Syntax/Typing/NubType.cs +++ b/src/compiler/Syntax/Typing/NubType.cs @@ -29,7 +29,10 @@ public abstract class NubType public abstract override string ToString(); } -public class NubCStringType : NubType +public abstract class NubComplexType : NubType; +public abstract class NubSimpleType : NubType; + +public class NubCStringType : NubComplexType { public override bool Equals(object? obj) { @@ -47,7 +50,7 @@ public class NubCStringType : NubType } } -public class NubStringType : NubType +public class NubStringType : NubComplexType { public override bool Equals(object? obj) { @@ -65,7 +68,7 @@ public class NubStringType : NubType } } -public class NubFuncType(NubType returnType, List parameters) : NubType +public class NubFuncType(NubType returnType, List parameters) : NubSimpleType { public NubType ReturnType { get; } = returnType; public List Parameters { get; } = parameters; @@ -86,7 +89,7 @@ public class NubFuncType(NubType returnType, List parameters) : NubType } } -public class NubStructType(string @namespace, string name) : NubType +public class NubStructType(string @namespace, string name) : NubComplexType { public string Namespace { get; } = @namespace; public string Name { get; } = name; @@ -107,7 +110,7 @@ public class NubStructType(string @namespace, string name) : NubType } } -public class NubPointerType(NubType baseType) : NubType +public class NubPointerType(NubType baseType) : NubSimpleType { public NubType BaseType { get; } = baseType; @@ -127,7 +130,7 @@ public class NubPointerType(NubType baseType) : NubType } } -public class NubArrayType(NubType elementType) : NubType +public class NubArrayType(NubType elementType) : NubComplexType { public NubType ElementType { get; } = elementType; @@ -152,7 +155,7 @@ public class NubArrayType(NubType elementType) : NubType } } -public class NubAnyType : NubType +public class NubAnyType : NubSimpleType { public override string ToString() => "any"; @@ -167,7 +170,7 @@ public class NubAnyType : NubType } } -public class NubVoidType : NubType +public class NubVoidType : NubSimpleType { public override string ToString() => "void"; @@ -182,7 +185,7 @@ public class NubVoidType : NubType } } -public class NubPrimitiveType(PrimitiveTypeKind kind) : NubType +public class NubPrimitiveType(PrimitiveTypeKind kind) : NubSimpleType { public PrimitiveTypeKind Kind { get; } = kind;