Working code emitter and doing some code gen with it too

This commit is contained in:
Tristan B. Kildaire 2021-11-02 15:13:44 +02:00
parent 2d46eb4458
commit ff9890437d
3 changed files with 128 additions and 5 deletions

View File

@ -2,6 +2,10 @@ module compiler.codegen.emit.core;
import compiler.symbols.data;
import compiler.typecheck.core;
import std.container.slist : SList;
import compiler.codegen.instruction;
import std.stdio;
import std.file;
/**
* TODO: Perhaps have an interface that can emit(Context/Parent, Statement)
@ -11,11 +15,21 @@ import compiler.typecheck.core;
public abstract class CodeEmitter
{
private TypeChecker typeChecker;
protected TypeChecker typeChecker;
this(TypeChecker typeChecker)
/**
* The code queue
*/
protected SList!(Instruction) codeQueue;
alias instructions = codeQueue;
protected File file;
this(TypeChecker typeChecker, File file)
{
this.typeChecker = typeChecker;
codeQueue = typeChecker.getCodeQueue();
this.file = file;
}
public abstract void emit();

View File

@ -2,16 +2,117 @@ module compiler.codegen.emit.dgen;
import compiler.codegen.emit.core : CodeEmitter;
import compiler.typecheck.core;
import std.container.slist : SList;
import compiler.codegen.instruction;
import std.stdio;
import std.file;
public final class DCodeEmitter : CodeEmitter
{
this(TypeChecker typeChecker)
this(TypeChecker typeChecker, File file)
{
super(typeChecker);
super(typeChecker, file);
}
/**
* TODO: We will need state as to where we are etc.
*/
private ulong pushCount;
/**
* RSP value before we started (needed for proper D exit/restore/main()-unwind)
*
* R15 (Richard 15) <- never use this register besides here and `restoreDInfo()`
*/
private void saveDInfo()
{
file.writeln(`
asm
{
mov R15, RSP;
}
`);
}
private void restoreDInfo()
{
file.writeln(`
asm
{
mov RSP, R15;
}
`);
}
public override void emit()
{
/* Emit initial struccture */
emitIninitailModule();
/* Save D info */
saveDInfo();
/* TODO: Implement me */
foreach(Instruction instruction; instructions)
{
/**
* compiler.codegen.instruction.VariableDeclaration
*/
if(cast(VariableDeclaration)instruction)
{
VariableDeclaration varDecInstr = cast(compiler.codegen.instruction.VariableDeclaration)instruction;
file.writeln(`asm
{
sub RSP, 4;
mov dword ptr [RSP], 69;
}
`);
/* TODO: We need to build map of stakc positions, maybe not */
}
/**
* compiler.codegen.instruction.VariableAssignmentInstr
*/
else if(cast(VariableAssignmentInstr)instruction)
{
VariableAssignmentInstr varAssInstr = cast(compiler.codegen.instruction.VariableAssignmentInstr)instruction;
/* Recursively descend soon */
// writeln("int "~varDecInstr.varName~";");
}
}
/* Restore D info */
restoreDInfo();
/* Close the module */
closeModule();
}
private void emitIninitailModule()
{
/* TODO: Maybe emit as d name */
file.writeln("module "~typeChecker.getModule().getName()~";");
file.writeln("void main()");
file.writeln("{");
}
private void closeModule()
{
/* Restore for D exit */
file.writeln(`
int h = -1;
h = *((&h)-4);
import std.stdio;
writeln(h);
`);
file.writeln("}");
}
}

View File

@ -70,8 +70,16 @@ void beginCompilation(string[] sourceFiles)
TypeChecker typeChecker = new TypeChecker(modulle);
typeChecker.beginCheck();
CodeEmitter emitter = new DCodeEmitter(typeChecker);
File outFile;
outFile.open("test.d", "w");
CodeEmitter emitter = new DCodeEmitter(typeChecker, outFile);
emitter.emit();
outFile.close();
}
// catch(CollidingNameException e)
// {