Compile to bytecode
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
#include <compile/compiler.hpp>
|
||||
#include <compile/errors.hpp>
|
||||
#include <execute/error.hpp>
|
||||
#include <fstream>
|
||||
#include <interpret/errors.hpp>
|
||||
#include <preprocessor/preprocessor.hpp>
|
||||
#include <token/errors.hpp>
|
||||
#include <wassembler.hpp>
|
||||
@@ -19,18 +21,13 @@ void PrintBadToken(Token::Token const & token, std::vector<std::string> const &
|
||||
std::puts("^");
|
||||
}
|
||||
|
||||
void PrintTokenError(Interpret::InterpretationError const & err, std::vector<std::string> const & lines)
|
||||
{
|
||||
PrintBadToken(err.errorToken, lines);
|
||||
}
|
||||
|
||||
void PrintTokenError(Token::TokenizationError const & err, std::vector<std::string> const & lines)
|
||||
{
|
||||
std::printf("%s ", err.errorMsg.c_str());
|
||||
PrintBadToken(err.errorToken, lines);
|
||||
}
|
||||
|
||||
bool Wassembler::LoadLinesFromFile(std::string const & filePath, std::vector<std::string> & lines) const
|
||||
bool Wassembler::LoadTextFile(std::string const & filePath, std::vector<std::string> & lines) const
|
||||
{
|
||||
std::ifstream input(filePath);
|
||||
if (!input.is_open())
|
||||
@@ -48,7 +45,19 @@ bool Wassembler::LoadLinesFromFile(std::string const & filePath, std::vector<std
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Wassembler::LoadTokens(std::vector<std::string> const & lines, std::vector<Token::Token> & tokens) const
|
||||
bool Wassembler::Preprocess(std::vector<std::string> & lines) const
|
||||
{
|
||||
Preprocessor preprocessor;
|
||||
preprocessor.process(lines);
|
||||
if (printSubstitutions)
|
||||
{
|
||||
preprocessor.printSubstitutions();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Wassembler::Tokenize(std::vector<std::string> const & lines, std::vector<Token::Token> & tokens) const
|
||||
{
|
||||
Token::Tokenizer tokenizer;
|
||||
bool tokenizationError = false;
|
||||
@@ -98,9 +107,64 @@ bool Wassembler::LoadTokens(std::vector<std::string> const & lines, std::vector<
|
||||
return !(syntaxError || tokenizationError);
|
||||
}
|
||||
|
||||
bool Wassembler::CompileToBytes(
|
||||
std::vector<Token::Token> const & tokens,
|
||||
std::vector<std::string> const & lines,
|
||||
std::vector<std::uint8_t> & bytes) const
|
||||
{
|
||||
Compile::Compiler compiler;
|
||||
try
|
||||
{
|
||||
compiler.Compile(tokens, bytes);
|
||||
}
|
||||
catch(Compile::CompilationError & e)
|
||||
{
|
||||
std::printf("Semantic error ");
|
||||
PrintBadToken(e.errorToken, lines);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Wassembler::ExecuteCode(std::vector<uint8_t> const & bytes)
|
||||
{
|
||||
vm.LoadCode(bytes, printTranslatedBytes);
|
||||
// TODO clear memory?
|
||||
vm.Run();
|
||||
}
|
||||
|
||||
bool Wassembler::CompileFile(
|
||||
std::string const & filePath,
|
||||
std::vector<std::uint8_t> & bytes) const
|
||||
{
|
||||
std::vector<std::string> lines;
|
||||
if (!LoadTextFile(filePath, lines))
|
||||
{
|
||||
std::printf("Error: Cannot open file %s for reading", filePath.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!Preprocess(lines))
|
||||
{
|
||||
std::puts("Aborting due to preprocessor error(s)");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<Token::Token> tokens;
|
||||
if (!Tokenize(lines, tokens) || !CompileToBytes(tokens, lines, bytes))
|
||||
{
|
||||
std::puts("Aborting due to syntax error(s)");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Wassembler::SetMemorySize(unsigned const size)
|
||||
{
|
||||
config.memorySize = size;
|
||||
vm.SetMemorySize(size);
|
||||
}
|
||||
|
||||
void Wassembler::EnableSubstitutionsLogging()
|
||||
@@ -113,50 +177,54 @@ void Wassembler::EnableTokensLogging()
|
||||
printTokens = true;
|
||||
}
|
||||
|
||||
bool Wassembler::LoadFromFile(std::string const & filePath)
|
||||
void Wassembler::EnableByteTranslationLogging()
|
||||
{
|
||||
printTranslatedBytes = true;
|
||||
}
|
||||
|
||||
bool Wassembler::CompileAndRun(std::string const & filePath)
|
||||
{
|
||||
std::vector<std::string> lines;
|
||||
if (!LoadLinesFromFile(filePath, lines))
|
||||
std::vector<std::uint8_t> bytes;
|
||||
if (!CompileFile(filePath, bytes))
|
||||
{
|
||||
std::printf("Error: Cannot open file %s for reading", filePath.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
Preprocessor preprocessor;
|
||||
preprocessor.process(lines);
|
||||
if (printSubstitutions)
|
||||
{
|
||||
preprocessor.printSubstitutions();
|
||||
}
|
||||
|
||||
std::vector<Token::Token> tokens;
|
||||
if (!LoadTokens(lines, tokens))
|
||||
{
|
||||
std::puts("Aborting due to syntax error(s)");
|
||||
return false;
|
||||
}
|
||||
|
||||
Interpret::Interpreter interpreter;
|
||||
auto codePtr = std::make_unique<Interpret::Code>();
|
||||
try
|
||||
{
|
||||
interpreter.Interpret(tokens, *codePtr);
|
||||
ExecuteCode(bytes);
|
||||
}
|
||||
catch(Interpret::InterpretationError & e)
|
||||
catch (Execute::RuntimeError const & e)
|
||||
{
|
||||
std::printf("Semantic error ");
|
||||
PrintBadToken(e.errorToken, lines);
|
||||
std::puts("Aborting due to semantic error(s)");
|
||||
std::puts(e.GetMessage().c_str());
|
||||
std::puts("Aborting due to runtime error(s)");
|
||||
return false;
|
||||
}
|
||||
|
||||
vm.LoadCode(std::move(codePtr));
|
||||
vm.LoadConfiguration(config);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Wassembler::Run()
|
||||
bool Wassembler::CompileToFile(
|
||||
std::string const & inputFilePath,
|
||||
std::string const & outputFilePath)
|
||||
{
|
||||
vm.Run();
|
||||
std::vector<std::uint8_t> bytes;
|
||||
if (!CompileFile(inputFilePath, bytes))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::ofstream output(outputFilePath, std::ios::binary | std::ios::trunc);
|
||||
if (!output.is_open())
|
||||
{
|
||||
std::printf("Error: Cannot open file %s for writing", outputFilePath.c_str());
|
||||
return false;
|
||||
}
|
||||
for(std::size_t i = 0; i < bytes.size(); ++i)
|
||||
{
|
||||
output << bytes[i];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user