Merge branch 'major/dotting' into major/dotting_partials

major/imports
Tristan B. V. Kildaire 5 months ago
commit de51bb82a1

@ -18,6 +18,8 @@ import tlang.compiler.configuration : CompilerConfiguration;
/* TODO: Module linking (general overhaul required) */
public import tlang.compiler.codegen.emit.types : EmitResult;
public abstract class CodeEmitter
{
protected TypeChecker typeChecker;
@ -145,10 +147,17 @@ public abstract class CodeEmitter
public abstract void emit();
/**
* Finalizes the emitting process (only
* to be called after the `emit()` finishes)
* Finalizes the emitting process.
* This is only to be called AFTER
* one has called `emit()`
*
* Returns: an `EmitResult`
* containing information
* about the successful
* emit process
*/
public abstract void finalize();
public abstract EmitResult finalize();
/**
* Transforms or emits a single Instruction

@ -1,6 +1,6 @@
module tlang.compiler.codegen.emit.dgen;
import tlang.compiler.codegen.emit.core : CodeEmitter;
import tlang.compiler.codegen.emit.core;
import tlang.compiler.typecheck.core;
import std.container.slist : SList;
import tlang.compiler.codegen.instruction;
@ -23,6 +23,7 @@ import std.format : format;
import std.datetime.stopwatch : StopWatch, AutoStart;
import std.datetime.stopwatch : Duration, dur;
import tlang.compiler.codegen.emit.dgen_simplifier;
import tlang.compiler.codegen.emit.dgen_types : DGenException;
public final class DCodeEmitter : CodeEmitter
{
@ -801,7 +802,14 @@ public final class DCodeEmitter : CodeEmitter
*/
else
{
emmmmit = "<TODO: Base emit: "~to!(string)(instruction)~">";
if(instruction is null)
{
emmmmit = "<TODO: transform() called but instruction was null>";
}
else
{
emmmmit = "<TODO: Base emit: "~to!(string)(instruction)~">";
}
}
return emmmmit;
@ -1640,7 +1648,7 @@ int main()
* This requires that the `emit()`
* step must have already been completed
*/
public override void finalize()
public override EmitResult finalize()
{
import tlang.compiler.symbols.data : Program;
Program program = this.typeChecker.getProgram();
@ -1706,11 +1714,17 @@ int main()
}
// Total compilation time
Duration total = Duration.zero();
StopWatch watch = StopWatch(AutoStart.yes);
Duration total_c = Duration.zero();
// TODO: Do for-each generation of `.o` files here with `-c`
foreach(Module curMod; programModules)
{
scope(exit)
{
watch.reset();
}
string modFileSrcPath = format("%s.c", curMod.getName());
srcFiles ~= modFileSrcPath;
string modFileObjPath = format("%s.o", curMod.getName());
@ -1719,18 +1733,16 @@ int main()
INFO("Compiling now with arguments: "~to!(string)(args));
StopWatch watch = StopWatch(AutoStart.yes);
Pid ccPID = spawnProcess(args);
int code = wait(ccPID);
if(code)
{
//NOTE: Make this a TLang exception
throw new Exception("The CC exited with a non-zero exit code ("~to!(string)(code)~")");
throw new DGenException("The CC exited with a non-zero exit code (%d)", code);
}
Duration compTime = watch.peek();
INFO(format("Compiled %s in %sms", curMod.getName(), compTime.total!("msecs")()));
total = dur!("msecs")(total.total!("msecs")()+compTime.total!("msecs")());
total_c = dur!("msecs")(total_c.total!("msecs")()+compTime.total!("msecs")());
// Only add it to the list of files if it was generated
// (this guards against the clean up routines spitting out errors
@ -1738,7 +1750,7 @@ int main()
objectFiles ~= modFileObjPath;
}
INFO(format("Total compilation time took %s", total));
INFO(format("Total compilation time took %s", total_c));
// Now determine the entry point module
// Module entryModule;
@ -1761,21 +1773,28 @@ int main()
args ~= ["-o", "./tlang.out"];
// Total linking time
Duration total_l = Duration.zero();
watch.reset();
// Now link all object files (the `.o`'s) together
// and perform linking
Pid ccPID = spawnProcess(args);
int code = wait(ccPID);
total_l = watch.peek();
if(code)
{
//NOTE: Make this a TLang exception
throw new Exception("The CC exited with a non-zero exit code ("~to!(string)(code)~")");
throw new DGenException("The CC exited with a non-zero exit code (%d)", code);
}
INFO(format("Total linking time took %s", total_l));
return EmitResult("./tlang.out", total_c+total_l);
}
catch(ProcessException e)
{
ERROR("NOTE: Case where it exited and Pid now inavlid (if it happens it would throw processexception surely)?");
ERROR("NOTE: Case where it exited and Pid now invalid (if it happens it would throw processexception surely)?");
assert(false);
}
}
@ -1809,7 +1828,7 @@ private Predicate!(Entity) derive_functionAccMod(AccessorType accModType)
{
return false;
}
// Onyl care about those with a matching
// Only care about those with a matching
// modifier
else
{
@ -1845,7 +1864,7 @@ private Predicate!(Entity) derive_variableAccMod(AccessorType accModType)
{
return false;
}
// Onyl care about those with a matching
// Only care about those with a matching
// modifier
else
{

@ -0,0 +1,27 @@
/**
* Type definitions for the C-based
* code emitter
*
* Authors: Tristan Brice Velloza Kildaire (deavmi)
*/
module tlang.compiler.codegen.emit.dgen_types;
import tlang.compiler.codegen.emit.types : CodeEmitterException;
import std.string : format;
/**
* An error that occurs during the
* code emitting via `DGen`
*/
public final class DGenException : CodeEmitterException
{
this(string m)
{
super(format("DGen: %s", m));
}
this(T...)(string msg, T items)
{
this(format(msg, items));
}
}

@ -0,0 +1,38 @@
/**
* Type definitions for emit module
*
* Authors: Tristan Brice Velloza Kildaire (deavmi)
*/
module tlang.compiler.codegen.emit.types;
import std.datetime : Duration;
/**
* The result after a successful emit
*/
public struct EmitResult
{
string createdFile;
Duration elapsedTime;
this(string createdFile, Duration elapsed)
{
this.createdFile = createdFile;
this.elapsedTime = elapsed;
}
}
import tlang.misc.exceptions : TError;
import std.string : format;
/**
* An error that occurs during
* the code emitting process
*/
public class CodeEmitterException : TError
{
this(string m)
{
super(format("CodeEmit: %s", m));
}
}

@ -17,7 +17,7 @@ import tlang.misc.exceptions;
import std.string : cmp;
import tlang.compiler.configuration;
import tlang.compiler.modman;
import tlang.compiler.codegen.emit.types : EmitResult;
// TODO: Add configentry unittests
/**
@ -88,6 +88,8 @@ public final class CompilerException : TError
}
}
public alias CompileResult = EmitResult;
public class Compiler
{
/* The input source code */
@ -264,7 +266,7 @@ public class Compiler
}
/* Perform code emitting */
public void doEmit()
public CompileResult doEmit()
{
if(typeChecker is null)
{
@ -274,10 +276,20 @@ public class Compiler
this.emitter = new DCodeEmitter(typeChecker, emitOutFile, config);
emitter.emit(); // Emit the code
emitOutFile.close(); // Flush (perform the write() syscall)
emitter.finalize(); // Call CC on the file containing generated C code
return emitter.finalize(); // Call CC on the file containing generated C code
}
public void compile()
/**
* Performs the compilation
*
* Returns: A `CompileResult`
* containing information about
* the produced output
* Throws: TError on any error
* that may occur during any
* of the compiler's stages
*/
public CompileResult compile()
{
/* Setup the lexer, perform the tokenization and obtain the tokens */
doLex();
@ -289,7 +301,7 @@ public class Compiler
doTypeCheck();
/* Perform code emitting */
doEmit();
return doEmit();
}
}

Loading…
Cancel
Save