From fefb86c20731f7364e64beb7a479603cd9e7f8ae Mon Sep 17 00:00:00 2001 From: nub31 Date: Sat, 21 Jun 2025 17:57:45 +0200 Subject: [PATCH] ... --- example/main.nub | 16 +- src/CLI/Program.cs | 2 +- src/Generation/QBE/QBEGenerator.cs | 248 ++++++++++++++--------------- 3 files changed, 136 insertions(+), 130 deletions(-) diff --git a/example/main.nub b/example/main.nub index 35a902e..8c1e401 100644 --- a/example/main.nub +++ b/example/main.nub @@ -8,10 +8,24 @@ export func main(args: []cstring): i64 { let human: Human human = alloc Human { - name = "test" + name = "member" } c::puts(human.name) + c::puts("literal") + + let x: cstring + + x = "variable" + + c::puts(x) + + let y: func(cstring) + + y = c::puts + + y("proxy") + return 0 } diff --git a/src/CLI/Program.cs b/src/CLI/Program.cs index d23090a..411c24c 100644 --- a/src/CLI/Program.cs +++ b/src/CLI/Program.cs @@ -84,7 +84,7 @@ foreach (var compilationUnit in compilationUnits) Debug.Assert(!string.IsNullOrWhiteSpace(outputDirectory)); Directory.CreateDirectory(outputDirectory); - var ssa = QBEGenerator.Generate(compilationUnit, definitionTable); + var ssa = QBEGenerator.Emit(compilationUnit, definitionTable); var ssaPath = Path.ChangeExtension(outputPath, "ssa"); File.WriteAllText(ssaPath, ssa); diff --git a/src/Generation/QBE/QBEGenerator.cs b/src/Generation/QBE/QBEGenerator.cs index fe7d444..0c603b6 100644 --- a/src/Generation/QBE/QBEGenerator.cs +++ b/src/Generation/QBE/QBEGenerator.cs @@ -28,7 +28,7 @@ public static class QBEGenerator private static int _anonymousFuncIndex; private static bool _codeIsReachable = true; - public static string Generate(CompilationUnit compilationUnit, DefinitionTable definitionTable) + public static string Emit(CompilationUnit compilationUnit, DefinitionTable definitionTable) { _compilationUnit = compilationUnit; _definitionTable = definitionTable; @@ -47,19 +47,19 @@ public static class QBEGenerator foreach (var structDef in _definitionTable.GetStructs()) { - GenerateStructDefinition(structDef); + EmitStructDefinition(structDef); _builder.AppendLine(); } foreach (var funcDef in _compilationUnit.Definitions.OfType()) { - GenerateFuncDefinition(FuncName(funcDef), funcDef.Parameters, funcDef.ReturnType, funcDef.Body, funcDef.Exported); + EmitFuncDefinition(FuncName(funcDef), funcDef.Parameters, funcDef.ReturnType, funcDef.Body, funcDef.Exported); _builder.AppendLine(); } while (_anonymousFunctions.TryDequeue(out var anon)) { - GenerateFuncDefinition(anon.Name, anon.Func.Parameters, anon.Func.ReturnType, anon.Func.Body, false); + EmitFuncDefinition(anon.Name, anon.Func.Parameters, anon.Func.ReturnType, anon.Func.Body, false); _builder.AppendLine(); } @@ -305,10 +305,15 @@ public static class QBEGenerator private static bool IsPointerType(NubType type) { - return type is NubStructType or NubArrayType or NubFixedArrayType; + if (type.IsVoid) + { + throw new InvalidOperationException($"{nameof(IsPointerType)} should not be called on void types"); + } + + return type is NubStructType or NubFixedArrayType; } - private static void GenerateFuncDefinition(string name, List parameters, NubType returnType, BlockNode body, bool exported) + private static void EmitFuncDefinition(string name, List parameters, NubType returnType, BlockNode body, bool exported) { _variables.Clear(); _variableScopes.Clear(); @@ -414,10 +419,10 @@ public static class QBEGenerator } } - parameterVars.Add(new Variable(parameter.Name, new Ident(parameterName, parameter.Type)).Assign()); + parameterVars.Add(new Variable(parameter.Name, new Ident(parameterName, parameter.Type))); } - GenerateBlock(body, parameterVars); + EmitBlock(body, parameterVars); if (body.Statements.LastOrDefault() is not ReturnNode) { @@ -430,7 +435,7 @@ public static class QBEGenerator _builder.AppendLine("}"); } - private static void GenerateStructDefinition(StructDefinitionNode structDefinition) + private static void EmitStructDefinition(StructDefinitionNode structDefinition) { _builder.Append($"type {StructName(structDefinition)} = {{ "); foreach (var structDefinitionField in structDefinition.Fields) @@ -466,54 +471,54 @@ public static class QBEGenerator _builder.AppendLine("}"); } - private static void GenerateStatement(StatementNode statement) + private static void EmitStatement(StatementNode statement) { switch (statement) { case ArrayIndexAssignmentNode arrayIndexAssignment: - GenerateArrayIndexAssignment(arrayIndexAssignment); + EmitArrayIndexAssignment(arrayIndexAssignment); break; case BreakNode: - GenerateBreak(); + EmitBreak(); break; case ContinueNode: - GenerateContinue(); + EmitContinue(); break; case DereferenceAssignmentNode dereferenceAssignment: - GenerateDereferenceAssignment(dereferenceAssignment); + EmitDereferenceAssignment(dereferenceAssignment); break; case IfNode ifStatement: - GenerateIf(ifStatement); + EmitIf(ifStatement); break; case MemberAssignmentNode memberAssignment: - GenerateMemberAssignment(memberAssignment); + EmitMemberAssignment(memberAssignment); break; case ReturnNode @return: - GenerateReturn(@return); + EmitReturn(@return); break; case StatementExpressionNode statementExpression: - GenerateExpression(statementExpression.Expression); + EmitExpression(statementExpression.Expression); break; case VariableDeclarationNode variableDeclaration: - GenerateVariableDeclaration(variableDeclaration); + EmitVariableDeclaration(variableDeclaration); break; case VariableAssignmentNode variableAssignment: - GenerateVariableAssignment(variableAssignment); + EmitVariableAssignment(variableAssignment); break; case WhileNode whileStatement: - GenerateWhile(whileStatement); + EmitWhile(whileStatement); break; default: throw new ArgumentOutOfRangeException(nameof(statement)); } } - private static void GenerateArrayIndexAssignment(ArrayIndexAssignmentNode arrayIndexAssignment) + private static void EmitArrayIndexAssignment(ArrayIndexAssignmentNode arrayIndexAssignment) { - var array = Unwrap(GenerateExpression(arrayIndexAssignment.ArrayIndexAccess.Array)); - var index = Unwrap(GenerateExpression(arrayIndexAssignment.ArrayIndexAccess.Index)); - GenerateArrayBoundsCheck(array, index); - var value = Unwrap(GenerateExpression(arrayIndexAssignment.Value)); + var array = EmitUnwrap(EmitExpression(arrayIndexAssignment.ArrayIndexAccess.Array)); + var index = EmitUnwrap(EmitExpression(arrayIndexAssignment.ArrayIndexAccess.Index)); + EmitArrayBoundsCheck(array, index); + var value = EmitUnwrap(EmitExpression(arrayIndexAssignment.Value)); switch (arrayIndexAssignment.ArrayIndexAccess.Array.Type) { @@ -524,7 +529,7 @@ public static class QBEGenerator _builder.AppendLine($" {pointer} =l add {pointer}, 8"); _builder.AppendLine($" {pointer} =l add {array}, {pointer}"); - GenerateCopy(arrayType.ElementType, value, pointer); + EmitCopy(arrayType.ElementType, value, pointer); break; } case NubFixedArrayType fixedArrayType: @@ -534,7 +539,7 @@ public static class QBEGenerator _builder.AppendLine($" {pointer} =l add {pointer}, 8"); _builder.AppendLine($" {pointer} =l add {array}, {pointer}"); - GenerateCopy(fixedArrayType.ElementType, value, pointer); + EmitCopy(fixedArrayType.ElementType, value, pointer); break; } default: @@ -544,7 +549,7 @@ public static class QBEGenerator } } - private static void GenerateBlock(BlockNode block, List? variables = null) + private static void EmitBlock(BlockNode block, List? variables = null) { _variableScopes.Push(_variables.Count); if (variables != null) @@ -557,7 +562,7 @@ public static class QBEGenerator foreach (var statement in block.Statements.Where(_ => _codeIsReachable)) { - GenerateStatement(statement); + EmitStatement(statement); } var count = _variableScopes.Pop(); @@ -569,50 +574,50 @@ public static class QBEGenerator _codeIsReachable = true; } - private static void GenerateBreak() + private static void EmitBreak() { _builder.AppendLine($" jmp {_breakLabels.Peek()}"); _codeIsReachable = false; } - private static void GenerateContinue() + private static void EmitContinue() { _builder.AppendLine($" jmp {_continueLabels.Peek()}"); _codeIsReachable = false; } - private static void GenerateDereferenceAssignment(DereferenceAssignmentNode dereferenceAssignment) + private static void EmitDereferenceAssignment(DereferenceAssignmentNode dereferenceAssignment) { - var pointer = Unwrap(GenerateExpression(dereferenceAssignment.Dereference.Expression)); - var value = Unwrap(GenerateExpression(dereferenceAssignment.Value)); - GenerateCopy(dereferenceAssignment.Value.Type, value, pointer); + var pointer = EmitUnwrap(EmitExpression(dereferenceAssignment.Dereference.Expression)); + var value = EmitUnwrap(EmitExpression(dereferenceAssignment.Value)); + EmitCopy(dereferenceAssignment.Value.Type, value, pointer); } - private static void GenerateIf(IfNode ifStatement) + private static void EmitIf(IfNode ifStatement) { var trueLabel = LabelName(); var falseLabel = LabelName(); var endLabel = LabelName(); - var result = Unwrap(GenerateExpression(ifStatement.Condition)); + var result = EmitUnwrap(EmitExpression(ifStatement.Condition)); _builder.AppendLine($" jnz {result}, {trueLabel}, {falseLabel}"); _builder.AppendLine(trueLabel); - GenerateBlock(ifStatement.Body); + EmitBlock(ifStatement.Body); _builder.AppendLine($" jmp {endLabel}"); _builder.AppendLine(falseLabel); if (ifStatement.Else.HasValue) { ifStatement.Else.Value.Match ( - elseIfNode => GenerateIf(elseIfNode), - elseNode => GenerateBlock(elseNode) + elseIfNode => EmitIf(elseIfNode), + elseNode => EmitBlock(elseNode) ); } _builder.AppendLine(endLabel); } - private static void GenerateMemberAssignment(MemberAssignmentNode memberAssignment) + private static void EmitMemberAssignment(MemberAssignmentNode memberAssignment) { var structType = memberAssignment.MemberAccess.Expression.Type as NubStructType; Debug.Assert(structType != null); @@ -620,21 +625,21 @@ public static class QBEGenerator var structDefinition = _definitionTable.LookupStruct(structType.Namespace, structType.Name).GetValue(); var offset = OffsetOf(structDefinition, memberAssignment.MemberAccess.Member); - var item = Unwrap(GenerateExpression(memberAssignment.MemberAccess.Expression)); + var item = EmitUnwrap(EmitExpression(memberAssignment.MemberAccess.Expression)); var pointer = VarName(); _builder.AppendLine($" {pointer} =l add {item}, {offset}"); - var value = Unwrap(GenerateExpression(memberAssignment.Value)); + var value = EmitUnwrap(EmitExpression(memberAssignment.Value)); - GenerateCopy(memberAssignment.Value.Type, value, pointer); + EmitCopy(memberAssignment.Value.Type, value, pointer); } - private static void GenerateReturn(ReturnNode @return) + private static void EmitReturn(ReturnNode @return) { if (@return.Value.HasValue) { - var result = Unwrap(GenerateExpression(@return.Value.Value)); + var result = EmitUnwrap(EmitExpression(@return.Value.Value)); _builder.AppendLine($" ret {result}"); } else @@ -643,22 +648,21 @@ public static class QBEGenerator } } - private static void GenerateVariableDeclaration(VariableDeclarationNode variableDeclaration) + private static void EmitVariableDeclaration(VariableDeclarationNode variableDeclaration) { var tmp = VarName(); _builder.AppendLine($" {tmp} =l alloc8 {SizeOf(variableDeclaration.Type)}"); _variables.Push(new Variable(variableDeclaration.Name, new Ident(tmp, variableDeclaration.Type))); } - private static void GenerateVariableAssignment(VariableAssignmentNode variableAssignment) + private static void EmitVariableAssignment(VariableAssignmentNode variableAssignment) { - var value = Unwrap(GenerateExpression(variableAssignment.Value)); + var value = EmitUnwrap(EmitExpression(variableAssignment.Value)); var variable = _variables.Single(x => x.Name == variableAssignment.Identifier.Name); - GenerateCopy(variableAssignment.Value.Type, value, variable.Ident.Name); - variable.Assign(); + EmitCopy(variableAssignment.Value.Type, value, variable.Ident.Name); } - private static void GenerateWhile(WhileNode whileStatement) + private static void EmitWhile(WhileNode whileStatement) { var conditionLabel = LabelName(); var iterationLabel = LabelName(); @@ -669,9 +673,9 @@ public static class QBEGenerator _builder.AppendLine($" jmp {conditionLabel}"); _builder.AppendLine(iterationLabel); - GenerateBlock(whileStatement.Body); + EmitBlock(whileStatement.Body); _builder.AppendLine(conditionLabel); - var result = Unwrap(GenerateExpression(whileStatement.Condition)); + var result = EmitUnwrap(EmitExpression(whileStatement.Condition)); _builder.AppendLine($" jnz {result}, {iterationLabel}, {endLabel}"); _builder.AppendLine(endLabel); @@ -679,39 +683,39 @@ public static class QBEGenerator _breakLabels.Pop(); } - private static Ident GenerateExpression(ExpressionNode expression) + private static Ident EmitExpression(ExpressionNode expression) { return expression switch { - AddressOfNode addressOf => GenerateAddressOf(addressOf), - AnonymousFuncNode anonymousFunc => GenerateAnonymousFunc(anonymousFunc), - ArrayIndexAccessNode arrayIndex => GenerateArrayIndexAccess(arrayIndex), - ArrayInitializerNode arrayInitializer => GenerateArrayInitializer(arrayInitializer), - BinaryExpressionNode binaryExpression => GenerateBinaryExpression(binaryExpression), - DereferenceNode dereference => GenerateDereference(dereference), - FixedArrayInitializerNode fixedArrayInitializer => GenerateFixedArrayInitializer(fixedArrayInitializer), - FuncCallNode funcCallExpression => GenerateFuncCall(funcCallExpression), - IdentifierNode identifier => GenerateIdentifier(identifier), - LiteralNode literal => GenerateLiteral(literal), - StructInitializerNode structInitializer => GenerateStructInitializer(structInitializer), - UnaryExpressionNode unaryExpression => GenerateUnaryExpression(unaryExpression), - MemberAccessNode memberAccess => GenerateMemberAccess(memberAccess), + AddressOfNode addressOf => EmitAddressOf(addressOf), + AnonymousFuncNode anonymousFunc => EmitAnonymousFunc(anonymousFunc), + ArrayIndexAccessNode arrayIndex => EmitArrayIndexAccess(arrayIndex), + ArrayInitializerNode arrayInitializer => EmitArrayInitializer(arrayInitializer), + BinaryExpressionNode binaryExpression => EmitBinaryExpression(binaryExpression), + DereferenceNode dereference => EmitDereference(dereference), + FixedArrayInitializerNode fixedArrayInitializer => EmitFixedArrayInitializer(fixedArrayInitializer), + FuncCallNode funcCallExpression => EmitFuncCall(funcCallExpression), + IdentifierNode identifier => EmitIdentifier(identifier), + LiteralNode literal => EmitLiteral(literal), + StructInitializerNode structInitializer => EmitStructInitializer(structInitializer), + UnaryExpressionNode unaryExpression => EmitUnaryExpression(unaryExpression), + MemberAccessNode memberAccess => EmitMemberAccess(memberAccess), _ => throw new ArgumentOutOfRangeException(nameof(expression)) }; } - private static Ident GenerateAnonymousFunc(AnonymousFuncNode anonymousFunc) + private static Ident EmitAnonymousFunc(AnonymousFuncNode anonymousFunc) { var name = $"$anon_func{++_anonymousFuncIndex}"; _anonymousFunctions.Enqueue((anonymousFunc, name)); return new Ident(name, anonymousFunc.Type, IdentKind.Func); } - private static string GenerateArrayIndexPointer(ArrayIndexAccessNode arrayIndexAccess) + private static string EmitArrayIndexPointer(ArrayIndexAccessNode arrayIndexAccess) { - var array = Unwrap(GenerateExpression(arrayIndexAccess.Array)); - var index = Unwrap(GenerateExpression(arrayIndexAccess.Index)); - GenerateArrayBoundsCheck(array, index); + var array = EmitUnwrap(EmitExpression(arrayIndexAccess.Array)); + var index = EmitUnwrap(EmitExpression(arrayIndexAccess.Index)); + EmitArrayBoundsCheck(array, index); var elementType = arrayIndexAccess.Array.Type switch { @@ -727,15 +731,15 @@ public static class QBEGenerator return pointer; } - private static Ident GenerateArrayIndexAccess(ArrayIndexAccessNode arrayIndexAccess) + private static Ident EmitArrayIndexAccess(ArrayIndexAccessNode arrayIndexAccess) { - var pointer = GenerateArrayIndexPointer(arrayIndexAccess); + var pointer = EmitArrayIndexPointer(arrayIndexAccess); var outputName = VarName(); _builder.AppendLine($" {outputName} {QBEAssign(arrayIndexAccess.Type)} {QBELoad(arrayIndexAccess.Type)} {pointer}"); return new Ident(outputName, arrayIndexAccess.Type); } - private static void GenerateArrayBoundsCheck(string array, string index) + private static void EmitArrayBoundsCheck(string array, string index) { var count = VarName(); _builder.AppendLine($" {count} =l loadl {array}"); @@ -759,9 +763,9 @@ public static class QBEGenerator _builder.AppendLine(notOobLabel); } - private static Ident GenerateArrayInitializer(ArrayInitializerNode arrayInitializer) + private static Ident EmitArrayInitializer(ArrayInitializerNode arrayInitializer) { - var capacity = Unwrap(GenerateExpression(arrayInitializer.Capacity)); + var capacity = EmitUnwrap(EmitExpression(arrayInitializer.Capacity)); var elementSize = SizeOf(arrayInitializer.ElementType); var capacityInBytes = VarName(); @@ -780,23 +784,23 @@ public static class QBEGenerator return new Ident(arrayPointer, arrayInitializer.Type); } - private static Ident GenerateDereference(DereferenceNode dereference) + private static Ident EmitDereference(DereferenceNode dereference) { - var result = Unwrap(GenerateExpression(dereference.Expression)); + var result = EmitUnwrap(EmitExpression(dereference.Expression)); var outputName = VarName(); _builder.AppendLine($" {outputName} {QBEAssign(dereference.Type)} {QBELoad(dereference.Type)} {result}"); return new Ident(outputName, dereference.Type); } - private static Ident GenerateAddressOf(AddressOfNode addressOf) + private static Ident EmitAddressOf(AddressOfNode addressOf) { switch (addressOf.Expression) { case ArrayIndexAccessNode arrayIndexAccess: - var pointer = GenerateArrayIndexPointer(arrayIndexAccess); + var pointer = EmitArrayIndexPointer(arrayIndexAccess); return new Ident(pointer, addressOf.Type); case DereferenceNode dereference: - return GenerateExpression(dereference.Expression); + return EmitExpression(dereference.Expression); case IdentifierNode identifier: if (identifier.Namespace.HasValue) { @@ -805,17 +809,17 @@ public static class QBEGenerator return _variables.Single(x => x.Name == identifier.Name).Ident; case MemberAccessNode memberAccess: - var ptr = GenerateMemberAccessPointer(memberAccess); + var ptr = EmitMemberAccessPointer(memberAccess); return new Ident(ptr, addressOf.Type); default: throw new ArgumentOutOfRangeException(); } } - private static Ident GenerateBinaryExpression(BinaryExpressionNode binaryExpression) + private static Ident EmitBinaryExpression(BinaryExpressionNode binaryExpression) { - var left = Unwrap(GenerateExpression(binaryExpression.Left)); - var right = Unwrap(GenerateExpression(binaryExpression.Right)); + var left = EmitUnwrap(EmitExpression(binaryExpression.Left)); + var right = EmitUnwrap(EmitExpression(binaryExpression.Right)); var outputName = VarName(); var output = new Ident(outputName, binaryExpression.Type); @@ -1026,7 +1030,7 @@ public static class QBEGenerator throw new NotSupportedException($"Binary operator {binaryExpression.Operator} for types {binaryExpression.Left.Type} and {binaryExpression.Right.Type} not supported"); } - private static Ident GenerateIdentifier(IdentifierNode identifier) + private static Ident EmitIdentifier(IdentifierNode identifier) { if (_definitionTable.LookupFunc(identifier.Namespace.Or(_compilationUnit.Namespace), identifier.Name).TryGetValue(out var func)) { @@ -1035,23 +1039,13 @@ public static class QBEGenerator if (!identifier.Namespace.HasValue) { - var variable = _variables.Single(v => v.Name == identifier.Name); - if (IsPointerType(identifier.Type)) - { - return variable.Ident; - } - else - { - var output = VarName(); - _builder.AppendLine($" {output} {QBEAssign(identifier.Type)} {QBELoad(identifier.Type)} {variable.Ident}"); - return new Ident(output, identifier.Type); - } + return _variables.Single(v => v.Name == identifier.Name).Ident; } throw new UnreachableException(); } - private static Ident GenerateLiteral(LiteralNode literal) + private static Ident EmitLiteral(LiteralNode literal) { if (literal.Type.IsInteger) { @@ -1092,7 +1086,7 @@ public static class QBEGenerator } } - private static Ident GenerateStructInitializer(StructInitializerNode structInitializer) + private static Ident EmitStructInitializer(StructInitializerNode structInitializer) { var structDefinition = _definitionTable.LookupStruct(structInitializer.StructType.Namespace, structInitializer.StructType.Name).GetValue(); @@ -1106,17 +1100,17 @@ public static class QBEGenerator if (structInitializer.Initializers.TryGetValue(field.Name, out var fieldValue)) { - var value = Unwrap(GenerateExpression(fieldValue)); + var value = EmitUnwrap(EmitExpression(fieldValue)); var pointer = VarName(); _builder.AppendLine($" {pointer} =l add {output}, {offset}"); - GenerateCopy(field.Type, value, pointer); + EmitCopy(field.Type, value, pointer); } else if (field.Value.HasValue) { - var value = Unwrap(GenerateExpression(field.Value.Value)); + var value = EmitUnwrap(EmitExpression(field.Value.Value)); var pointer = VarName(); _builder.AppendLine($" {pointer} =l add {output}, {offset}"); - GenerateCopy(field.Type, value, pointer); + EmitCopy(field.Type, value, pointer); } else { @@ -1127,9 +1121,9 @@ public static class QBEGenerator return new Ident(output, structInitializer.StructType); } - private static Ident GenerateUnaryExpression(UnaryExpressionNode unaryExpression) + private static Ident EmitUnaryExpression(UnaryExpressionNode unaryExpression) { - var operand = Unwrap(GenerateExpression(unaryExpression.Operand)); + var operand = EmitUnwrap(EmitExpression(unaryExpression.Operand)); var outputName = VarName(); switch (unaryExpression.Operator) @@ -1174,9 +1168,9 @@ 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 string EmitMemberAccessPointer(MemberAccessNode memberAccess) { - var item = Unwrap(GenerateExpression(memberAccess.Expression)); + var item = EmitUnwrap(EmitExpression(memberAccess.Expression)); switch (memberAccess.Expression.Type) { case NubArrayType: @@ -1204,16 +1198,16 @@ public static class QBEGenerator } } - private static Ident GenerateMemberAccess(MemberAccessNode memberAccess) + private static Ident EmitMemberAccess(MemberAccessNode memberAccess) { - var pointer = GenerateMemberAccessPointer(memberAccess); + var pointer = EmitMemberAccessPointer(memberAccess); var output = VarName(); _builder.AppendLine($" {output} {QBEAssign(memberAccess.Type)} {QBELoad(memberAccess.Type)} {pointer}"); return new Ident(output, memberAccess.Type); } - private static Ident GenerateFixedArrayInitializer(FixedArrayInitializerNode fixedArrayInitializer) + private static Ident EmitFixedArrayInitializer(FixedArrayInitializerNode fixedArrayInitializer) { var totalSize = SizeOf(fixedArrayInitializer.Type); var outputName = VarName(); @@ -1230,7 +1224,7 @@ public static class QBEGenerator return new Ident(outputName, fixedArrayInitializer.Type); } - private static Ident GenerateFuncCall(FuncCallNode funcCall) + private static Ident EmitFuncCall(FuncCallNode funcCall) { var funcType = (NubFuncType)funcCall.Expression.Type; @@ -1239,7 +1233,7 @@ public static class QBEGenerator for (var i = 0; i < funcCall.Parameters.Count; i++) { var parameter = funcCall.Parameters[i]; - var result = Unwrap(GenerateExpression(parameter)); + var result = EmitUnwrap(EmitExpression(parameter)); var qbeType = parameter.Type switch { @@ -1269,7 +1263,7 @@ public static class QBEGenerator parameterStrings.Add($"{qbeType} {result}"); } - var funcPointer = Unwrap(GenerateExpression(funcCall.Expression)); + var funcPointer = EmitUnwrap(EmitExpression(funcCall.Expression)); if (funcType.ReturnType is not NubVoidType) { @@ -1284,19 +1278,19 @@ public static class QBEGenerator } } - private static void GenerateCopy(NubType type, string source, string destinationPtr) + private static void EmitCopy(NubType type, string sourcePtr, string destinationPtr) { if (SizeOf(type) > 8) { - _builder.AppendLine($" blit {source}, {destinationPtr}, {SizeOf(type)}"); + _builder.AppendLine($" blit {sourcePtr}, {destinationPtr}, {SizeOf(type)}"); } else { - _builder.AppendLine($" {QBEStore(type)} {source}, {destinationPtr}"); + _builder.AppendLine($" {QBEStore(type)} {sourcePtr}, {destinationPtr}"); } } - private static string Unwrap(Ident ident) + private static string EmitUnwrap(Ident ident) { if (ident.Type.IsVoid) { @@ -1309,7 +1303,7 @@ public static class QBEGenerator case IdentKind.Literal: return ident.Name; case IdentKind.Variable: - if (SizeOf(ident.Type) > 8) + if (IsPointerType(ident.Type)) { return ident.Name; } @@ -1329,13 +1323,6 @@ internal class Variable(string name, Ident ident) { public string Name { get; } = name; public Ident Ident { get; } = ident; - public bool Initialized { get; private set; } - - public Variable Assign() - { - Initialized = true; - return this; - } } internal class Ident(string name, NubType type, IdentKind kind = IdentKind.Variable) @@ -1343,6 +1330,11 @@ internal class Ident(string name, NubType type, IdentKind kind = IdentKind.Varia public string Name { get; } = name; public NubType Type { get; } = type; public IdentKind Kind { get; } = kind; + + public override string ToString() + { + throw new InvalidOperationException(); + } } internal enum IdentKind