Compiler
- Moved configuration sub-system to its own class `CompilerConfiguration` - `getConfig()` and `setConfig()` are now templatised to generate, at compile-time, type-specific versions which will fetch and convert using the requested type - Added some more default configuration parameters for DGen DGen - Implemented configuration checking for `genTabs()` and `emitEntryPoint()` (both which have the default config value of `true`) - Added commented-out testing code (see issue #88)
This commit is contained in:
parent
a772b55966
commit
a987f114ac
|
@ -10,6 +10,7 @@ import compiler.codegen.instruction : Instruction;
|
||||||
import std.range : walkLength;
|
import std.range : walkLength;
|
||||||
import gogga;
|
import gogga;
|
||||||
import std.conv : to;
|
import std.conv : to;
|
||||||
|
import compiler.compiler : CompilerConfiguration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: Perhaps have an interface that can emit(Context/Parent, Statement)
|
* TODO: Perhaps have an interface that can emit(Context/Parent, Statement)
|
||||||
|
@ -21,6 +22,7 @@ public abstract class CodeEmitter
|
||||||
{
|
{
|
||||||
protected TypeChecker typeChecker;
|
protected TypeChecker typeChecker;
|
||||||
protected File file;
|
protected File file;
|
||||||
|
protected CompilerConfiguration config;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The selected queue is the queue to be used
|
* The selected queue is the queue to be used
|
||||||
|
@ -125,7 +127,7 @@ public abstract class CodeEmitter
|
||||||
return functionBodyInstrs.keys();
|
return functionBodyInstrs.keys();
|
||||||
}
|
}
|
||||||
|
|
||||||
this(TypeChecker typeChecker, File file)
|
this(TypeChecker typeChecker, File file, CompilerConfiguration config)
|
||||||
{
|
{
|
||||||
this.typeChecker = typeChecker;
|
this.typeChecker = typeChecker;
|
||||||
|
|
||||||
|
@ -138,6 +140,7 @@ public abstract class CodeEmitter
|
||||||
gprintln("CodeEmitter: Got number of function defs: "~to!(string)(functionBodyInstrs));
|
gprintln("CodeEmitter: Got number of function defs: "~to!(string)(functionBodyInstrs));
|
||||||
|
|
||||||
this.file = file;
|
this.file = file;
|
||||||
|
this.config = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -18,6 +18,7 @@ import compiler.symbols.data : SymbolType, Variable, Function, VariableParameter
|
||||||
import compiler.symbols.check : getCharacter;
|
import compiler.symbols.check : getCharacter;
|
||||||
import misc.utils : Stack;
|
import misc.utils : Stack;
|
||||||
import compiler.symbols.typing.core : Type, Primitive, Integer, Void, Pointer;
|
import compiler.symbols.typing.core : Type, Primitive, Integer, Void, Pointer;
|
||||||
|
import compiler.compiler : CompilerConfiguration;
|
||||||
|
|
||||||
public final class DCodeEmitter : CodeEmitter
|
public final class DCodeEmitter : CodeEmitter
|
||||||
{
|
{
|
||||||
|
@ -27,9 +28,9 @@ public final class DCodeEmitter : CodeEmitter
|
||||||
private bool varDecWantsConsumeVarAss = false;
|
private bool varDecWantsConsumeVarAss = false;
|
||||||
|
|
||||||
|
|
||||||
this(TypeChecker typeChecker, File file)
|
this(TypeChecker typeChecker, File file, CompilerConfiguration config)
|
||||||
{
|
{
|
||||||
super(typeChecker, file);
|
super(typeChecker, file, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ulong transformDepth = 0;
|
private ulong transformDepth = 0;
|
||||||
|
@ -37,10 +38,16 @@ public final class DCodeEmitter : CodeEmitter
|
||||||
private string genTabs(ulong count)
|
private string genTabs(ulong count)
|
||||||
{
|
{
|
||||||
string tabStr;
|
string tabStr;
|
||||||
for(ulong i = 0; i < count; i++)
|
|
||||||
|
/* Only generate tabs if enabled in compiler config */
|
||||||
|
if(config.getConfig!(bool)("dgen:pretty_code"))
|
||||||
{
|
{
|
||||||
tabStr~="\t";
|
for(ulong i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
tabStr~="\t";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return tabStr;
|
return tabStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -515,8 +522,13 @@ public final class DCodeEmitter : CodeEmitter
|
||||||
emitFunctionPrototypes();
|
emitFunctionPrototypes();
|
||||||
emitFunctionDefinitions();
|
emitFunctionDefinitions();
|
||||||
|
|
||||||
//TODO: Emit main (entry point)
|
|
||||||
emitEntryPoint();
|
// If enabled (default: yes) then emit entry point (TODO: change later)
|
||||||
|
if(config.getConfig!(bool)("dgen_emit_entrypoint_test"))
|
||||||
|
{
|
||||||
|
//TODO: Emit main (entry point)
|
||||||
|
emitEntryPoint();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -13,6 +13,30 @@ import core.stdc.stdlib;
|
||||||
import compiler.codegen.emit.core;
|
import compiler.codegen.emit.core;
|
||||||
import compiler.codegen.emit.dgen;
|
import compiler.codegen.emit.dgen;
|
||||||
|
|
||||||
|
public class CompilerConfiguration
|
||||||
|
{
|
||||||
|
private string[string] config;
|
||||||
|
|
||||||
|
public void setConfig(VType)(string key, VType value)
|
||||||
|
{
|
||||||
|
config[key] = to!(string)(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public VType getConfig(VType)(string key)
|
||||||
|
{
|
||||||
|
import std.algorithm : canFind;
|
||||||
|
if(canFind(config.keys(), key))
|
||||||
|
{
|
||||||
|
return to!(VType)(config[key]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO: Change to a TError
|
||||||
|
// throw new Exception("Key not found");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class Compiler
|
public class Compiler
|
||||||
{
|
{
|
||||||
|
@ -32,33 +56,23 @@ public class Compiler
|
||||||
private CodeEmitter emitter;
|
private CodeEmitter emitter;
|
||||||
private File emitOutFile;
|
private File emitOutFile;
|
||||||
|
|
||||||
private string[string] config;
|
/* The configuration */
|
||||||
|
private CompilerConfiguration config;
|
||||||
|
|
||||||
/* TODO: Make the default config */
|
/* TODO: Make the default config */
|
||||||
private void defaultConfig()
|
private void defaultConfig()
|
||||||
{
|
{
|
||||||
/* Enable Behaviour-C fixes */
|
/* Enable Behaviour-C fixes */
|
||||||
setConfig("behavec:preinline_args", "true");
|
config.setConfig("behavec:preinline_args", true);
|
||||||
|
|
||||||
|
/* Enable pretty code generation for DGen */
|
||||||
|
config.setConfig("dgen:pretty_code", true);
|
||||||
|
|
||||||
|
/* Enable entry point test generation for DGen */
|
||||||
|
config.setConfig("dgen_emit_entrypoint_test", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setConfig(string key, string value)
|
|
||||||
{
|
|
||||||
config[key] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string getConfig(string key)
|
|
||||||
{
|
|
||||||
import std.algorithm : canFind;
|
|
||||||
if(canFind(config.keys(), key))
|
|
||||||
{
|
|
||||||
return config[key];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// TODO: Change to a TError
|
|
||||||
throw new Exception("Key not found");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new compiler instance to compile the given
|
* Create a new compiler instance to compile the given
|
||||||
|
@ -71,6 +85,8 @@ public class Compiler
|
||||||
this.inputSource = sourceCode;
|
this.inputSource = sourceCode;
|
||||||
this.emitOutFile = emitOutFile;
|
this.emitOutFile = emitOutFile;
|
||||||
|
|
||||||
|
this.config = new CompilerConfiguration();
|
||||||
|
|
||||||
/* Enable the default config */
|
/* Enable the default config */
|
||||||
defaultConfig();
|
defaultConfig();
|
||||||
}
|
}
|
||||||
|
@ -100,7 +116,7 @@ public class Compiler
|
||||||
this.typeChecker.beginCheck();
|
this.typeChecker.beginCheck();
|
||||||
|
|
||||||
/* Perform code emitting */
|
/* Perform code emitting */
|
||||||
this.emitter = new DCodeEmitter(typeChecker, emitOutFile);
|
this.emitter = new DCodeEmitter(typeChecker, emitOutFile, config);
|
||||||
emitter.emit(); // Emit the code
|
emitter.emit(); // Emit the code
|
||||||
emitOutFile.close(); // Flush (perform the write() syscall)
|
emitOutFile.close(); // Flush (perform the write() syscall)
|
||||||
emitter.finalize(); // Call CC on the file containing generated C code
|
emitter.finalize(); // Call CC on the file containing generated C code
|
||||||
|
@ -147,4 +163,24 @@ void beginCompilation(string[] sourceFiles)
|
||||||
/* Perform the compilation */
|
/* Perform the compilation */
|
||||||
compiler.compile();
|
compiler.compile();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
// TODO: Add tests here for our `simple_<x>.t` tests or put them in DGen, I think here is better
|
||||||
|
// FIXME: Crashes and I think because too fast or actually bad state? Maybe something is not being
|
||||||
|
// cleared, I believe this may be what is happening
|
||||||
|
// ... see issue #88
|
||||||
|
// string[] testFiles = ["source/tlang/testing/simple_functions.t",
|
||||||
|
// "source/tlang/testing/simple_while.t",
|
||||||
|
// "source/tlang/testing/simple_for_loops.t",
|
||||||
|
// "source/tlang/testing/simple_cast.t",
|
||||||
|
// "source/tlang/testing/simple_conditionals.t",
|
||||||
|
// "source/tlang/testing/nested_conditionals.t",
|
||||||
|
// "source/tlang/testing/simple_discard.t"
|
||||||
|
// ];
|
||||||
|
// foreach(string testFile; testFiles)
|
||||||
|
// {
|
||||||
|
// beginCompilation([testFile]);
|
||||||
|
// }
|
||||||
}
|
}
|
Loading…
Reference in New Issue