Refactor main.cpp functions into separate class
This commit is contained in:
121
src/wassembler.cpp
Normal file
121
src/wassembler.cpp
Normal file
@@ -0,0 +1,121 @@
|
||||
#include <fstream>
|
||||
#include <interpret/errors.hpp>
|
||||
#include <token/errors.hpp>
|
||||
#include <wassembler.hpp>
|
||||
|
||||
void PrintBadToken(Token::Token const & token, std::vector<std::string> const & lines)
|
||||
{
|
||||
std::printf("at line number %i, column %i:\n",
|
||||
token.lineNumber + 1,
|
||||
token.lineColumn + 1);
|
||||
std::printf("%s\n", lines[token.lineNumber].c_str());
|
||||
for(int i = 0; i < token.lineColumn; ++i)
|
||||
{
|
||||
std::putc(' ', stdout);
|
||||
}
|
||||
std::puts("^");
|
||||
}
|
||||
|
||||
void PrintTokenError(Interpret::InterpretationError const & err, std::vector<std::string> const & lines)
|
||||
{
|
||||
std::printf("%s ", err.errorMsg.c_str());
|
||||
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
|
||||
{
|
||||
std::ifstream input(filePath);
|
||||
if (!input.is_open())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string line;
|
||||
while(std::getline(input, line))
|
||||
{
|
||||
lines.push_back(line);
|
||||
}
|
||||
input.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Wassembler::LoadTokens(std::vector<std::string> const & lines, std::vector<Token::Token> & tokens) const
|
||||
{
|
||||
Token::Tokenizer tokenizer;
|
||||
bool tokenizationError = false;
|
||||
for(std::size_t i = 0; i < lines.size(); ++i)
|
||||
{
|
||||
try
|
||||
{
|
||||
tokenizer.Tokenize(lines[i], i, tokens);
|
||||
}
|
||||
catch(Token::TokenizationError & err)
|
||||
{
|
||||
tokenizationError = true;
|
||||
PrintTokenError(err, lines);
|
||||
}
|
||||
}
|
||||
|
||||
// Validate the syntax
|
||||
bool syntaxError = false;
|
||||
for(auto const & token : tokens)
|
||||
{
|
||||
if (!token.isValid)
|
||||
{
|
||||
std::printf("Syntax error ");
|
||||
PrintBadToken(token, lines);
|
||||
syntaxError = true;
|
||||
}
|
||||
}
|
||||
|
||||
return !(syntaxError || tokenizationError);
|
||||
}
|
||||
|
||||
bool Wassembler::LoadFromFile(std::string const & filePath)
|
||||
{
|
||||
std::vector<std::string> lines;
|
||||
if (!LoadLinesFromFile(filePath, lines))
|
||||
{
|
||||
std::printf("Error: Cannot open file %s for reading", filePath.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
catch(Interpret::InterpretationError & e)
|
||||
{
|
||||
PrintBadToken(e.errorToken, lines);
|
||||
return false;
|
||||
}
|
||||
|
||||
vm.LoadCode(std::move(codePtr));
|
||||
|
||||
Configuration config;
|
||||
vm.LoadConfiguration(config);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Wassembler::Run()
|
||||
{
|
||||
vm.Run();
|
||||
}
|
||||
Reference in New Issue
Block a user