...
This commit is contained in:
@@ -52,7 +52,7 @@ public class Generator
|
|||||||
foreach (var globalVariable in _definitions.OfType<GlobalVariableDefinitionNode>())
|
foreach (var globalVariable in _definitions.OfType<GlobalVariableDefinitionNode>())
|
||||||
{
|
{
|
||||||
var symbol = _symbolTable.ResolveGlobalVariable(globalVariable.Name);
|
var symbol = _symbolTable.ResolveGlobalVariable(globalVariable.Name);
|
||||||
_builder.AppendLine($" {symbol.Identifier}: resq 1 ; {globalVariable.Name}");
|
_builder.AppendLine($" {symbol.Identifier}: resq 1");
|
||||||
}
|
}
|
||||||
|
|
||||||
_builder.AppendLine();
|
_builder.AppendLine();
|
||||||
@@ -61,7 +61,6 @@ public class Generator
|
|||||||
|
|
||||||
var main = _symbolTable.ResolveLocalFunc(Entrypoint, []);
|
var main = _symbolTable.ResolveLocalFunc(Entrypoint, []);
|
||||||
|
|
||||||
_builder.AppendLine(" ; Initialize global variables");
|
|
||||||
foreach (var globalVariable in _definitions.OfType<GlobalVariableDefinitionNode>())
|
foreach (var globalVariable in _definitions.OfType<GlobalVariableDefinitionNode>())
|
||||||
{
|
{
|
||||||
var symbol = _symbolTable.ResolveGlobalVariable(globalVariable.Name);
|
var symbol = _symbolTable.ResolveGlobalVariable(globalVariable.Name);
|
||||||
@@ -70,13 +69,12 @@ public class Generator
|
|||||||
}
|
}
|
||||||
|
|
||||||
_builder.AppendLine();
|
_builder.AppendLine();
|
||||||
_builder.AppendLine($" ; Call entrypoint {Entrypoint}");
|
|
||||||
_builder.AppendLine($" call {main.StartLabel}");
|
_builder.AppendLine($" call {main.StartLabel}");
|
||||||
|
|
||||||
_builder.AppendLine();
|
_builder.AppendLine();
|
||||||
_builder.AppendLine(main.ReturnType.HasValue
|
_builder.AppendLine(main.ReturnType.HasValue
|
||||||
? " mov rdi, rax ; Exit with return value of entrypoint"
|
? " mov rdi, rax"
|
||||||
: " mov rdi, 0 ; Exit with default status code 0");
|
: " mov rdi, 0");
|
||||||
_builder.AppendLine(" mov rax, 60");
|
_builder.AppendLine(" mov rax, 60");
|
||||||
_builder.AppendLine(" syscall");
|
_builder.AppendLine(" syscall");
|
||||||
|
|
||||||
@@ -121,16 +119,13 @@ public class Generator
|
|||||||
{
|
{
|
||||||
var func = _symbolTable.ResolveLocalFunc(node.Name, node.Parameters.Select(p => p.Type).ToList());
|
var func = _symbolTable.ResolveLocalFunc(node.Name, node.Parameters.Select(p => p.Type).ToList());
|
||||||
|
|
||||||
_builder.AppendLine($"; {node.ToString()}");
|
|
||||||
_builder.AppendLine($"{func.StartLabel}:");
|
_builder.AppendLine($"{func.StartLabel}:");
|
||||||
_builder.AppendLine(" ; Set up stack frame");
|
|
||||||
_builder.AppendLine(" push rbp");
|
_builder.AppendLine(" push rbp");
|
||||||
_builder.AppendLine(" mov rbp, rsp");
|
_builder.AppendLine(" mov rbp, rsp");
|
||||||
_builder.AppendLine($" sub rsp, {func.StackAllocation}");
|
_builder.AppendLine($" sub rsp, {func.StackAllocation}");
|
||||||
|
|
||||||
string[] registers = ["rdi", "rsi", "rdx", "rcx", "r8", "r9"];
|
string[] registers = ["rdi", "rsi", "rdx", "rcx", "r8", "r9"];
|
||||||
|
|
||||||
_builder.AppendLine(" ; Body");
|
|
||||||
for (var i = 0; i < func.Parameters.Count; i++)
|
for (var i = 0; i < func.Parameters.Count; i++)
|
||||||
{
|
{
|
||||||
var parameter = func.ResolveLocalVariable(func.Parameters.ElementAt(i).Name);
|
var parameter = func.ResolveLocalVariable(func.Parameters.ElementAt(i).Name);
|
||||||
@@ -149,7 +144,6 @@ public class Generator
|
|||||||
GenerateBlock(node.Body, func);
|
GenerateBlock(node.Body, func);
|
||||||
|
|
||||||
_builder.AppendLine($"{func.EndLabel}:");
|
_builder.AppendLine($"{func.EndLabel}:");
|
||||||
_builder.AppendLine(" ; Clean up stack frame");
|
|
||||||
_builder.AppendLine(" mov rsp, rbp");
|
_builder.AppendLine(" mov rsp, rbp");
|
||||||
_builder.AppendLine(" pop rbp");
|
_builder.AppendLine(" pop rbp");
|
||||||
_builder.AppendLine(" ret");
|
_builder.AppendLine(" ret");
|
||||||
|
|||||||
@@ -17,35 +17,25 @@ public class ExpressionTyper
|
|||||||
private readonly List<GlobalVariableDefinitionNode> _variableDefinitions;
|
private readonly List<GlobalVariableDefinitionNode> _variableDefinitions;
|
||||||
private readonly Stack<Variable> _variables;
|
private readonly Stack<Variable> _variables;
|
||||||
|
|
||||||
public ExpressionTyper(FileNode file, Dictionary<string, FileNode> deps)
|
public ExpressionTyper(IReadOnlyCollection<DefinitionNode> definitions)
|
||||||
{
|
{
|
||||||
_variables = new Stack<Variable>();
|
_variables = new Stack<Variable>();
|
||||||
_functions = [];
|
_functions = [];
|
||||||
_variableDefinitions = [];
|
_variableDefinitions = [];
|
||||||
|
|
||||||
ResolveFunctions(file, deps);
|
var functions = definitions
|
||||||
}
|
|
||||||
|
|
||||||
private void ResolveFunctions(FileNode file, Dictionary<string, FileNode> deps)
|
|
||||||
{
|
|
||||||
var functions = file.Definitions
|
|
||||||
.OfType<LocalFuncDefinitionNode>()
|
.OfType<LocalFuncDefinitionNode>()
|
||||||
.Select(f => new Func(f.Name, f.Parameters, f.Body, f.ReturnType))
|
.Select(f => new Func(f.Name, f.Parameters, f.Body, f.ReturnType))
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
var externFunctions = file.Definitions
|
var externFunctions = definitions
|
||||||
.OfType<ExternFuncDefinitionNode>()
|
.OfType<ExternFuncDefinitionNode>()
|
||||||
.Select(f => new Func(f.Name, f.Parameters, Optional<BlockNode>.Empty(), f.ReturnType))
|
.Select(f => new Func(f.Name, f.Parameters, Optional<BlockNode>.Empty(), f.ReturnType))
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
_functions.AddRange(functions);
|
_functions.AddRange(functions);
|
||||||
_functions.AddRange(externFunctions);
|
_functions.AddRange(externFunctions);
|
||||||
_variableDefinitions.AddRange(file.Definitions.OfType<GlobalVariableDefinitionNode>());
|
_variableDefinitions.AddRange(definitions.OfType<GlobalVariableDefinitionNode>());
|
||||||
|
|
||||||
foreach (var include in file.Includes)
|
|
||||||
{
|
|
||||||
ResolveFunctions(deps[include], deps);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Populate()
|
public void Populate()
|
||||||
|
|||||||
@@ -33,13 +33,12 @@ while (queue.TryDequeue(out var path))
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var file in files)
|
var definitions = files.Values.SelectMany(f => f.Definitions).ToArray();
|
||||||
{
|
|
||||||
var typer = new ExpressionTyper(file.Value, files);
|
|
||||||
typer.Populate();
|
|
||||||
}
|
|
||||||
|
|
||||||
var generator = new Generator(files.Values.SelectMany(f => f.Definitions).ToList());
|
var typer = new ExpressionTyper(definitions);
|
||||||
|
typer.Populate();
|
||||||
|
|
||||||
|
var generator = new Generator(definitions);
|
||||||
var asm = generator.Generate();
|
var asm = generator.Generate();
|
||||||
|
|
||||||
Console.WriteLine(asm);
|
Console.WriteLine(asm);
|
||||||
|
|||||||
Reference in New Issue
Block a user