This commit is contained in:
nub31
2025-07-02 17:52:20 +02:00
parent 63d2c15202
commit 6003fa2f51
3 changed files with 33 additions and 100 deletions

View File

@@ -56,7 +56,7 @@ public static class QBEGenerator
}
foreach (var funcDef in _syntaxTree.Definitions.OfType<BoundLocalFuncDefinitionNode>())
{
{
EmitFuncDefinition(FuncName(funcDef), funcDef.Parameters, funcDef.ReturnType, funcDef.Body, funcDef.Exported);
_builder.AppendLine();
}
@@ -140,7 +140,6 @@ public static class QBEGenerator
_ => throw new ArgumentOutOfRangeException()
},
NubStructType => "storel",
NubFixedArrayType => "storel",
NubFuncType => "storel",
NubCStringType => "storel",
NubStringType => "storel",
@@ -170,7 +169,6 @@ public static class QBEGenerator
_ => throw new ArgumentOutOfRangeException()
},
NubStructType => "loadl",
NubFixedArrayType => "loadl",
NubFuncType => "loadl",
NubCStringType => "loadl",
NubStringType => "loadl",
@@ -200,7 +198,6 @@ public static class QBEGenerator
_ => throw new ArgumentOutOfRangeException()
},
NubStructType => "=l",
NubFixedArrayType => "=l",
NubFuncType => "=l",
NubCStringType => "=l",
NubStringType => "=l",
@@ -236,10 +233,6 @@ public static class QBEGenerator
{
return 8;
}
case NubFixedArrayType nubFixedArrayType:
{
return AlignmentOf(nubFixedArrayType.ElementType);
}
default:
{
throw new ArgumentOutOfRangeException();
@@ -295,10 +288,6 @@ public static class QBEGenerator
{
return 8;
}
case NubFixedArrayType nubFixedArrayType:
{
return SizeOf(nubFixedArrayType.ElementType) * nubFixedArrayType.Capacity + 8;
}
default:
{
throw new ArgumentOutOfRangeException();
@@ -326,16 +315,6 @@ public static class QBEGenerator
throw new UnreachableException($"Member '{member}' not found in struct");
}
private static bool IsPointerType(NubType type)
{
if (type.IsVoid)
{
throw new InvalidOperationException($"{nameof(IsPointerType)} should not be called on void types");
}
return type is NubStructType or NubFixedArrayType;
}
private static void EmitFuncDefinition(string name, List<BoundFuncParameter> parameters, NubType returnType, BoundBlockNode body, bool exported)
{
_variables.Clear();
@@ -369,7 +348,6 @@ public static class QBEGenerator
_ => throw new ArgumentOutOfRangeException()
},
NubStructType structType => StructName(_definitionTable.LookupStruct(structType.Namespace, structType.Name).GetValue()),
NubFixedArrayType => "l",
NubFuncType => "l",
NubCStringType => "l",
NubStringType => "l",
@@ -402,7 +380,6 @@ public static class QBEGenerator
_ => throw new ArgumentOutOfRangeException()
},
NubStructType structType => StructName(_definitionTable.LookupStruct(structType.Namespace, structType.Name).GetValue()),
NubFixedArrayType => "l",
NubFuncType => "l",
NubCStringType => "l",
NubStringType => "l",
@@ -485,7 +462,6 @@ public static class QBEGenerator
_ => throw new ArgumentOutOfRangeException()
},
NubStructType structType => StructName(_definitionTable.LookupStruct(structType.Namespace, structType.Name).GetValue()),
NubFixedArrayType fixedArrayType => $"b {SizeOf(fixedArrayType)}",
NubFuncType => "l",
NubCStringType => "l",
NubStringType => "l",
@@ -558,16 +534,6 @@ public static class QBEGenerator
EmitCopy(arrayType.ElementType, value, pointer);
break;
}
case NubFixedArrayType fixedArrayType:
{
var pointer = VarName();
_builder.AppendLine($" {pointer} =l mul {index}, {SizeOf(fixedArrayType.ElementType)}");
_builder.AppendLine($" {pointer} =l add {pointer}, 8");
_builder.AppendLine($" {pointer} =l add {array}, {pointer}");
EmitCopy(fixedArrayType.ElementType, value, pointer);
break;
}
default:
{
throw new ArgumentOutOfRangeException();
@@ -746,7 +712,6 @@ public static class QBEGenerator
var elementType = arrayIndexAccess.Array.Type switch
{
NubArrayType arrayType => arrayType.ElementType,
NubFixedArrayType fixedArrayType => fixedArrayType.ElementType,
_ => throw new ArgumentOutOfRangeException()
};
@@ -769,23 +734,23 @@ public static class QBEGenerator
{
var count = VarName();
_builder.AppendLine($" {count} =l loadl {array}");
var isNegative = VarName();
_builder.AppendLine($" {isNegative} =w csltl {index}, 0");
var isOob = VarName();
_builder.AppendLine($" {isOob} =w csgel {index}, {count}");
var anyOob = VarName();
_builder.AppendLine($" {anyOob} =w or {isNegative}, {isOob}");
var oobLabel = LabelName();
var notOobLabel = LabelName();
_builder.AppendLine($" jnz {anyOob}, {oobLabel}, {notOobLabel}");
_builder.AppendLine(oobLabel);
_builder.AppendLine($" call $nub_panic_array_oob()");
_builder.AppendLine(notOobLabel);
}
@@ -793,12 +758,12 @@ public static class QBEGenerator
{
var capacity = EmitUnwrap(EmitExpression(arrayInitializer.Capacity));
var elementSize = SizeOf(arrayInitializer.ElementType);
var capacityInBytes = VarName();
_builder.AppendLine($" {capacityInBytes} =l mul {capacity}, {elementSize}");
var totalSize = VarName();
_builder.AppendLine($" {totalSize} =l add {capacityInBytes}, 8");
var arrayPointer = VarName();
_builder.AppendLine($" {arrayPointer} =l alloc8 {totalSize}");
_builder.AppendLine($" storel {capacity}, {arrayPointer}");
@@ -1100,6 +1065,7 @@ public static class QBEGenerator
{
return new Val(literal.Literal, literal.Type, ValKind.Immediate);
}
break;
}
case LiteralKind.Float:
@@ -1122,6 +1088,7 @@ public static class QBEGenerator
var bits = BitConverter.DoubleToInt64Bits(value);
return new Val(bits.ToString(), literal.Type, ValKind.Immediate);
}
break;
}
case LiteralKind.String:
@@ -1139,6 +1106,7 @@ public static class QBEGenerator
_cStringLiterals.Add(cStringLiteral);
return new Val(cStringLiteral.Name, literal.Type, ValKind.Immediate);
}
break;
}
case LiteralKind.Bool:
@@ -1147,10 +1115,11 @@ public static class QBEGenerator
{
return new Val(bool.Parse(literal.Literal) ? "1" : "0", literal.Type, ValKind.Immediate);
}
break;
}
}
throw new NotSupportedException($"Cannot create literal of kind '{literal.Kind}' for type {literal.Type}");
}
@@ -1250,7 +1219,7 @@ public static class QBEGenerator
_builder.AppendLine($" {output} =l loadl {item}");
break;
}
throw new UnreachableException();
}
case NubStringType:
@@ -1267,7 +1236,7 @@ public static class QBEGenerator
{
var structDefinition = _definitionTable.LookupStruct(structType.Namespace, structType.Name).GetValue();
var offset = OffsetOf(structDefinition, memberAccess.Member);
var offsetName = VarName();
_builder.AppendLine($" {offsetName} =l add {item}, {offset}");
_builder.AppendLine($" {output} {QBEAssign(memberAccess.Type)} {QBELoad(memberAccess.Type)} {item}");
@@ -1278,7 +1247,7 @@ public static class QBEGenerator
throw new ArgumentOutOfRangeException();
}
}
return new Val(output, memberAccess.Type, ValKind.Immediate);
}
@@ -1330,7 +1299,6 @@ public static class QBEGenerator
_ => throw new ArgumentOutOfRangeException()
},
NubStructType structType => StructName(_definitionTable.LookupStruct(structType.Namespace, structType.Name).GetValue()),
NubFixedArrayType => "l",
NubFuncType => "l",
NubCStringType => "l",
NubStringType => "l",
@@ -1372,25 +1340,29 @@ public static class QBEGenerator
{
throw new InvalidOperationException("Cannot unwrap temporary of void type");
}
switch (val.Kind)
{
case ValKind.Func:
case ValKind.Immediate:
{
return val.Name;
}
case ValKind.Pointer:
if (IsPointerType(val.Type))
{
if (val.Type is NubStructType)
{
return val.Name;
}
else
{
var result = VarName();
_builder.AppendLine($" {result} {QBEAssign(val.Type)} {QBELoad(val.Type)} {val.Name}");
return result;
}
var result = VarName();
_builder.AppendLine($" {result} {QBEAssign(val.Type)} {QBELoad(val.Type)} {val.Name}");
return result;
}
default:
{
throw new ArgumentOutOfRangeException();
}
}
}
}

View File

@@ -1,5 +1,4 @@
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.CodeAnalysis;
using Common;
using Syntax.Diagnostics;
using Syntax.Parsing.Node;
@@ -730,29 +729,9 @@ public static class Parser
if (TryExpectSymbol(Symbol.OpenBracket))
{
if (Peek().TryGetValue(out var token) && token is LiteralToken { Kind: LiteralKind.Integer, Value: var sizeValue })
{
Next();
ExpectSymbol(Symbol.CloseBracket);
var baseType = ParseType();
var size = int.Parse(sizeValue);
if (size > 0)
{
return new NubFixedArrayType(baseType, size);
}
else
{
throw new UnreachableException();
}
}
else
{
ExpectSymbol(Symbol.CloseBracket);
var baseType = ParseType();
return new NubArrayType(baseType);
}
ExpectSymbol(Symbol.CloseBracket);
var baseType = ParseType();
return new NubArrayType(baseType);
}
if (!Peek().TryGetValue(out var peekToken))

View File

@@ -166,24 +166,6 @@ public class NubArrayType(NubType elementType) : NubType
}
}
public class NubFixedArrayType(NubType elementType, int capacity) : NubType
{
public NubType ElementType { get; } = elementType;
public int Capacity { get; } = capacity;
public override string ToString() => $"[{Capacity}]{ElementType}";
public override bool Equals(object? obj)
{
return obj is NubFixedArrayType other && ElementType.Equals(other.ElementType) && Capacity == other.Capacity;
}
public override int GetHashCode()
{
return HashCode.Combine(ElementType, Capacity);
}
}
public class NubAnyType : NubType
{
public override string ToString() => "any";