From b28fb825069f5cc1153cc8c999d1467b5fda21cf Mon Sep 17 00:00:00 2001 From: nub31 Date: Sat, 21 Jun 2025 16:21:39 +0200 Subject: [PATCH] tmp --- src/Generation/QBE/QBEGenerator.cs | 158 +++++++++++++++-------------- 1 file changed, 84 insertions(+), 74 deletions(-) diff --git a/src/Generation/QBE/QBEGenerator.cs b/src/Generation/QBE/QBEGenerator.cs index 275eca4..1fe599b 100644 --- a/src/Generation/QBE/QBEGenerator.cs +++ b/src/Generation/QBE/QBEGenerator.cs @@ -71,9 +71,9 @@ public static class QBEGenerator return _builder.ToString(); } - private static string VarName() + private static Tmp NewTmp() { - return $"%v{++_variableIndex}"; + return new Tmp($"%v{++_variableIndex}"); } private static string LabelName() @@ -389,26 +389,26 @@ public static class QBEGenerator foreach (var parameter in parameters) { - var parameterName = "%" + parameter.Name; + var parameterName = new Tmp("%" + parameter.Name); if (parameter.Type is NubPrimitiveType primitiveType) { switch (primitiveType.Kind) { case PrimitiveTypeKind.I16: - parameterName = VarName(); + parameterName = NewTmp(); _builder.AppendLine($" {parameterName} =w extsh %{parameter.Name}"); break; case PrimitiveTypeKind.I8: - parameterName = VarName(); + parameterName = NewTmp(); _builder.AppendLine($" {parameterName} =w extsb %{parameter.Name}"); break; case PrimitiveTypeKind.U16: - parameterName = VarName(); + parameterName = NewTmp(); _builder.AppendLine($" {parameterName} =w extuh %{parameter.Name}"); break; case PrimitiveTypeKind.U8: - parameterName = VarName(); + parameterName = NewTmp(); _builder.AppendLine($" {parameterName} =w extub %{parameter.Name}"); break; } @@ -519,13 +519,13 @@ public static class QBEGenerator { case NubArrayType arrayType: { - var startName = VarName(); + var startName = NewTmp(); _builder.AppendLine($" {startName} =l add {array}, 8"); - var adjustedIndex = VarName(); + var adjustedIndex = NewTmp(); _builder.AppendLine($" {adjustedIndex} =l mul {index}, {SizeOf(arrayType.ElementType)}"); - var pointer = VarName(); + var pointer = NewTmp(); _builder.AppendLine($" {pointer} =l add {startName}, {adjustedIndex}"); GenerateCopy(arrayType.ElementType, value, pointer); @@ -533,13 +533,13 @@ public static class QBEGenerator } case NubFixedArrayType fixedArrayType: { - var startName = VarName(); + var startName = NewTmp(); _builder.AppendLine($" {startName} =l add {array}, 8"); - var adjustedIndex = VarName(); + var adjustedIndex = NewTmp(); _builder.AppendLine($" {adjustedIndex} =l mul {index}, {SizeOf(fixedArrayType.ElementType)}"); - var pointer = VarName(); + var pointer = NewTmp(); _builder.AppendLine($" {pointer} =l add {startName}, {adjustedIndex}"); GenerateCopy(fixedArrayType.ElementType, value, pointer); @@ -629,7 +629,7 @@ public static class QBEGenerator var offset = OffsetOf(structDefinition, memberAssignment.MemberAccess.Member); var item = GenerateExpression(memberAssignment.MemberAccess.Expression); - var pointer = VarName(); + var pointer = NewTmp(); _builder.AppendLine($" {pointer} =l add {item}, {offset}"); @@ -653,7 +653,7 @@ public static class QBEGenerator private static void GenerateVariableDeclaration(VariableDeclarationNode variableDeclaration) { - var generatedName = VarName(); + var generatedName = NewTmp(); _builder.AppendLine($" {generatedName} =l alloc8 {SizeOf(variableDeclaration.Type)}"); _variables.Push(new Variable(variableDeclaration.Name, generatedName)); } @@ -662,7 +662,7 @@ public static class QBEGenerator { var value = GenerateExpression(variableAssignment.Value); var variable = _variables.Single(x => x.Name == variableAssignment.Identifier.Name); - GenerateCopy(variableAssignment.Value.Type, value, variable.GeneratedName); + GenerateCopy(variableAssignment.Value.Type, value, variable.Tmp); variable.Assign(); } @@ -687,7 +687,7 @@ public static class QBEGenerator _breakLabels.Pop(); } - private static string GenerateExpression(ExpressionNode expression) + private static Tmp GenerateExpression(ExpressionNode expression) { return expression switch { @@ -708,14 +708,16 @@ public static class QBEGenerator }; } - private static string GenerateAnonymousFunc(AnonymousFuncNode anonymousFunc) + private static Tmp GenerateAnonymousFunc(AnonymousFuncNode anonymousFunc) { var name = $"$anon_func{++_anonymousFuncIndex}"; _anonymousFunctions.Enqueue((anonymousFunc, name)); - return name; + var tmp = NewTmp(); + _builder.AppendLine($" {NewTmp()} =l {name}"); + return tmp; } - private static string GenerateArrayIndexPointer(ArrayIndexAccessNode arrayIndexAccess) + private static Tmp GenerateArrayIndexPointer(ArrayIndexAccessNode arrayIndexAccess) { var array = GenerateExpression(arrayIndexAccess.Array); var index = GenerateExpression(arrayIndexAccess.Index); @@ -728,16 +730,16 @@ public static class QBEGenerator _ => throw new ArgumentOutOfRangeException() }; - var firstItemPointerName = VarName(); + var firstItemPointerName = NewTmp(); _builder.AppendLine($" {firstItemPointerName} =l add {array}, 8"); - var offsetPointerName = VarName(); + var offsetPointerName = NewTmp(); _builder.AppendLine($" {offsetPointerName} =l mul {index}, {SizeOf(elementType)}"); - var resultPointerName = VarName(); + var resultPointerName = NewTmp(); _builder.AppendLine($" {resultPointerName} =l add {firstItemPointerName}, {offsetPointerName}"); return resultPointerName; } - private static string GenerateArrayIndexAccess(ArrayIndexAccessNode arrayIndexAccess) + private static Tmp GenerateArrayIndexAccess(ArrayIndexAccessNode arrayIndexAccess) { var pointerName = GenerateArrayIndexPointer(arrayIndexAccess); @@ -754,24 +756,24 @@ public static class QBEGenerator } else { - var outputName = VarName(); + var outputName = NewTmp(); _builder.AppendLine($" {outputName} {QBEAssign(arrayIndexAccess.Type)} {QBELoad(arrayIndexAccess.Type)} {pointerName}"); return outputName; } } - private static void GenerateArrayBoundsCheck(string array, string index) + private static void GenerateArrayBoundsCheck(Tmp array, Tmp index) { - var countName = VarName(); + var countName = NewTmp(); _builder.AppendLine($" {countName} =l loadl {array}"); - var isNegativeName = VarName(); + var isNegativeName = NewTmp(); _builder.AppendLine($" {isNegativeName} =w csltl {index}, 0"); - var isOobName = VarName(); + var isOobName = NewTmp(); _builder.AppendLine($" {isOobName} =w csgel {index}, {countName}"); - var anyOobName = VarName(); + var anyOobName = NewTmp(); _builder.AppendLine($" {anyOobName} =w or {isNegativeName}, {isOobName}"); var oobLabel = LabelName(); @@ -784,34 +786,34 @@ public static class QBEGenerator _builder.AppendLine(notOobLabel); } - private static string GenerateArrayInitializer(ArrayInitializerNode arrayInitializer) + private static Tmp GenerateArrayInitializer(ArrayInitializerNode arrayInitializer) { var capacity = GenerateExpression(arrayInitializer.Capacity); var elementSize = SizeOf(arrayInitializer.ElementType); - var capacityInBytes = VarName(); + var capacityInBytes = NewTmp(); _builder.AppendLine($" {capacityInBytes} =l mul {capacity}, {elementSize}"); - var totalArraySize = VarName(); + var totalArraySize = NewTmp(); _builder.AppendLine($" {totalArraySize} =l add {capacityInBytes}, 8"); - var outputName = VarName(); + var outputName = NewTmp(); _builder.AppendLine($" {outputName} =l alloc8 {totalArraySize}"); _builder.AppendLine($" storel {capacity}, {outputName}"); - var dataPtr = VarName(); + var dataPtr = NewTmp(); _builder.AppendLine($" {dataPtr} =l add {outputName}, 8"); _builder.AppendLine($" call $nub_memset(l {dataPtr}, w 0, l {capacityInBytes})"); return outputName; } - private static string GenerateDereference(DereferenceNode dereference) + private static Tmp GenerateDereference(DereferenceNode dereference) { var result = GenerateExpression(dereference.Expression); - var outputName = VarName(); + var outputName = NewTmp(); _builder.AppendLine($" {outputName} {QBEAssign(dereference.Type)} {QBELoad(dereference.Type)} {result}"); return outputName; } - private static string GenerateAddressOf(AddressOfNode addressOf) + private static Tmp GenerateAddressOf(AddressOfNode addressOf) { switch (addressOf.Expression) { @@ -825,7 +827,7 @@ public static class QBEGenerator throw new NotSupportedException("There is nothing to address in another namespace"); } - return _variables.Single(x => x.Name == identifier.Name).GeneratedName; + return _variables.Single(x => x.Name == identifier.Name).Tmp; case MemberAccessNode memberAccess: return GenerateMemberAccessPointer(memberAccess); default: @@ -833,11 +835,11 @@ public static class QBEGenerator } } - private static string GenerateBinaryExpression(BinaryExpressionNode binaryExpression) + private static Tmp GenerateBinaryExpression(BinaryExpressionNode binaryExpression) { var left = GenerateExpression(binaryExpression.Left); var right = GenerateExpression(binaryExpression.Right); - var outputName = VarName(); + var outputName = NewTmp(); switch (binaryExpression.Operator) { @@ -1046,11 +1048,11 @@ public static class QBEGenerator throw new NotSupportedException($"Binary operator {binaryExpression.Operator} for types {binaryExpression.Left.Type} and {binaryExpression.Right.Type} not supported"); } - private static string GenerateIdentifier(IdentifierNode identifier) + private static Tmp GenerateIdentifier(IdentifierNode identifier) { if (_definitionTable.LookupFunc(identifier.Namespace.Or(_compilationUnit.Namespace), identifier.Name).TryGetValue(out var func)) { - return FuncName(func); + return new Tmp(FuncName(func)); } if (!identifier.Namespace.HasValue) @@ -1058,12 +1060,12 @@ public static class QBEGenerator var variable = _variables.Single(v => v.Name == identifier.Name); if (IsPointerType(identifier.Type)) { - return variable.GeneratedName; + return variable.Tmp; } else { - var output = VarName(); - _builder.AppendLine($" {output} {QBEAssign(identifier.Type)} {QBELoad(identifier.Type)} {variable.GeneratedName}"); + var output = NewTmp(); + _builder.AppendLine($" {output} {QBEAssign(identifier.Type)} {QBELoad(identifier.Type)} {variable.Tmp}"); return output; } } @@ -1071,16 +1073,16 @@ public static class QBEGenerator throw new UnreachableException(); } - private static string GenerateLiteral(LiteralNode literal) + private static Tmp GenerateLiteral(LiteralNode literal) { if (literal.Type.IsInteger) { switch (literal.Kind) { case LiteralKind.Integer: - return literal.Literal; + return new Tmp(literal.Literal); case LiteralKind.Float: - return literal.Literal.Split(".").First(); + return new Tmp(literal.Literal.Split(".").First()); default: throw new ArgumentOutOfRangeException(); } @@ -1090,33 +1092,33 @@ public static class QBEGenerator { var value = double.Parse(literal.Literal, CultureInfo.InvariantCulture); var bits = BitConverter.DoubleToInt64Bits(value); - return bits.ToString(); + return new Tmp(bits.ToString()); } if (literal.Type.IsFloat32) { var value = float.Parse(literal.Literal, CultureInfo.InvariantCulture); var bits = BitConverter.SingleToInt32Bits(value); - return bits.ToString(); + return new Tmp(bits.ToString()); } switch (literal.Kind) { case LiteralKind.String: _strings.Add(literal.Literal); - return $"$string{_strings.Count}"; + return new Tmp($"$string{_strings.Count}"); case LiteralKind.Bool: - return bool.Parse(literal.Literal) ? "1" : "0"; + return new Tmp(bool.Parse(literal.Literal) ? "1" : "0"); default: throw new ArgumentOutOfRangeException(); } } - private static string GenerateStructInitializer(StructInitializerNode structInitializer) + private static Tmp GenerateStructInitializer(StructInitializerNode structInitializer) { var structDefinition = _definitionTable.LookupStruct(structInitializer.StructType.Namespace, structInitializer.StructType.Name).GetValue(); - var structVar = VarName(); + var structVar = NewTmp(); var size = SizeOf(structInitializer.StructType); _builder.AppendLine($" {structVar} =l alloc8 {size}"); @@ -1127,14 +1129,14 @@ public static class QBEGenerator if (structInitializer.Initializers.TryGetValue(field.Name, out var fieldValue)) { var value = GenerateExpression(fieldValue); - var pointer = VarName(); + var pointer = NewTmp(); _builder.AppendLine($" {pointer} =l add {structVar}, {offset}"); GenerateCopy(field.Type, value, pointer); } else if (field.Value.HasValue) { var value = GenerateExpression(field.Value.Value); - var pointer = VarName(); + var pointer = NewTmp(); _builder.AppendLine($" {pointer} =l add {structVar}, {offset}"); GenerateCopy(field.Type, value, pointer); } @@ -1147,10 +1149,10 @@ public static class QBEGenerator return structVar; } - private static string GenerateUnaryExpression(UnaryExpressionNode unaryExpression) + private static Tmp GenerateUnaryExpression(UnaryExpressionNode unaryExpression) { var operand = GenerateExpression(unaryExpression.Operand); - var outputName = VarName(); + var outputName = NewTmp(); switch (unaryExpression.Operator) { @@ -1194,7 +1196,7 @@ public static class QBEGenerator throw new NotSupportedException($"Unary operator {unaryExpression.Operator} for type {unaryExpression.Operand.Type} not supported"); } - private static string GenerateMemberAccessPointer(MemberAccessNode memberAccess) + private static Tmp GenerateMemberAccessPointer(MemberAccessNode memberAccess) { var item = GenerateExpression(memberAccess.Expression); switch (memberAccess.Expression.Type) @@ -1213,7 +1215,7 @@ public static class QBEGenerator var structDefinition = _definitionTable.LookupStruct(structType.Namespace, structType.Name).GetValue(); var offset = OffsetOf(structDefinition, memberAccess.Member); - var offsetName = VarName(); + var offsetName = NewTmp(); _builder.AppendLine($" {offsetName} =l add {item}, {offset}"); return offsetName; } @@ -1224,7 +1226,7 @@ public static class QBEGenerator } } - private static string GenerateMemberAccess(MemberAccessNode memberAccess) + private static Tmp GenerateMemberAccess(MemberAccessNode memberAccess) { var pointer = GenerateMemberAccessPointer(memberAccess); @@ -1234,21 +1236,21 @@ public static class QBEGenerator } else { - var outputName = VarName(); + var outputName = NewTmp(); _builder.AppendLine($" {outputName} {QBEAssign(memberAccess.Type)} {QBELoad(memberAccess.Type)} {pointer}"); return outputName; } } - private static string GenerateFixedArrayInitializer(FixedArrayInitializerNode fixedArrayInitializer) + private static Tmp GenerateFixedArrayInitializer(FixedArrayInitializerNode fixedArrayInitializer) { var totalSize = SizeOf(fixedArrayInitializer.Type); - var outputName = VarName(); + var outputName = NewTmp(); _builder.AppendLine($" {outputName} =l alloc8 {totalSize}"); _builder.AppendLine($" storel {fixedArrayInitializer.Capacity}, {outputName}"); - var dataPtr = VarName(); + var dataPtr = NewTmp(); _builder.AppendLine($" {dataPtr} =l add {outputName}, 8"); var dataSize = totalSize - 8; @@ -1257,7 +1259,7 @@ public static class QBEGenerator return outputName; } - private static string GenerateFuncCall(FuncCallNode funcCall) + private static Tmp GenerateFuncCall(FuncCallNode funcCall) { var funcType = (NubFuncType)funcCall.Expression.Type; @@ -1300,34 +1302,34 @@ public static class QBEGenerator if (funcType.ReturnType is not NubVoidType) { - var outputName = VarName(); + var outputName = NewTmp(); _builder.AppendLine($" {outputName} {QBEAssign(funcCall.Type)} call {funcPointer}({string.Join(", ", parameterStrings)})"); return outputName; } else { _builder.AppendLine($" call {funcPointer}({string.Join(", ", parameterStrings)})"); - return "fuck"; + return new Tmp("fuck"); } } - private static void GenerateCopy(NubType type, string value, string destinationPointer) + private static void GenerateCopy(NubType type, Tmp source, Tmp destination) { if (SizeOf(type) > 8) { - _builder.AppendLine($" blit {value}, {destinationPointer}, {SizeOf(type)}"); + _builder.AppendLine($" blit {source}, {destination}, {SizeOf(type)}"); } else { - _builder.AppendLine($" {QBEStore(type)} {value}, {destinationPointer}"); + _builder.AppendLine($" {QBEStore(type)} {source}, {destination}"); } } } -internal class Variable(string name, string generatedName) +internal class Variable(string name, Tmp tmp) { public string Name { get; init; } = name; - public string GeneratedName { get; init; } = generatedName; + public Tmp Tmp { get; init; } = tmp; public bool Initialized { get; private set; } public Variable Assign() @@ -1336,3 +1338,11 @@ internal class Variable(string name, string generatedName) return this; } } + +internal record Tmp(string Name) +{ + public override string ToString() + { + return Name; + } +} \ No newline at end of file