CodeEmitter

- Added `finalize()` method, this is to be called whenever the emitting is done and a compiler is to be called on the code

DGen

- Implemented a gcc-based finalization method
- Added `emitEntryPoint()` to emit a main() function which is to be called in libc's `_start` symbol

VariableDeclaration

- Added note we may need a symbol table lookup system actually, rather than just a simple `symbolRename`

Compiler

- Call the `finalize()` method on the DGen code emitter

----

Test cases

- Added `simple_variables_only_decs.t` to test code generation
This commit is contained in:
Tristan B. Velloza Kildaire 2022-12-11 21:41:15 +02:00
parent be95288855
commit 6a64ed40c9
5 changed files with 53 additions and 0 deletions

View File

@ -41,4 +41,6 @@ public abstract class CodeEmitter
}
public abstract void emit();
public abstract void finalize();
}

View File

@ -11,6 +11,7 @@ import std.string : cmp;
import gogga;
import std.range : walkLength;
import std.string : wrap;
import std.process : spawnProcess, Pid, ProcessException, wait;
public final class DCodeEmitter : CodeEmitter
{
@ -19,6 +20,31 @@ public final class DCodeEmitter : CodeEmitter
super(typeChecker, file);
}
public override void finalize()
{
try
{
//NOTE: Change to system compiler (maybe, we need to choose a good C compiler)
Pid ccPID = spawnProcess(["gcc", "-o", "tlang.out", file.name()]);
//NOTE: Case where it exited and Pid now inavlid (if it happens it would throw processexception surely)?
int code = wait(ccPID);
gprintln(code);
if(code)
{
//NOTE: Make this a TLang exception
throw new Exception("The CC exited with a non-zero exit code");
}
}
catch(ProcessException e)
{
gprintln("NOTE: Case where it exited and Pid now inavlid (if it happens it would throw processexception surely)?", DebugType.ERROR);
assert(false);
}
}
public override void emit()
{
// Emit header comment (NOTE: Change this to a useful piece of text)
@ -29,6 +55,11 @@ public final class DCodeEmitter : CodeEmitter
gprintln("Code emittings needed: "~to!(string)(walkLength(codeQueue[])));
emitCodeQueue(codeQueue);
//TODO: Emit function definitions
//TODO: Emit main (entry point)
emitEntryPoint();
}
/**
@ -83,4 +114,15 @@ public final class DCodeEmitter : CodeEmitter
file.writeln(currentInstruction.emit());
}
}
private void emitEntryPoint()
{
//TODO: Implement me
file.writeln(`
int main()
{
return 0;
}`);
}
}

View File

@ -104,6 +104,8 @@ public final class VariableDeclaration : StorageDeclaration
// a custom CodeEmitter should be allowed, so let's call it a general rule)
//
//simple_variables.x -> simple_variables_x
//NOTE: We may need to create a symbol table actually and add to that and use that as these names
//could get out of hand (too long)
string renamedSymbol = symbolRename(typedEntityVariableName);
return varType~" "~renamedSymbol~";";

View File

@ -80,6 +80,8 @@ void beginCompilation(string[] sourceFiles)
emitter.emit();
outFile.close();
// Cause the generation to happen
emitter.finalize();
}
// catch(CollidingNameException e)
// {

View File

@ -0,0 +1,5 @@
module simple_variables_only_decs;
int x;
int y;