Node -> none
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using NubLang.Syntax.Node;
|
||||
using NubLang.Syntax.Binding.Node;
|
||||
using NubLang.Syntax.Tokenization;
|
||||
|
||||
namespace NubLang.Generation.QBE;
|
||||
@@ -17,8 +17,8 @@ public static class QBEGenerator
|
||||
private static List<StringLiteral> _stringLiterals = [];
|
||||
private static Stack<string> _breakLabels = [];
|
||||
private static Stack<string> _continueLabels = [];
|
||||
private static Queue<(BoundAnonymousFuncNode Func, string Name)> _anonymousFunctions = [];
|
||||
private static Dictionary<BoundTraitFuncImplNode, string> _implFunctions = [];
|
||||
private static Queue<(BoundAnonymousFunc Func, string Name)> _anonymousFunctions = [];
|
||||
private static Dictionary<BoundTraitFuncImpl, string> _implFunctions = [];
|
||||
private static Stack<Variable> _variables = [];
|
||||
private static Stack<int> _variableScopes = [];
|
||||
private static int _tmpIndex;
|
||||
@@ -64,7 +64,7 @@ public static class QBEGenerator
|
||||
_writer.NewLine();
|
||||
}
|
||||
|
||||
foreach (var funcDef in _syntaxTree.Definitions.OfType<BoundLocalFuncNode>())
|
||||
foreach (var funcDef in _syntaxTree.Definitions.OfType<BoundLocalFunc>())
|
||||
{
|
||||
EmitFuncDefinition(funcDef, LocalFuncName(funcDef), funcDef.Parameters, funcDef.ReturnType, funcDef.Body, funcDef.Exported);
|
||||
_writer.NewLine();
|
||||
@@ -116,12 +116,12 @@ public static class QBEGenerator
|
||||
return $"$string{++_stringLiteralIndex}";
|
||||
}
|
||||
|
||||
private static string LocalFuncName(BoundLocalFuncNode funcDef)
|
||||
private static string LocalFuncName(BoundLocalFunc funcDef)
|
||||
{
|
||||
return funcDef.Exported ? $"${funcDef.Name}" : $"${funcDef.Namespace}_{funcDef.Name}";
|
||||
}
|
||||
|
||||
private static string ExternFuncName(BoundExternFuncNode funcDef)
|
||||
private static string ExternFuncName(BoundExternFunc funcDef)
|
||||
{
|
||||
return $"${funcDef.CallName}";
|
||||
}
|
||||
@@ -227,23 +227,23 @@ public static class QBEGenerator
|
||||
return size;
|
||||
}
|
||||
|
||||
private static bool EmitTryMoveInto(BoundExpressionNode source, string destinationPointer)
|
||||
private static bool EmitTryMoveInto(BoundExpression source, string destinationPointer)
|
||||
{
|
||||
switch (source)
|
||||
{
|
||||
case BoundArrayInitializerNode arrayInitializer:
|
||||
case BoundArrayInitializer arrayInitializer:
|
||||
{
|
||||
_writer.WriteDebugLocation(arrayInitializer);
|
||||
EmitStore(source.Type, EmitUnwrap(EmitArrayInitializer(arrayInitializer)), destinationPointer);
|
||||
return true;
|
||||
}
|
||||
case BoundStructInitializerNode structInitializer:
|
||||
case BoundStructInitializer structInitializer:
|
||||
{
|
||||
_writer.WriteDebugLocation(structInitializer);
|
||||
EmitStructInitializer(structInitializer, destinationPointer);
|
||||
return true;
|
||||
}
|
||||
case BoundLiteralNode { Kind: LiteralKind.String } literal:
|
||||
case BoundLiteral { Kind: LiteralKind.String } literal:
|
||||
{
|
||||
_writer.WriteDebugLocation(literal);
|
||||
EmitStore(source.Type, EmitUnwrap(EmitLiteral(literal)), destinationPointer);
|
||||
@@ -254,7 +254,7 @@ public static class QBEGenerator
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void EmitCopyIntoOrInitialize(BoundExpressionNode source, string destinationPointer)
|
||||
private static void EmitCopyIntoOrInitialize(BoundExpression source, string destinationPointer)
|
||||
{
|
||||
// If the source is a value which is not used yet such as an array/struct initializer or literal, we can skip copying
|
||||
if (EmitTryMoveInto(source, destinationPointer))
|
||||
@@ -292,13 +292,13 @@ public static class QBEGenerator
|
||||
}
|
||||
}
|
||||
|
||||
private static bool EmitTryCreateWithoutCopy(BoundExpressionNode source, [NotNullWhen(true)] out string? destination)
|
||||
private static bool EmitTryCreateWithoutCopy(BoundExpression source, [NotNullWhen(true)] out string? destination)
|
||||
{
|
||||
switch (source)
|
||||
{
|
||||
case BoundArrayInitializerNode:
|
||||
case BoundStructInitializerNode:
|
||||
case BoundLiteralNode { Kind: LiteralKind.String }:
|
||||
case BoundArrayInitializer:
|
||||
case BoundStructInitializer:
|
||||
case BoundLiteral { Kind: LiteralKind.String }:
|
||||
{
|
||||
destination = EmitUnwrap(EmitExpression(source));
|
||||
return true;
|
||||
@@ -309,7 +309,7 @@ public static class QBEGenerator
|
||||
return false;
|
||||
}
|
||||
|
||||
private static string EmitCreateCopyOrInitialize(BoundExpressionNode source)
|
||||
private static string EmitCreateCopyOrInitialize(BoundExpression source)
|
||||
{
|
||||
// If the source is a value which is not used yet such as an array/struct initializer or literal, we can skip copying
|
||||
if (EmitTryCreateWithoutCopy(source, out var uncopiedValue))
|
||||
@@ -391,7 +391,7 @@ public static class QBEGenerator
|
||||
return "l";
|
||||
}
|
||||
|
||||
private static void EmitFuncDefinition(BoundNode debugNode, string name, List<BoundFuncParameterNode> parameters, NubType returnType, BoundBlock body, bool exported)
|
||||
private static void EmitFuncDefinition(BoundNode debugNode, string name, List<BoundFuncParameter> parameters, NubType returnType, BoundBlock body, bool exported)
|
||||
{
|
||||
_variables.Clear();
|
||||
_variableScopes.Clear();
|
||||
@@ -424,7 +424,7 @@ public static class QBEGenerator
|
||||
|
||||
EmitBlock(body, parameterVars);
|
||||
|
||||
if (body.Statements.LastOrDefault() is not BoundReturnNode)
|
||||
if (body.Statements.LastOrDefault() is not BoundReturn)
|
||||
{
|
||||
if (returnType is NubVoidType)
|
||||
{
|
||||
@@ -435,7 +435,7 @@ public static class QBEGenerator
|
||||
_writer.EndFunction();
|
||||
}
|
||||
|
||||
private static void EmitStructDefinition(BoundStructNode structDef)
|
||||
private static void EmitStructDefinition(BoundStruct structDef)
|
||||
{
|
||||
_writer.WriteLine($"type {CustomTypeName(structDef.Namespace, structDef.Name)} = {{ ");
|
||||
|
||||
@@ -456,7 +456,7 @@ public static class QBEGenerator
|
||||
_writer.WriteLine("}");
|
||||
return;
|
||||
|
||||
string StructDefQBEType(BoundStructFieldNode field)
|
||||
string StructDefQBEType(BoundStructField field)
|
||||
{
|
||||
if (field.Type.IsSimpleType(out var simpleType, out var complexType))
|
||||
{
|
||||
@@ -481,7 +481,7 @@ public static class QBEGenerator
|
||||
}
|
||||
}
|
||||
|
||||
private static void EmitTraitVTable(BoundTraitNode traitDef)
|
||||
private static void EmitTraitVTable(BoundTrait traitDef)
|
||||
{
|
||||
_writer.WriteLine($"type {CustomTypeName(traitDef.Namespace, traitDef.Name)} = {{");
|
||||
|
||||
@@ -493,34 +493,34 @@ public static class QBEGenerator
|
||||
_writer.WriteLine("}");
|
||||
}
|
||||
|
||||
private static void EmitStatement(BoundStatementNode statement)
|
||||
private static void EmitStatement(BoundStatement statement)
|
||||
{
|
||||
_writer.WriteDebugLocation(statement);
|
||||
|
||||
switch (statement)
|
||||
{
|
||||
case BoundAssignmentNode assignment:
|
||||
case BoundAssignment assignment:
|
||||
EmitAssignment(assignment);
|
||||
break;
|
||||
case BoundBreakNode:
|
||||
case BoundBreak:
|
||||
EmitBreak();
|
||||
break;
|
||||
case BoundContinueNode:
|
||||
case BoundContinue:
|
||||
EmitContinue();
|
||||
break;
|
||||
case BoundIfNode ifStatement:
|
||||
case BoundIf ifStatement:
|
||||
EmitIf(ifStatement);
|
||||
break;
|
||||
case BoundReturnNode @return:
|
||||
case BoundReturn @return:
|
||||
EmitReturn(@return);
|
||||
break;
|
||||
case BoundStatementExpressionNode statementExpression:
|
||||
case BoundStatementExpression statementExpression:
|
||||
EmitExpression(statementExpression.Expression);
|
||||
break;
|
||||
case BoundVariableDeclarationNode variableDeclaration:
|
||||
case BoundVariableDeclaration variableDeclaration:
|
||||
EmitVariableDeclaration(variableDeclaration);
|
||||
break;
|
||||
case BoundWhileNode whileStatement:
|
||||
case BoundWhile whileStatement:
|
||||
EmitWhile(whileStatement);
|
||||
break;
|
||||
default:
|
||||
@@ -528,7 +528,7 @@ public static class QBEGenerator
|
||||
}
|
||||
}
|
||||
|
||||
private static void EmitAssignment(BoundAssignmentNode assignment)
|
||||
private static void EmitAssignment(BoundAssignment assignment)
|
||||
{
|
||||
var destination = EmitExpression(assignment.Target);
|
||||
Debug.Assert(destination.Kind == ValKind.Pointer);
|
||||
@@ -572,7 +572,7 @@ public static class QBEGenerator
|
||||
_codeIsReachable = false;
|
||||
}
|
||||
|
||||
private static void EmitIf(BoundIfNode ifStatement)
|
||||
private static void EmitIf(BoundIf ifStatement)
|
||||
{
|
||||
var trueLabel = LabelName();
|
||||
var falseLabel = LabelName();
|
||||
@@ -596,7 +596,7 @@ public static class QBEGenerator
|
||||
_writer.WriteLine(endLabel);
|
||||
}
|
||||
|
||||
private static void EmitReturn(BoundReturnNode @return)
|
||||
private static void EmitReturn(BoundReturn @return)
|
||||
{
|
||||
if (@return.Value.HasValue)
|
||||
{
|
||||
@@ -609,7 +609,7 @@ public static class QBEGenerator
|
||||
}
|
||||
}
|
||||
|
||||
private static void EmitVariableDeclaration(BoundVariableDeclarationNode variableDeclaration)
|
||||
private static void EmitVariableDeclaration(BoundVariableDeclaration variableDeclaration)
|
||||
{
|
||||
var name = $"%{variableDeclaration.Name}";
|
||||
_writer.Indented($"{name} =l alloc8 8");
|
||||
@@ -623,7 +623,7 @@ public static class QBEGenerator
|
||||
_variables.Push(new Variable(variableDeclaration.Name, new Val(name, variableDeclaration.Type, ValKind.Pointer)));
|
||||
}
|
||||
|
||||
private static void EmitWhile(BoundWhileNode whileStatement)
|
||||
private static void EmitWhile(BoundWhile whileStatement)
|
||||
{
|
||||
var conditionLabel = LabelName();
|
||||
var iterationLabel = LabelName();
|
||||
@@ -644,39 +644,39 @@ public static class QBEGenerator
|
||||
_breakLabels.Pop();
|
||||
}
|
||||
|
||||
private static Val EmitExpression(BoundExpressionNode expression)
|
||||
private static Val EmitExpression(BoundExpression expression)
|
||||
{
|
||||
_writer.WriteDebugLocation(expression);
|
||||
return expression switch
|
||||
{
|
||||
BoundArrayInitializerNode arrayInitializer => EmitArrayInitializer(arrayInitializer),
|
||||
BoundStructInitializerNode structInitializer => EmitStructInitializer(structInitializer),
|
||||
BoundAddressOfNode addressOf => EmitAddressOf(addressOf),
|
||||
BoundDereferenceNode dereference => EmitDereference(dereference),
|
||||
BoundAnonymousFuncNode anonymousFunc => EmitAnonymousFunc(anonymousFunc),
|
||||
BoundBinaryExpressionNode binaryExpression => EmitBinaryExpression(binaryExpression),
|
||||
BoundFuncCallNode funcCallExpression => EmitFuncCall(funcCallExpression),
|
||||
BoundExternFuncIdentNode externFuncIdent => EmitExternFuncIdent(externFuncIdent),
|
||||
BoundLocalFuncIdentNode localFuncIdent => EmitLocalFuncIdent(localFuncIdent),
|
||||
BoundVariableIdentNode variableIdent => EmitVariableIdent(variableIdent),
|
||||
BoundLiteralNode literal => EmitLiteral(literal),
|
||||
BoundUnaryExpressionNode unaryExpression => EmitUnaryExpression(unaryExpression),
|
||||
BoundStructFieldAccessNode structFieldAccess => EmitStructFieldAccess(structFieldAccess),
|
||||
BoundTraitFuncAccessNode traitFuncAccess => EmitTraitFuncAccess(traitFuncAccess),
|
||||
BoundTraitImplFuncAccessNode traitImplFuncAccess => EmitTraitImplFuncAccess(traitImplFuncAccess),
|
||||
BoundArrayIndexAccessNode arrayIndex => EmitArrayIndexAccess(arrayIndex),
|
||||
BoundArrayInitializer arrayInitializer => EmitArrayInitializer(arrayInitializer),
|
||||
BoundStructInitializer structInitializer => EmitStructInitializer(structInitializer),
|
||||
BoundAddressOf addressOf => EmitAddressOf(addressOf),
|
||||
BoundDereference dereference => EmitDereference(dereference),
|
||||
BoundAnonymousFunc anonymousFunc => EmitAnonymousFunc(anonymousFunc),
|
||||
BoundBinaryExpression binaryExpression => EmitBinaryExpression(binaryExpression),
|
||||
BoundFuncCall funcCallExpression => EmitFuncCall(funcCallExpression),
|
||||
BoundExternFuncIdent externFuncIdent => EmitExternFuncIdent(externFuncIdent),
|
||||
BoundLocalFuncIdent localFuncIdent => EmitLocalFuncIdent(localFuncIdent),
|
||||
BoundVariableIdent variableIdent => EmitVariableIdent(variableIdent),
|
||||
BoundLiteral literal => EmitLiteral(literal),
|
||||
BoundUnaryExpression unaryExpression => EmitUnaryExpression(unaryExpression),
|
||||
BoundStructFieldAccess structFieldAccess => EmitStructFieldAccess(structFieldAccess),
|
||||
BoundTraitFuncAccess traitFuncAccess => EmitTraitFuncAccess(traitFuncAccess),
|
||||
BoundTraitImplFuncAccess traitImplFuncAccess => EmitTraitImplFuncAccess(traitImplFuncAccess),
|
||||
BoundArrayIndexAccess arrayIndex => EmitArrayIndexAccess(arrayIndex),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(expression))
|
||||
};
|
||||
}
|
||||
|
||||
private static Val EmitAnonymousFunc(BoundAnonymousFuncNode anonymousFunc)
|
||||
private static Val EmitAnonymousFunc(BoundAnonymousFunc anonymousFunc)
|
||||
{
|
||||
var name = $"$anon_func{++_anonymousFuncIndex}";
|
||||
_anonymousFunctions.Enqueue((anonymousFunc, name));
|
||||
return new Val(name, anonymousFunc.Type, ValKind.Direct);
|
||||
}
|
||||
|
||||
private static Val EmitArrayIndexAccess(BoundArrayIndexAccessNode arrayIndexAccess)
|
||||
private static Val EmitArrayIndexAccess(BoundArrayIndexAccess arrayIndexAccess)
|
||||
{
|
||||
var array = EmitUnwrap(EmitExpression(arrayIndexAccess.Target));
|
||||
var index = EmitUnwrap(EmitExpression(arrayIndexAccess.Index));
|
||||
@@ -716,7 +716,7 @@ public static class QBEGenerator
|
||||
_writer.Indented(notOobLabel);
|
||||
}
|
||||
|
||||
private static Val EmitArrayInitializer(BoundArrayInitializerNode arrayInitializer)
|
||||
private static Val EmitArrayInitializer(BoundArrayInitializer arrayInitializer)
|
||||
{
|
||||
var capacity = EmitUnwrap(EmitExpression(arrayInitializer.Capacity));
|
||||
var elementSize = arrayInitializer.ElementType.Size(_definitionTable);
|
||||
@@ -737,12 +737,12 @@ public static class QBEGenerator
|
||||
return new Val(arrayPointer, arrayInitializer.Type, ValKind.Direct);
|
||||
}
|
||||
|
||||
private static Val EmitDereference(BoundDereferenceNode dereference)
|
||||
private static Val EmitDereference(BoundDereference dereference)
|
||||
{
|
||||
return EmitLoad(dereference.Type, EmitUnwrap(EmitExpression(dereference.Expression)));
|
||||
}
|
||||
|
||||
private static Val EmitAddressOf(BoundAddressOfNode addressOf)
|
||||
private static Val EmitAddressOf(BoundAddressOf addressOf)
|
||||
{
|
||||
var value = EmitExpression(addressOf.Expression);
|
||||
if (value.Kind != ValKind.Pointer)
|
||||
@@ -753,7 +753,7 @@ public static class QBEGenerator
|
||||
return new Val(value.Name, addressOf.Type, ValKind.Direct);
|
||||
}
|
||||
|
||||
private static Val EmitBinaryExpression(BoundBinaryExpressionNode binaryExpression)
|
||||
private static Val EmitBinaryExpression(BoundBinaryExpression binaryExpression)
|
||||
{
|
||||
var left = EmitUnwrap(EmitExpression(binaryExpression.Left));
|
||||
var right = EmitUnwrap(EmitExpression(binaryExpression.Right));
|
||||
@@ -860,24 +860,24 @@ public static class QBEGenerator
|
||||
};
|
||||
}
|
||||
|
||||
private static Val EmitExternFuncIdent(BoundExternFuncIdentNode externFuncIdent)
|
||||
private static Val EmitExternFuncIdent(BoundExternFuncIdent externFuncIdent)
|
||||
{
|
||||
var func = _definitionTable.LookupExternFunc(externFuncIdent.Namespace, externFuncIdent.Name);
|
||||
return new Val(ExternFuncName(func), externFuncIdent.Type, ValKind.Direct);
|
||||
}
|
||||
|
||||
private static Val EmitLocalFuncIdent(BoundLocalFuncIdentNode localFuncIdent)
|
||||
private static Val EmitLocalFuncIdent(BoundLocalFuncIdent localFuncIdent)
|
||||
{
|
||||
var func = _definitionTable.LookupExternFunc(localFuncIdent.Namespace, localFuncIdent.Name);
|
||||
return new Val(ExternFuncName(func), localFuncIdent.Type, ValKind.Direct);
|
||||
}
|
||||
|
||||
private static Val EmitVariableIdent(BoundVariableIdentNode variableIdent)
|
||||
private static Val EmitVariableIdent(BoundVariableIdent variableIdent)
|
||||
{
|
||||
return _variables.Single(v => v.Name == variableIdent.Name).Val;
|
||||
}
|
||||
|
||||
private static Val EmitLiteral(BoundLiteralNode literal)
|
||||
private static Val EmitLiteral(BoundLiteral literal)
|
||||
{
|
||||
switch (literal.Kind)
|
||||
{
|
||||
@@ -959,7 +959,7 @@ public static class QBEGenerator
|
||||
throw new NotSupportedException($"Cannot create literal of kind '{literal.Kind}' for type {literal.Type}");
|
||||
}
|
||||
|
||||
private static Val EmitStructInitializer(BoundStructInitializerNode structInitializer, string? destination = null)
|
||||
private static Val EmitStructInitializer(BoundStructInitializer structInitializer, string? destination = null)
|
||||
{
|
||||
var @struct = _definitionTable.LookupStruct(structInitializer.StructType.Namespace, structInitializer.StructType.Name);
|
||||
|
||||
@@ -987,7 +987,7 @@ public static class QBEGenerator
|
||||
return new Val(destination, structInitializer.StructType, ValKind.Direct);
|
||||
}
|
||||
|
||||
private static Val EmitUnaryExpression(BoundUnaryExpressionNode unaryExpression)
|
||||
private static Val EmitUnaryExpression(BoundUnaryExpression unaryExpression)
|
||||
{
|
||||
var operand = EmitUnwrap(EmitExpression(unaryExpression.Operand));
|
||||
var outputName = TmpName();
|
||||
@@ -1034,7 +1034,7 @@ public static class QBEGenerator
|
||||
throw new NotSupportedException($"Unary operator {unaryExpression.Operator} for type {unaryExpression.Operand.Type} not supported");
|
||||
}
|
||||
|
||||
private static Val EmitStructFieldAccess(BoundStructFieldAccessNode structFieldAccess)
|
||||
private static Val EmitStructFieldAccess(BoundStructFieldAccess structFieldAccess)
|
||||
{
|
||||
var target = EmitUnwrap(EmitExpression(structFieldAccess.Target));
|
||||
|
||||
@@ -1053,12 +1053,12 @@ public static class QBEGenerator
|
||||
return new Val(output, structFieldAccess.Type, ValKind.Pointer);
|
||||
}
|
||||
|
||||
private static Val EmitTraitFuncAccess(BoundTraitFuncAccessNode traitFuncAccess)
|
||||
private static Val EmitTraitFuncAccess(BoundTraitFuncAccess traitFuncAccess)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private static Val EmitTraitImplFuncAccess(BoundTraitImplFuncAccessNode traitImplFuncAccess)
|
||||
private static Val EmitTraitImplFuncAccess(BoundTraitImplFuncAccess traitImplFuncAccess)
|
||||
{
|
||||
var target = EmitExpression(traitImplFuncAccess.Target);
|
||||
|
||||
@@ -1069,7 +1069,7 @@ public static class QBEGenerator
|
||||
return new Val(name, traitImplFuncAccess.Type, ValKind.Direct, new MethodCallContext(target));
|
||||
}
|
||||
|
||||
private static Val EmitFuncCall(BoundFuncCallNode funcCall)
|
||||
private static Val EmitFuncCall(BoundFuncCall funcCall)
|
||||
{
|
||||
var expression = EmitExpression(funcCall.Expression);
|
||||
var funcPointer = EmitUnwrap(expression);
|
||||
@@ -1111,7 +1111,7 @@ public static class QBEGenerator
|
||||
};
|
||||
}
|
||||
|
||||
private static int OffsetOf(BoundStructNode structDefinition, string member)
|
||||
private static int OffsetOf(BoundStruct structDefinition, string member)
|
||||
{
|
||||
var offset = 0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user