...
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -1,2 +1 @@
|
|||||||
extern func strlen(msg: String): int64;
|
extern func strlen(msg: String): int64;
|
||||||
extern func strcmp(a: String, b: String): bool;
|
|
||||||
|
|||||||
Reference in New Issue
Block a user