From 6a64ed40c9f37715854fc02824e754a912fd7983 Mon Sep 17 00:00:00 2001 From: "Tristan B. Velloza Kildaire" Date: Sun, 11 Dec 2022 21:41:15 +0200 Subject: [PATCH] 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 --- source/tlang/compiler/codegen/emit/core.d | 2 + source/tlang/compiler/codegen/emit/dgen.d | 42 +++++++++++++++++++ source/tlang/compiler/codegen/instruction.d | 2 + source/tlang/compiler/compiler.d | 2 + .../testing/simple_variables_only_decs.t | 5 +++ 5 files changed, 53 insertions(+) create mode 100644 source/tlang/testing/simple_variables_only_decs.t diff --git a/source/tlang/compiler/codegen/emit/core.d b/source/tlang/compiler/codegen/emit/core.d index 28042890..4a3e1d57 100644 --- a/source/tlang/compiler/codegen/emit/core.d +++ b/source/tlang/compiler/codegen/emit/core.d @@ -41,4 +41,6 @@ public abstract class CodeEmitter } public abstract void emit(); + + public abstract void finalize(); } \ No newline at end of file diff --git a/source/tlang/compiler/codegen/emit/dgen.d b/source/tlang/compiler/codegen/emit/dgen.d index dda73ff3..763b8ed0 100644 --- a/source/tlang/compiler/codegen/emit/dgen.d +++ b/source/tlang/compiler/codegen/emit/dgen.d @@ -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; +}`); + } } \ No newline at end of file diff --git a/source/tlang/compiler/codegen/instruction.d b/source/tlang/compiler/codegen/instruction.d index bfa88b1d..be56e8de 100644 --- a/source/tlang/compiler/codegen/instruction.d +++ b/source/tlang/compiler/codegen/instruction.d @@ -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~";"; diff --git a/source/tlang/compiler/compiler.d b/source/tlang/compiler/compiler.d index 1b10222a..1282ea6f 100644 --- a/source/tlang/compiler/compiler.d +++ b/source/tlang/compiler/compiler.d @@ -80,6 +80,8 @@ void beginCompilation(string[] sourceFiles) emitter.emit(); outFile.close(); + // Cause the generation to happen + emitter.finalize(); } // catch(CollidingNameException e) // { diff --git a/source/tlang/testing/simple_variables_only_decs.t b/source/tlang/testing/simple_variables_only_decs.t new file mode 100644 index 00000000..b0d4c34a --- /dev/null +++ b/source/tlang/testing/simple_variables_only_decs.t @@ -0,0 +1,5 @@ +module simple_variables_only_decs; + + +int x; +int y; \ No newline at end of file