...
This commit is contained in:
@@ -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; }
|
||||
|
||||
Reference in New Issue
Block a user