2021-03-02 19:51:49 +00:00
|
|
|
/**
|
2022-12-14 17:49:08 +00:00
|
|
|
* Commands
|
|
|
|
*
|
|
|
|
* All command-line arguments and their impementations
|
|
|
|
*/
|
2021-03-02 19:51:49 +00:00
|
|
|
|
|
|
|
module commandline.commands;
|
|
|
|
|
|
|
|
import jcli;
|
|
|
|
import std.stdio;
|
2021-03-02 19:55:45 +00:00
|
|
|
import compiler.compiler : beginCompilation;
|
2023-01-22 12:59:55 +00:00
|
|
|
import misc.exceptions : TError;
|
2022-01-20 08:54:21 +00:00
|
|
|
import std.exception : ErrnoException;
|
2022-12-14 17:49:08 +00:00
|
|
|
import compiler.lexer : Lexer, Token;
|
|
|
|
import compiler.parsing.core : Parser;
|
|
|
|
import compiler.typecheck.core : TypeChecker;
|
2023-01-22 12:59:55 +00:00
|
|
|
import gogga;
|
2021-03-02 19:51:49 +00:00
|
|
|
|
2022-12-14 17:49:08 +00:00
|
|
|
//TODO: Re-order the definitions below so that they appear with compile first, then lex, parse, ..., help
|
2021-03-02 19:51:49 +00:00
|
|
|
|
2022-01-20 08:54:21 +00:00
|
|
|
/**
|
|
|
|
* Compile the given source file from start to finish
|
|
|
|
*/
|
2021-03-02 19:51:49 +00:00
|
|
|
@Command("compile", "Compiles the given file(s)")
|
|
|
|
struct compileCommand
|
|
|
|
{
|
2022-08-23 15:33:49 +01:00
|
|
|
@ArgPositional("source file", "The source file to compile")
|
2021-03-02 19:51:49 +00:00
|
|
|
string sourceFile;
|
|
|
|
|
|
|
|
// @CommandRawListArg
|
|
|
|
// string[] d;
|
|
|
|
// TODO: Get array
|
|
|
|
|
|
|
|
void onExecute()
|
|
|
|
{
|
|
|
|
writeln("Compiling source file: "~sourceFile);
|
2021-03-02 19:55:45 +00:00
|
|
|
beginCompilation([sourceFile]);
|
2021-03-02 19:51:49 +00:00
|
|
|
}
|
2022-01-20 08:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Only perform tokenization of the given source files
|
|
|
|
*/
|
|
|
|
@Command("lex", "Performs tokenization of the given file(s)")
|
|
|
|
struct lexCommand
|
|
|
|
{
|
2022-12-14 17:49:08 +00:00
|
|
|
@ArgPositional("source file", "The source file to lex")
|
2022-01-20 08:54:21 +00:00
|
|
|
string sourceFile;
|
|
|
|
|
|
|
|
void onExecute()
|
|
|
|
{
|
|
|
|
writeln("Performing tokenization on file: "~sourceFile);
|
|
|
|
|
|
|
|
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;
|
2022-12-14 17:49:08 +00:00
|
|
|
file.close();
|
2022-01-20 08:54:21 +00:00
|
|
|
|
|
|
|
/* Begin lexing process */
|
|
|
|
Lexer lexer = new Lexer(sourceText);
|
2023-01-22 12:59:55 +00:00
|
|
|
lexer.performLex();
|
|
|
|
|
|
|
|
writeln("=== Tokens ===\n");
|
|
|
|
writeln(lexer.getTokens());
|
|
|
|
}
|
|
|
|
catch(TError t)
|
|
|
|
{
|
|
|
|
gprintln(t.msg, DebugType.ERROR);
|
2022-01-20 08:54:21 +00:00
|
|
|
}
|
|
|
|
catch(ErrnoException e)
|
|
|
|
{
|
|
|
|
/* TODO: Use gogga error */
|
|
|
|
writeln("Could not open source file "~sourceFile);
|
|
|
|
}
|
|
|
|
}
|
2022-12-14 17:49:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Command("syntaxcheck", "Check the syntax of the program")
|
|
|
|
struct parseCommand
|
|
|
|
{
|
|
|
|
@ArgPositional("source file", "The source file to check syntax of")
|
|
|
|
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);
|
2023-01-22 12:59:55 +00:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
catch(TError t)
|
|
|
|
{
|
|
|
|
gprintln(t.msg, DebugType.ERROR);
|
2022-12-14 17:49:08 +00:00
|
|
|
}
|
|
|
|
catch(ErrnoException e)
|
|
|
|
{
|
|
|
|
/* TODO: Use gogga error */
|
|
|
|
writeln("Could not open source file "~sourceFile);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Command("typecheck", "Perform typechecking on the program")
|
|
|
|
struct typecheckCommand
|
|
|
|
{
|
|
|
|
@ArgPositional("source file", "The source file to typecheck")
|
|
|
|
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);
|
2023-01-22 12:59:55 +00:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
catch(TError t)
|
|
|
|
{
|
|
|
|
gprintln(t.msg, DebugType.ERROR);
|
2022-12-14 17:49:08 +00:00
|
|
|
}
|
|
|
|
catch(ErrnoException e)
|
|
|
|
{
|
|
|
|
/* TODO: Use gogga error */
|
|
|
|
writeln("Could not open source file "~sourceFile);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// @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
|
|
|
|
{
|
|
|
|
/* TODO: Add missing implementation for this */
|
|
|
|
void onExecute()
|
|
|
|
{
|
|
|
|
/* TODO: We want to show the commands list, not a seperate help command */
|
|
|
|
}
|
2021-03-02 19:51:49 +00:00
|
|
|
}
|