This commit is contained in:
nub31
2025-05-26 20:39:41 +02:00
parent 1105661603
commit 36a1dbd0ec
8 changed files with 145 additions and 107 deletions

View File

@@ -6,31 +6,35 @@ namespace Nub.Lang.Backend;
public class Generator
{
private readonly List<DefinitionNode> _definitions;
private readonly StringBuilder _builder = new();
private readonly Dictionary<string, Variable> _variables = new();
private readonly List<string> _strings = [];
private readonly Stack<string> _breakLabels = new();
private readonly Stack<string> _continueLabels = new();
private List<SourceFile> _sourceFiles = [];
private StringBuilder _builder = new();
private Dictionary<string, Variable> _variables = [];
private List<string> _strings = [];
private Stack<string> _breakLabels = [];
private Stack<string> _continueLabels = [];
private int _variableIndex;
private bool _codeIsReachable = true;
public Generator(List<DefinitionNode> definitions)
public string Generate(List<SourceFile> sourceFiles)
{
_definitions = definitions;
}
public string Generate()
{
foreach (var structDefinition in _definitions.OfType<StructDefinitionNode>())
_sourceFiles = sourceFiles;
_builder = new StringBuilder();
_variables = new Dictionary<string, Variable>();
_strings = [];
_breakLabels = [];
_continueLabels = [];
_variableIndex = 0;
_codeIsReachable = true;
foreach (var structDef in _sourceFiles.SelectMany(f => f.Definitions).OfType<StructDefinitionNode>())
{
GenerateStructDefinition(structDefinition);
GenerateStructDefinition(structDef);
_builder.AppendLine();
}
foreach (var funcDefinition in _definitions.OfType<LocalFuncDefinitionNode>())
foreach (var funcDef in _sourceFiles.SelectMany(f => f.Definitions).OfType<LocalFuncDefinitionNode>())
{
GenerateFuncDefinition(funcDefinition);
GenerateFuncDefinition(funcDef);
_builder.AppendLine();
}
@@ -213,12 +217,12 @@ public class Generator
throw new ArgumentOutOfRangeException();
}
}
case NubStructType nubCustomType:
case NubStructType nubStructType:
{
var definition = _definitions.OfType<StructDefinitionNode>().FirstOrDefault(s => s.Name == nubCustomType.Name);
var definition = LookupStructDefinition(nubStructType.Namespace, nubStructType.Name);
if (definition == null)
{
throw new Exception($"Cannot determine size of non-existent type {nubCustomType}");
throw new Exception($"Cannot determine size of non-existent type {nubStructType}");
}
return definition.Fields.Sum(f => QbeTypeSize(f.Type));
@@ -362,12 +366,8 @@ public class Generator
private string GenerateFuncCall(FuncCall funcCall)
{
var parameterDefinitions = _definitions
.OfType<IFuncSignature>()
.FirstOrDefault(d => d.Name == funcCall.Name)
?.Parameters;
if (parameterDefinitions == null)
var funcDefinition = LookupFuncSignature(funcCall.Namespace, funcCall.Name, funcCall.Parameters.Select(p => p.Type).ToList());
if (funcDefinition == null)
{
throw new Exception($"Unknown function {funcCall}");
}
@@ -376,19 +376,19 @@ public class Generator
for (var i = 0; i < funcCall.Parameters.Count; i++)
{
if (i < parameterDefinitions.Count && parameterDefinitions[i].Variadic)
if (i < funcDefinition.Parameters.Count && funcDefinition.Parameters[i].Variadic)
{
parameterStrings.Add("...");
}
NubType expectedType;
if (i < parameterDefinitions.Count)
if (i < funcDefinition.Parameters.Count)
{
expectedType = parameterDefinitions[i].Type;
expectedType = funcDefinition.Parameters[i].Type;
}
else if (parameterDefinitions[^1].Variadic)
else if (funcDefinition.Parameters[^1].Variadic)
{
expectedType = parameterDefinitions[^1].Type;
expectedType = funcDefinition.Parameters[^1].Type;
}
else
{
@@ -1295,7 +1295,7 @@ public class Generator
private string GenerateStructInitializer(StructInitializerNode structInitializer)
{
var structDefinition = _definitions.OfType<StructDefinitionNode>().FirstOrDefault(s => s.Name == structInitializer.StructType.Name);
var structDefinition = LookupStructDefinition(structInitializer.StructType.Namespace, structInitializer.StructType.Name);
if (structDefinition == null)
{
throw new Exception($"Struct {structInitializer.StructType.Name} is not defined");
@@ -1399,10 +1399,7 @@ public class Generator
}
case NubStructType structType:
{
var structDefinition = _definitions
.OfType<StructDefinitionNode>()
.FirstOrDefault(s => s.Name == structType.Name);
var structDefinition = LookupStructDefinition(structType.Namespace, structType.Namespace);
if (structDefinition == null)
{
throw new Exception($"Struct {structType.Name} is not defined");
@@ -1449,6 +1446,24 @@ public class Generator
return $"v{++_variableIndex}";
}
private IFuncSignature? LookupFuncSignature(string @namespace, string name, List<NubType> parameters)
{
return _sourceFiles
.Where(f => f.Namespace == @namespace)
.SelectMany(f => f.Definitions)
.OfType<IFuncSignature>()
.FirstOrDefault(f => f.SignatureMatches(name, parameters));
}
private StructDefinitionNode? LookupStructDefinition(string @namespace, string name)
{
return _sourceFiles
.Where(f => f.Namespace == @namespace)
.SelectMany(f => f.Definitions)
.OfType<StructDefinitionNode>()
.FirstOrDefault(d => d.Name == name);
}
private class Variable
{
public required string Pointer { get; init; }