DGen
- Compiler flag name change - Comment formatting Compiler - Implemented `getConfig()` in order to return the `Compiler` object's `CompilerConfiguration` instance - Updated a configuration parameters name in the `defaultConfig()` - Added some work-in-progress data structures `ConfigObject` and `ConfigList` Command-line - Added a plethorah of new flags and re-worked a lot of the common flags across the multiple commands to use mixins to avoid code duplication and enforce code re-use - The compilation command now uses the `Compiler` object - You can now control the symbol mapper used - You can now set the verbosity level (no-oped currently) - You can set the output filename - You can set whether pretty code is to be used or not - You can set whether or not to generate the entrypoint testing code during emit
This commit is contained in:
parent
1f6e9cbbb6
commit
3f84020e22
|
@ -16,29 +16,143 @@ import compiler.parsing.core : Parser;
|
|||
import compiler.typecheck.core : TypeChecker;
|
||||
import gogga;
|
||||
import compiler.compiler : Compiler;
|
||||
|
||||
import std.conv : to;
|
||||
//TODO: Re-order the definitions below so that they appear with compile first, then lex, parse, ..., help
|
||||
|
||||
public enum SymbolMappingTechnique
|
||||
{
|
||||
hashmapper,
|
||||
lebanese
|
||||
}
|
||||
|
||||
public enum VerbosityLevel
|
||||
{
|
||||
info,
|
||||
warning,
|
||||
error,
|
||||
debugg
|
||||
}
|
||||
|
||||
// TODO: Add base command as verbosity is something we will always want to control
|
||||
// TODO: Try get inheritane working as we may be able to set things then
|
||||
|
||||
// Stuff that all commands need
|
||||
mixin template BaseCommand()
|
||||
{
|
||||
@ArgPositional("source file", "The source file to compile")
|
||||
string sourceFile;
|
||||
|
||||
@ArgNamed("verbose|v", "Verbosity level")
|
||||
VerbosityLevel debugLevel;
|
||||
|
||||
void BaseCommandInit(Compiler compiler)
|
||||
{
|
||||
// Set the verbosity level
|
||||
compiler.getConfig().setConfig("verbosity", debugLevel);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Base requirements for Emit+
|
||||
*/
|
||||
mixin template EmitBase()
|
||||
{
|
||||
@ArgGroup("Emit", "Options pertaining to the code emitter")
|
||||
{
|
||||
@ArgNamed("symbol-mapper|sm", "The symbol mapping technique to use")
|
||||
@(ArgExistence.optional)
|
||||
SymbolMappingTechnique symbolTechnique;
|
||||
|
||||
@ArgNamed("prettygen|pg", "Generate pretty-printed code")
|
||||
@(ArgExistence.optional)
|
||||
bool prettyPrintCodeGen;
|
||||
|
||||
@ArgNamed("output|o", "Filename of generated object file")
|
||||
@(ArgExistence.optional)
|
||||
string outputFilename = "tlangout.c";
|
||||
|
||||
@ArgNamed("entrypointTest|et", "Whether or not to emit entrypoint testing code")
|
||||
@(ArgExistence.optional)
|
||||
bool entrypointTestEmit = true; // TODO: Change this later to `false` of course
|
||||
}
|
||||
|
||||
void EmitBaseInit(Compiler compiler)
|
||||
{
|
||||
// Set the symbol mapper technique
|
||||
compiler.getConfig().setConfig("emit:mapper", symbolTechnique);
|
||||
|
||||
// Set whether pretty-printed code should be generated
|
||||
compiler.getConfig().setConfig("dgen:pretty_code", prettyPrintCodeGen);
|
||||
|
||||
// Set whether or not to enable the entry point testing code
|
||||
compiler.getConfig().setConfig("dgen:emit_entrypoint_test", entrypointTestEmit);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the given source file from start to finish
|
||||
*/
|
||||
@Command("compile", "Compiles the given file(s)")
|
||||
struct compileCommand
|
||||
{
|
||||
@ArgPositional("source file", "The source file to compile")
|
||||
string sourceFile;
|
||||
mixin BaseCommand!();
|
||||
|
||||
|
||||
|
||||
mixin EmitBase!();
|
||||
|
||||
|
||||
void onExecute()
|
||||
{
|
||||
writeln("Compiling source file: "~sourceFile);
|
||||
try
|
||||
{
|
||||
beginCompilation([sourceFile]);
|
||||
/* Read the source file's data */
|
||||
File file;
|
||||
file.open(sourceFile, "r");
|
||||
ulong fSize = file.size();
|
||||
byte[] data;
|
||||
data.length = fSize;
|
||||
data = file.rawRead(data);
|
||||
string sourceText = cast(string)data;
|
||||
file.close();
|
||||
|
||||
/* Begin lexing process */
|
||||
File outFile;
|
||||
outFile.open(outputFilename, "w");
|
||||
Compiler compiler = new Compiler(sourceText, outFile);
|
||||
|
||||
/* Setup general configuration parameters */
|
||||
BaseCommandInit(compiler);
|
||||
|
||||
/* Perform tokenization */
|
||||
compiler.doLex();
|
||||
writeln("=== Tokens ===\n");
|
||||
writeln(compiler.getTokens());
|
||||
|
||||
/* Perform parsing */
|
||||
compiler.doParse();
|
||||
// TODO: Do something with the returned module
|
||||
auto modulel = compiler.getModule();
|
||||
|
||||
/* Perform typechecking/codegen */
|
||||
compiler.doTypeCheck();
|
||||
|
||||
/**
|
||||
* Configure the emitter and then perform code emit
|
||||
*/
|
||||
EmitBaseInit(compiler);
|
||||
compiler.doEmit();
|
||||
}
|
||||
catch(TError t)
|
||||
{
|
||||
gprintln(t.msg, DebugType.ERROR);
|
||||
}
|
||||
catch(ErrnoException e)
|
||||
{
|
||||
/* TODO: Use gogga error */
|
||||
writeln("Could not open source file "~sourceFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,8 +162,7 @@ struct compileCommand
|
|||
@Command("lex", "Performs tokenization of the given file(s)")
|
||||
struct lexCommand
|
||||
{
|
||||
@ArgPositional("source file", "The source file to lex")
|
||||
string sourceFile;
|
||||
mixin BaseCommand!();
|
||||
|
||||
void onExecute()
|
||||
{
|
||||
|
@ -69,6 +182,11 @@ struct lexCommand
|
|||
|
||||
/* Begin lexing process */
|
||||
Compiler compiler = new Compiler(sourceText, File());
|
||||
|
||||
/* Setup general configuration parameters */
|
||||
BaseCommandInit(compiler);
|
||||
|
||||
|
||||
compiler.doLex();
|
||||
writeln("=== Tokens ===\n");
|
||||
writeln(compiler.getTokens());
|
||||
|
@ -88,8 +206,8 @@ struct lexCommand
|
|||
@Command("syntaxcheck", "Check the syntax of the program")
|
||||
struct parseCommand
|
||||
{
|
||||
@ArgPositional("source file", "The source file to check syntax of")
|
||||
string sourceFile;
|
||||
mixin BaseCommand!();
|
||||
|
||||
|
||||
/* TODO: Add missing implementation for this */
|
||||
void onExecute()
|
||||
|
@ -108,6 +226,10 @@ struct parseCommand
|
|||
|
||||
/* Begin lexing process */
|
||||
Compiler compiler = new Compiler(sourceText, File());
|
||||
|
||||
/* Setup general configuration parameters */
|
||||
BaseCommandInit(compiler);
|
||||
|
||||
compiler.doLex();
|
||||
writeln("=== Tokens ===\n");
|
||||
writeln(compiler.getTokens());
|
||||
|
@ -132,8 +254,8 @@ struct parseCommand
|
|||
@Command("typecheck", "Perform typechecking on the program")
|
||||
struct typecheckCommand
|
||||
{
|
||||
@ArgPositional("source file", "The source file to typecheck")
|
||||
string sourceFile;
|
||||
mixin BaseCommand!();
|
||||
|
||||
|
||||
void onExecute()
|
||||
{
|
||||
|
@ -151,6 +273,10 @@ struct typecheckCommand
|
|||
|
||||
/* Begin lexing process */
|
||||
Compiler compiler = new Compiler(sourceText, File());
|
||||
|
||||
/* Setup general configuration parameters */
|
||||
BaseCommandInit(compiler);
|
||||
|
||||
compiler.doLex();
|
||||
writeln("=== Tokens ===\n");
|
||||
writeln(compiler.getTokens());
|
||||
|
@ -175,63 +301,6 @@ struct typecheckCommand
|
|||
}
|
||||
}
|
||||
|
||||
// @Command("emit", "Perform emitting on the program")
|
||||
// struct emitCommand
|
||||
// {
|
||||
// @ArgPositional("source file", "The source file to emit")
|
||||
// string sourceFile;
|
||||
|
||||
// /* TODO: Add missing implementation for this */
|
||||
// void onExecute()
|
||||
// {
|
||||
// // TODO: Add call to typechecker here
|
||||
// try
|
||||
// {
|
||||
// /* Read the source file's data */
|
||||
// File file;
|
||||
// file.open(sourceFile, "r");
|
||||
// ulong fSize = file.size();
|
||||
// byte[] data;
|
||||
// data.length = fSize;
|
||||
// data = file.rawRead(data);
|
||||
// string sourceText = cast(string)data;
|
||||
// file.close();
|
||||
|
||||
// /* Begin lexing process */
|
||||
// Lexer lexer = new Lexer(sourceText);
|
||||
// if(lexer.performLex())
|
||||
// {
|
||||
// Token[] tokens = lexer.getTokens();
|
||||
// writeln("=== Tokens ===\n");
|
||||
// writeln(tokens);
|
||||
|
||||
// // TODO: Catch exception
|
||||
// Parser parser = new Parser(tokens);
|
||||
// // TODO: Do something with the returned module
|
||||
// auto modulel = parser.parse();
|
||||
|
||||
// //TODO: collect results here
|
||||
// //TODO: catch exceptions
|
||||
// TypeChecker typeChecker = new TypeChecker(modulel);
|
||||
// typeChecker.beginCheck();
|
||||
|
||||
// //TODO: emit is basically full cpmpile or nah? we should write emit to stdout actually
|
||||
// //or nah?
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// /* TODO: Is the lexer.performLex() return value used? */
|
||||
// writeln("There was an error whilst performing tokenization");
|
||||
// }
|
||||
// }
|
||||
// catch(ErrnoException e)
|
||||
// {
|
||||
// /* TODO: Use gogga error */
|
||||
// writeln("Could not open source file "~sourceFile);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
@Command("help", "Shows the help screen")
|
||||
struct helpCommand
|
||||
{
|
||||
|
|
|
@ -554,7 +554,7 @@ public final class DCodeEmitter : CodeEmitter
|
|||
|
||||
|
||||
// If enabled (default: yes) then emit entry point (TODO: change later)
|
||||
if(config.getConfig!(bool)("dgen_emit_entrypoint_test"))
|
||||
if(config.getConfig!(bool)("dgen:emit_entrypoint_test"))
|
||||
{
|
||||
//TODO: Emit main (entry point)
|
||||
emitEntryPoint();
|
||||
|
@ -776,7 +776,7 @@ public final class DCodeEmitter : CodeEmitter
|
|||
|
||||
private void emitEntryPoint()
|
||||
{
|
||||
//TODO: Implement me
|
||||
// TODO: Implement me
|
||||
|
||||
// Test for `simple_functions.t` (function call testing)
|
||||
if(cmp(typeChecker.getModule().getName(), "simple_functions") == 0)
|
||||
|
|
|
@ -39,6 +39,16 @@ public final class CompilerException : TError
|
|||
}
|
||||
}
|
||||
|
||||
public class ConfigObject
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class ConfigList : ConfigObject
|
||||
{
|
||||
private ConfigObject[] list;
|
||||
}
|
||||
|
||||
public class CompilerConfiguration
|
||||
{
|
||||
private string[string] config;
|
||||
|
@ -105,13 +115,16 @@ public class Compiler
|
|||
config.setConfig("dgen:pretty_code", true);
|
||||
|
||||
/* Enable entry point test generation for DGen */
|
||||
config.setConfig("dgen_emit_entrypoint_test", true);
|
||||
config.setConfig("dgen:emit_entrypoint_test", true);
|
||||
|
||||
/* Set the mapping to hashing of entity names (TODO: This should be changed before release) */
|
||||
config.setConfig("emit:mapper", "hashmapper");
|
||||
}
|
||||
|
||||
|
||||
public CompilerConfiguration getConfig()
|
||||
{
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new compiler instance to compile the given
|
||||
|
|
Loading…
Reference in New Issue