This commit is contained in:
nub31
2025-06-14 18:14:53 +02:00
parent 4a3de81d97
commit fef54cc538

View File

@@ -76,6 +76,16 @@ public static class QBEGenerator
return _builder.ToString(); return _builder.ToString();
} }
private static string VarName()
{
return $"%v{++_variableIndex}";
}
private static string LabelName()
{
return $"@l{++_labelIndex}";
}
private static string FuncName(IFuncSignature func) private static string FuncName(IFuncSignature func)
{ {
return func switch return func switch
@@ -393,19 +403,19 @@ public static class QBEGenerator
switch (primitiveType.Kind) switch (primitiveType.Kind)
{ {
case PrimitiveTypeKind.I16: case PrimitiveTypeKind.I16:
parameterName = GenVarName(); parameterName = VarName();
_builder.AppendLine($" {parameterName} =w extsh %{parameter.Name}"); _builder.AppendLine($" {parameterName} =w extsh %{parameter.Name}");
break; break;
case PrimitiveTypeKind.I8: case PrimitiveTypeKind.I8:
parameterName = GenVarName(); parameterName = VarName();
_builder.AppendLine($" {parameterName} =w extsb %{parameter.Name}"); _builder.AppendLine($" {parameterName} =w extsb %{parameter.Name}");
break; break;
case PrimitiveTypeKind.U16: case PrimitiveTypeKind.U16:
parameterName = GenVarName(); parameterName = VarName();
_builder.AppendLine($" {parameterName} =w extuh %{parameter.Name}"); _builder.AppendLine($" {parameterName} =w extuh %{parameter.Name}");
break; break;
case PrimitiveTypeKind.U8: case PrimitiveTypeKind.U8:
parameterName = GenVarName(); parameterName = VarName();
_builder.AppendLine($" {parameterName} =w extub %{parameter.Name}"); _builder.AppendLine($" {parameterName} =w extub %{parameter.Name}");
break; break;
} }
@@ -514,13 +524,13 @@ public static class QBEGenerator
{ {
case NubArrayType arrayType: case NubArrayType arrayType:
{ {
var startName = GenVarName(); var startName = VarName();
_builder.AppendLine($" {startName} =l add {array}, 8"); _builder.AppendLine($" {startName} =l add {array}, 8");
var adjustedIndex = GenVarName(); var adjustedIndex = VarName();
_builder.AppendLine($" {adjustedIndex} =l mul {index}, {SizeOf(arrayType.ElementType)}"); _builder.AppendLine($" {adjustedIndex} =l mul {index}, {SizeOf(arrayType.ElementType)}");
var pointer = GenVarName(); var pointer = VarName();
_builder.AppendLine($" {pointer} =l add {startName}, {adjustedIndex}"); _builder.AppendLine($" {pointer} =l add {startName}, {adjustedIndex}");
GenerateCopy(arrayType.ElementType, value, pointer); GenerateCopy(arrayType.ElementType, value, pointer);
@@ -528,13 +538,13 @@ public static class QBEGenerator
} }
case NubFixedArrayType fixedArrayType: case NubFixedArrayType fixedArrayType:
{ {
var startName = GenVarName(); var startName = VarName();
_builder.AppendLine($" {startName} =l add {array}, 8"); _builder.AppendLine($" {startName} =l add {array}, 8");
var adjustedIndex = GenVarName(); var adjustedIndex = VarName();
_builder.AppendLine($" {adjustedIndex} =l mul {index}, {SizeOf(fixedArrayType.ElementType)}"); _builder.AppendLine($" {adjustedIndex} =l mul {index}, {SizeOf(fixedArrayType.ElementType)}");
var pointer = GenVarName(); var pointer = VarName();
_builder.AppendLine($" {pointer} =l add {startName}, {adjustedIndex}"); _builder.AppendLine($" {pointer} =l add {startName}, {adjustedIndex}");
GenerateCopy(fixedArrayType.ElementType, value, pointer); GenerateCopy(fixedArrayType.ElementType, value, pointer);
@@ -593,9 +603,9 @@ public static class QBEGenerator
private static void GenerateIf(IfNode ifStatement) private static void GenerateIf(IfNode ifStatement)
{ {
var trueLabel = GenLabelName(); var trueLabel = LabelName();
var falseLabel = GenLabelName(); var falseLabel = LabelName();
var endLabel = GenLabelName(); var endLabel = LabelName();
var result = GenerateExpression(ifStatement.Condition); var result = GenerateExpression(ifStatement.Condition);
_builder.AppendLine($" jnz {result}, {trueLabel}, {falseLabel}"); _builder.AppendLine($" jnz {result}, {trueLabel}, {falseLabel}");
@@ -624,7 +634,7 @@ public static class QBEGenerator
var offset = LookupMemberOffset(structDefinition, memberAssignment.MemberAccess.Member); var offset = LookupMemberOffset(structDefinition, memberAssignment.MemberAccess.Member);
var item = GenerateExpression(memberAssignment.MemberAccess.Expression); var item = GenerateExpression(memberAssignment.MemberAccess.Expression);
var pointer = GenVarName(); var pointer = VarName();
_builder.AppendLine($" {pointer} =l add {item}, {offset}"); _builder.AppendLine($" {pointer} =l add {item}, {offset}");
@@ -649,7 +659,7 @@ public static class QBEGenerator
private static void GenerateVariableDeclaration(VariableDeclarationNode variableDeclaration) private static void GenerateVariableDeclaration(VariableDeclarationNode variableDeclaration)
{ {
var type = variableDeclaration.ExplicitType.Value ?? variableDeclaration.Value.Value!.Type; var type = variableDeclaration.ExplicitType.Value ?? variableDeclaration.Value.Value!.Type;
var pointer = GenVarName(); var pointer = VarName();
_builder.AppendLine($" {pointer} =l alloc8 {SizeOf(type)}"); _builder.AppendLine($" {pointer} =l alloc8 {SizeOf(type)}");
if (variableDeclaration.Value.HasValue) if (variableDeclaration.Value.HasValue)
@@ -659,7 +669,7 @@ public static class QBEGenerator
} }
else else
{ {
var pointerName = GenVarName(); var pointerName = VarName();
_variables.Push((variableDeclaration.Name, pointerName)); _variables.Push((variableDeclaration.Name, pointerName));
} }
@@ -675,9 +685,9 @@ public static class QBEGenerator
private static void GenerateWhile(WhileNode whileStatement) private static void GenerateWhile(WhileNode whileStatement)
{ {
var conditionLabel = GenLabelName(); var conditionLabel = LabelName();
var iterationLabel = GenLabelName(); var iterationLabel = LabelName();
var endLabel = GenLabelName(); var endLabel = LabelName();
_breakLabels.Push(endLabel); _breakLabels.Push(endLabel);
_continueLabels.Push(conditionLabel); _continueLabels.Push(conditionLabel);
@@ -719,7 +729,7 @@ public static class QBEGenerator
{ {
var name = $"$anon_func{++_anonymousFuncIndex}"; var name = $"$anon_func{++_anonymousFuncIndex}";
_anonymousFunctions.Enqueue((anonymousFunc, name)); _anonymousFunctions.Enqueue((anonymousFunc, name));
var pointer = GenVarName(); var pointer = VarName();
_builder.AppendLine($" {pointer} =l alloc8 8"); _builder.AppendLine($" {pointer} =l alloc8 8");
_builder.AppendLine($" storel {name}, {pointer}"); _builder.AppendLine($" storel {name}, {pointer}");
return pointer; return pointer;
@@ -735,21 +745,21 @@ public static class QBEGenerator
{ {
case NubArrayType arrayType: case NubArrayType arrayType:
{ {
var firstItemPointerName = GenVarName(); var firstItemPointerName = VarName();
_builder.AppendLine($" {firstItemPointerName} =l add {array}, 8"); _builder.AppendLine($" {firstItemPointerName} =l add {array}, 8");
var offsetPointerName = GenVarName(); var offsetPointerName = VarName();
_builder.AppendLine($" {offsetPointerName} =l mul {index}, {SizeOf(arrayType.ElementType)}"); _builder.AppendLine($" {offsetPointerName} =l mul {index}, {SizeOf(arrayType.ElementType)}");
var resultPointerName = GenVarName(); var resultPointerName = VarName();
_builder.AppendLine($" {resultPointerName} =l add {firstItemPointerName}, {offsetPointerName}"); _builder.AppendLine($" {resultPointerName} =l add {firstItemPointerName}, {offsetPointerName}");
return resultPointerName; return resultPointerName;
} }
case NubFixedArrayType fixedArrayType: case NubFixedArrayType fixedArrayType:
{ {
var firstItemPointerName = GenVarName(); var firstItemPointerName = VarName();
_builder.AppendLine($" {firstItemPointerName} =l add {array}, 8"); _builder.AppendLine($" {firstItemPointerName} =l add {array}, 8");
var offsetPointerName = GenVarName(); var offsetPointerName = VarName();
_builder.AppendLine($" {offsetPointerName} =l mul {index}, {SizeOf(fixedArrayType.ElementType)}"); _builder.AppendLine($" {offsetPointerName} =l mul {index}, {SizeOf(fixedArrayType.ElementType)}");
var resultPointerName = GenVarName(); var resultPointerName = VarName();
_builder.AppendLine($" {resultPointerName} =l add {firstItemPointerName}, {offsetPointerName}"); _builder.AppendLine($" {resultPointerName} =l add {firstItemPointerName}, {offsetPointerName}");
return resultPointerName; return resultPointerName;
} }
@@ -770,7 +780,7 @@ public static class QBEGenerator
} }
else else
{ {
var outputName = GenVarName(); var outputName = VarName();
_builder.AppendLine($" {outputName} {QBEAssign(arrayIndexAccess.Type)} {QBELoad(arrayIndexAccess.Type)} {pointerName}"); _builder.AppendLine($" {outputName} {QBEAssign(arrayIndexAccess.Type)} {QBELoad(arrayIndexAccess.Type)} {pointerName}");
return outputName; return outputName;
} }
@@ -778,20 +788,20 @@ public static class QBEGenerator
private static void GenerateArrayBoundsCheck(string array, string index) private static void GenerateArrayBoundsCheck(string array, string index)
{ {
var countName = GenVarName(); var countName = VarName();
_builder.AppendLine($" {countName} =l loadl {array}"); _builder.AppendLine($" {countName} =l loadl {array}");
var isNegativeName = GenVarName(); var isNegativeName = VarName();
_builder.AppendLine($" {isNegativeName} =w csltl {index}, 0"); _builder.AppendLine($" {isNegativeName} =w csltl {index}, 0");
var isOobName = GenVarName(); var isOobName = VarName();
_builder.AppendLine($" {isOobName} =w csgel {index}, {countName}"); _builder.AppendLine($" {isOobName} =w csgel {index}, {countName}");
var anyOobName = GenVarName(); var anyOobName = VarName();
_builder.AppendLine($" {anyOobName} =w or {isNegativeName}, {isOobName}"); _builder.AppendLine($" {anyOobName} =w or {isNegativeName}, {isOobName}");
var oobLabel = GenLabelName(); var oobLabel = LabelName();
var notOobLabel = GenLabelName(); var notOobLabel = LabelName();
_builder.AppendLine($" jnz {anyOobName}, {oobLabel}, {notOobLabel}"); _builder.AppendLine($" jnz {anyOobName}, {oobLabel}, {notOobLabel}");
_builder.AppendLine(oobLabel); _builder.AppendLine(oobLabel);
@@ -804,15 +814,15 @@ public static class QBEGenerator
{ {
var capacity = GenerateExpression(arrayInitializer.Capacity); var capacity = GenerateExpression(arrayInitializer.Capacity);
var elementSize = SizeOf(arrayInitializer.ElementType); var elementSize = SizeOf(arrayInitializer.ElementType);
var capacityInBytes = GenVarName(); var capacityInBytes = VarName();
_builder.AppendLine($" {capacityInBytes} =l mul {capacity}, {elementSize}"); _builder.AppendLine($" {capacityInBytes} =l mul {capacity}, {elementSize}");
var totalArraySize = GenVarName(); var totalArraySize = VarName();
_builder.AppendLine($" {totalArraySize} =l add {capacityInBytes}, 8"); _builder.AppendLine($" {totalArraySize} =l add {capacityInBytes}, 8");
var outputName = GenVarName(); var outputName = VarName();
_builder.AppendLine($" {outputName} =l alloc8 {totalArraySize}"); _builder.AppendLine($" {outputName} =l alloc8 {totalArraySize}");
_builder.AppendLine($" storel {capacity}, {outputName}"); _builder.AppendLine($" storel {capacity}, {outputName}");
var dataPtr = GenVarName(); var dataPtr = VarName();
_builder.AppendLine($" {dataPtr} =l add {outputName}, 8"); _builder.AppendLine($" {dataPtr} =l add {outputName}, 8");
_builder.AppendLine($" call $nub_memset(l {dataPtr}, w 0, l {capacityInBytes})"); _builder.AppendLine($" call $nub_memset(l {dataPtr}, w 0, l {capacityInBytes})");
@@ -822,7 +832,7 @@ public static class QBEGenerator
private static string GenerateDereference(DereferenceNode dereference) private static string GenerateDereference(DereferenceNode dereference)
{ {
var result = GenerateExpression(dereference.Expression); var result = GenerateExpression(dereference.Expression);
var outputName = GenVarName(); var outputName = VarName();
_builder.AppendLine($" {outputName} {QBEAssign(dereference.Type)} {QBELoad(dereference.Type)} {result}"); _builder.AppendLine($" {outputName} {QBEAssign(dereference.Type)} {QBELoad(dereference.Type)} {result}");
return outputName; return outputName;
} }
@@ -852,7 +862,7 @@ public static class QBEGenerator
{ {
var left = GenerateExpression(binaryExpression.Left); var left = GenerateExpression(binaryExpression.Left);
var right = GenerateExpression(binaryExpression.Right); var right = GenerateExpression(binaryExpression.Right);
var outputName = GenVarName(); var outputName = VarName();
switch (binaryExpression.Operator) switch (binaryExpression.Operator)
{ {
@@ -1078,7 +1088,7 @@ public static class QBEGenerator
{ {
if (_definitionTable.LookupFunc(identifier.Namespace.Or(_compilationUnit.Namespace), identifier.Name).TryGetValue(out var func)) if (_definitionTable.LookupFunc(identifier.Namespace.Or(_compilationUnit.Namespace), identifier.Name).TryGetValue(out var func))
{ {
var pointer = GenVarName(); var pointer = VarName();
_builder.AppendLine($" {pointer} =l alloc8 8"); _builder.AppendLine($" {pointer} =l alloc8 8");
_builder.AppendLine($" storel {FuncName(func)}, {pointer}"); _builder.AppendLine($" storel {FuncName(func)}, {pointer}");
return pointer; return pointer;
@@ -1139,7 +1149,7 @@ public static class QBEGenerator
{ {
var structDefinition = _definitionTable.LookupStruct(structInitializer.StructType.Namespace, structInitializer.StructType.Name).GetValue(); var structDefinition = _definitionTable.LookupStruct(structInitializer.StructType.Namespace, structInitializer.StructType.Name).GetValue();
var structVar = GenVarName(); var structVar = VarName();
var size = SizeOf(structInitializer.StructType); var size = SizeOf(structInitializer.StructType);
_builder.AppendLine($" {structVar} =l alloc8 {size}"); _builder.AppendLine($" {structVar} =l alloc8 {size}");
@@ -1150,14 +1160,14 @@ public static class QBEGenerator
if (structInitializer.Initializers.TryGetValue(field.Name, out var fieldValue)) if (structInitializer.Initializers.TryGetValue(field.Name, out var fieldValue))
{ {
var value = GenerateExpression(fieldValue); var value = GenerateExpression(fieldValue);
var pointer = GenVarName(); var pointer = VarName();
_builder.AppendLine($" {pointer} =l add {structVar}, {offset}"); _builder.AppendLine($" {pointer} =l add {structVar}, {offset}");
GenerateCopy(field.Type, value, pointer); GenerateCopy(field.Type, value, pointer);
} }
else if (field.Value.HasValue) else if (field.Value.HasValue)
{ {
var value = GenerateExpression(field.Value.Value); var value = GenerateExpression(field.Value.Value);
var pointer = GenVarName(); var pointer = VarName();
_builder.AppendLine($" {pointer} =l add {structVar}, {offset}"); _builder.AppendLine($" {pointer} =l add {structVar}, {offset}");
GenerateCopy(field.Type, value, pointer); GenerateCopy(field.Type, value, pointer);
} }
@@ -1173,7 +1183,7 @@ public static class QBEGenerator
private static string GenerateUnaryExpression(UnaryExpressionNode unaryExpression) private static string GenerateUnaryExpression(UnaryExpressionNode unaryExpression)
{ {
var operand = GenerateExpression(unaryExpression.Operand); var operand = GenerateExpression(unaryExpression.Operand);
var outputName = GenVarName(); var outputName = VarName();
switch (unaryExpression.Operator) switch (unaryExpression.Operator)
{ {
@@ -1236,7 +1246,7 @@ public static class QBEGenerator
var structDefinition = _definitionTable.LookupStruct(structType.Namespace, structType.Name).GetValue(); var structDefinition = _definitionTable.LookupStruct(structType.Namespace, structType.Name).GetValue();
var offset = LookupMemberOffset(structDefinition, memberAccess.Member); var offset = LookupMemberOffset(structDefinition, memberAccess.Member);
var offsetName = GenVarName(); var offsetName = VarName();
_builder.AppendLine($" {offsetName} =l add {item}, {offset}"); _builder.AppendLine($" {offsetName} =l add {item}, {offset}");
return offsetName; return offsetName;
} }
@@ -1257,7 +1267,7 @@ public static class QBEGenerator
} }
else else
{ {
var outputName = GenVarName(); var outputName = VarName();
_builder.AppendLine($" {outputName} {QBEAssign(memberAccess.Type)} {QBELoad(memberAccess.Type)} {pointer}"); _builder.AppendLine($" {outputName} {QBEAssign(memberAccess.Type)} {QBELoad(memberAccess.Type)} {pointer}");
return outputName; return outputName;
} }
@@ -1266,12 +1276,12 @@ public static class QBEGenerator
private static string GenerateFixedArrayInitializer(FixedArrayInitializerNode fixedArrayInitializer) private static string GenerateFixedArrayInitializer(FixedArrayInitializerNode fixedArrayInitializer)
{ {
var totalSize = SizeOf(fixedArrayInitializer.Type); var totalSize = SizeOf(fixedArrayInitializer.Type);
var outputName = GenVarName(); var outputName = VarName();
_builder.AppendLine($" {outputName} =l alloc8 {totalSize}"); _builder.AppendLine($" {outputName} =l alloc8 {totalSize}");
_builder.AppendLine($" storel {fixedArrayInitializer.Capacity}, {outputName}"); _builder.AppendLine($" storel {fixedArrayInitializer.Capacity}, {outputName}");
var dataPtr = GenVarName(); var dataPtr = VarName();
_builder.AppendLine($" {dataPtr} =l add {outputName}, 8"); _builder.AppendLine($" {dataPtr} =l add {outputName}, 8");
var dataSize = totalSize - 8; var dataSize = totalSize - 8;
@@ -1326,14 +1336,14 @@ public static class QBEGenerator
else else
{ {
var funcPointerPointer = GenerateExpression(funcCall.Expression); var funcPointerPointer = GenerateExpression(funcCall.Expression);
var funcPointer = GenVarName(); var funcPointer = VarName();
_builder.AppendLine($" {funcPointer} =l loadl {funcPointerPointer}"); _builder.AppendLine($" {funcPointer} =l loadl {funcPointerPointer}");
funcTarget = funcPointer; funcTarget = funcPointer;
} }
if (funcType.ReturnType is not NubVoidType) if (funcType.ReturnType is not NubVoidType)
{ {
var outputName = GenVarName(); var outputName = VarName();
_builder.AppendLine($" {outputName} {QBEAssign(funcCall.Type)} call {funcTarget}({string.Join(", ", parameterStrings)})"); _builder.AppendLine($" {outputName} {QBEAssign(funcCall.Type)} call {funcTarget}({string.Join(", ", parameterStrings)})");
return outputName; return outputName;
} }
@@ -1364,22 +1374,12 @@ public static class QBEGenerator
} }
else else
{ {
var result = GenVarName(); var result = VarName();
_builder.AppendLine($" {result} {QBEAssign(type)} {QBELoad(type)} {pointer}"); _builder.AppendLine($" {result} {QBEAssign(type)} {QBELoad(type)} {pointer}");
return result; return result;
} }
} }
private static string GenVarName()
{
return $"%v{++_variableIndex}";
}
private static string GenLabelName()
{
return $"@l{++_labelIndex}";
}
private static int LookupMemberOffset(StructDefinitionNode structDefinition, string member) private static int LookupMemberOffset(StructDefinitionNode structDefinition, string member)
{ {
var offset = 0; var offset = 0;