This commit is contained in:
nub31
2025-01-28 20:06:21 +01:00
parent c65b487f05
commit 0553d0abbf
4 changed files with 29 additions and 52 deletions

View File

@@ -10,56 +10,33 @@ public class Generator
private readonly List<DefinitionNode> _definitions; private readonly List<DefinitionNode> _definitions;
private readonly SymbolTable _symbolTable; private readonly SymbolTable _symbolTable;
private readonly StringBuilder _builder; private readonly StringBuilder _builder;
private readonly HashSet<string> _externFuncDefinitions;
private readonly ExpressionGenerator _expressionGenerator; private readonly ExpressionGenerator _expressionGenerator;
private readonly FuncGenerator _funcGenerator; private readonly FuncGenerator _funcGenerator;
public Generator(FileNode file, Dictionary<string, FileNode> deps) public Generator(IReadOnlyCollection<DefinitionNode> definitions)
{ {
_definitions = []; _definitions = [];
_builder = new StringBuilder(); _builder = new StringBuilder();
_externFuncDefinitions = ["strcmp"];
_symbolTable = new SymbolTable(); _symbolTable = new SymbolTable();
_expressionGenerator = new ExpressionGenerator(_symbolTable, _builder); _expressionGenerator = new ExpressionGenerator(_symbolTable, _builder);
_funcGenerator = new FuncGenerator(_symbolTable, _builder, _expressionGenerator); _funcGenerator = new FuncGenerator(_symbolTable, _builder, _expressionGenerator);
ResolveGlobalVariables(file, deps); foreach (var globalVariableDefinition in definitions.OfType<GlobalVariableDefinitionNode>())
ResolveDefinitions(file, deps);
}
private void ResolveGlobalVariables(FileNode file, Dictionary<string, FileNode> deps)
{
foreach (var globalVariableDefinition in file.Definitions.OfType<GlobalVariableDefinitionNode>())
{ {
_symbolTable.DefineGlobalVariable(globalVariableDefinition); _symbolTable.DefineGlobalVariable(globalVariableDefinition);
_definitions.Add(globalVariableDefinition); _definitions.Add(globalVariableDefinition);
} }
foreach (var include in file.Includes) foreach (var funcDefinitionNode in definitions.OfType<ExternFuncDefinitionNode>())
{
ResolveGlobalVariables(deps[include], deps);
}
}
private void ResolveDefinitions(FileNode file, Dictionary<string, FileNode> deps)
{
foreach (var funcDefinitionNode in file.Definitions.OfType<ExternFuncDefinitionNode>())
{
_symbolTable.DefineFunc(funcDefinitionNode);
_definitions.Add(funcDefinitionNode);
_externFuncDefinitions.Add(_symbolTable.ResolveExternFunc(funcDefinitionNode.Name, funcDefinitionNode.Parameters.Select(p => p.Type).ToList()).StartLabel);
}
foreach (var funcDefinitionNode in file.Definitions.OfType<LocalFuncDefinitionNode>())
{ {
_symbolTable.DefineFunc(funcDefinitionNode); _symbolTable.DefineFunc(funcDefinitionNode);
_definitions.Add(funcDefinitionNode); _definitions.Add(funcDefinitionNode);
} }
foreach (var include in file.Includes) foreach (var funcDefinitionNode in definitions.OfType<LocalFuncDefinitionNode>())
{ {
ResolveDefinitions(deps[include], deps); _symbolTable.DefineFunc(funcDefinitionNode);
_definitions.Add(funcDefinitionNode);
} }
} }
@@ -67,7 +44,7 @@ public class Generator
{ {
_builder.AppendLine("global _start"); _builder.AppendLine("global _start");
foreach (var externFuncDefinition in _externFuncDefinitions) foreach (var externFuncDefinition in _definitions.OfType<ExternFuncDefinitionNode>().Select(e => e.Name))
{ {
_builder.AppendLine($"extern {externFuncDefinition}"); _builder.AppendLine($"extern {externFuncDefinition}");
} }
@@ -111,6 +88,27 @@ public class Generator
_builder.AppendLine(_funcGenerator.GenerateFuncDefinition(funcDefinition)); _builder.AppendLine(_funcGenerator.GenerateFuncDefinition(funcDefinition));
} }
_builder.AppendLine("""
strcmp:
xor rdx, rdx
.loop:
mov al, [rsi + rdx]
mov bl, [rdi + rdx]
inc rdx
cmp al, bl
jne .not_equal
cmp al, 0
je .equal
jmp .loop
.not_equal:
mov rax, 0
ret
.equal:
mov rax, 1
ret
""");
_builder.AppendLine(); _builder.AppendLine();
_builder.AppendLine("section .data"); _builder.AppendLine("section .data");
foreach (var str in _symbolTable.Strings) foreach (var str in _symbolTable.Strings)

View File

@@ -39,8 +39,7 @@ foreach (var file in files)
typer.Populate(); typer.Populate();
} }
var generator = new Generator(files.Values.SelectMany(f => f.Definitions).ToList());
var generator = new Generator(files[rootFileName], files);
var asm = generator.Generate(); var asm = generator.Generate();
Console.WriteLine(asm); Console.WriteLine(asm);

View File

@@ -1,25 +1,6 @@
global strlen global strlen
global strcmp
section .text section .text
strcmp:
xor rdx, rdx
.loop:
mov al, [rsi + rdx]
mov bl, [rdi + rdx]
inc rdx
cmp al, bl
jne .not_equal
cmp al, 0
je .equal
jmp .loop
.not_equal:
mov rax, 0
ret
.equal:
mov rax, 1
ret
strlen: strlen:
xor rax, rax xor rax, rax
.loop: .loop:

View File

@@ -1,2 +1 @@
extern func strlen(msg: String): int64; extern func strlen(msg: String): int64;
extern func strcmp(a: String, b: String): bool;