Refactor main.cpp functions into separate class
This commit is contained in:
13
include/configuration.hpp
Normal file
13
include/configuration.hpp
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
struct Configuration
|
||||||
|
{
|
||||||
|
unsigned memorySize;
|
||||||
|
std::vector<std::pair<unsigned, std::string>> strings;
|
||||||
|
|
||||||
|
void PrepareMemory(std::vector<std::uint8_t> & memory) const;
|
||||||
|
Configuration();
|
||||||
|
};
|
||||||
@@ -9,12 +9,10 @@ namespace Execute
|
|||||||
{
|
{
|
||||||
unsigned currentStatement;
|
unsigned currentStatement;
|
||||||
unsigned nextStatement;
|
unsigned nextStatement;
|
||||||
std::unordered_map<std::string, unsigned> const & labelStatementIndice;
|
std::unordered_map<std::string, unsigned> const * labelStatementIndice;
|
||||||
std::vector<InterruptFn> const interrupts;
|
std::vector<InterruptFn> interrupts;
|
||||||
std::vector<std::uint8_t> memory;
|
std::vector<std::uint8_t> memory;
|
||||||
unsigned stackPointer;
|
unsigned stackPointer;
|
||||||
bool terminated;
|
bool terminated;
|
||||||
|
|
||||||
State(std::unordered_map<std::string, unsigned> const & labelStatementIndice, unsigned const memorySize);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
|
#include <configuration.hpp>
|
||||||
#include <execute/flags.hpp>
|
#include <execute/flags.hpp>
|
||||||
#include <execute/registers.hpp>
|
#include <execute/registers.hpp>
|
||||||
#include <execute/state.hpp>
|
#include <execute/state.hpp>
|
||||||
#include <interpret/code.hpp>
|
#include <interpret/code.hpp>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace Execute
|
namespace Execute
|
||||||
{
|
{
|
||||||
@@ -11,17 +13,16 @@ namespace Execute
|
|||||||
Flags flags;
|
Flags flags;
|
||||||
Registers registers;
|
Registers registers;
|
||||||
State state;
|
State state;
|
||||||
bool terminated;
|
|
||||||
|
|
||||||
Interpret::Code const & code;
|
std::unique_ptr<Interpret::Code const> codePtr;
|
||||||
|
|
||||||
void Step();
|
void Step();
|
||||||
|
|
||||||
VirtualMachine(Interpret::Code const & code, unsigned const memorySize);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void Run();
|
void Run();
|
||||||
void SingleStep();
|
void SingleStep();
|
||||||
|
void LoadConfiguration(Configuration const & c);
|
||||||
|
void LoadCode(std::unique_ptr<Interpret::Code> code);
|
||||||
|
|
||||||
Flags const & GetFlags() const;
|
Flags const & GetFlags() const;
|
||||||
Registers const & GetRegisters() const;
|
Registers const & GetRegisters() const;
|
||||||
@@ -30,6 +31,6 @@ namespace Execute
|
|||||||
|
|
||||||
bool IsTerminated() const;
|
bool IsTerminated() const;
|
||||||
|
|
||||||
static VirtualMachine CreateFromCode(Interpret::Code const & code);
|
VirtualMachine();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -12,5 +12,10 @@ namespace Interpret
|
|||||||
std::vector<std::unique_ptr<Statement>> statements;
|
std::vector<std::unique_ptr<Statement>> statements;
|
||||||
std::unordered_map<std::string, unsigned> labelStatementIndice;
|
std::unordered_map<std::string, unsigned> labelStatementIndice;
|
||||||
std::unordered_map<std::string, int> declarations;
|
std::unordered_map<std::string, int> declarations;
|
||||||
|
|
||||||
|
Code() = default;
|
||||||
|
~Code() = default;
|
||||||
|
Code(const Code&) = delete;
|
||||||
|
Code& operator=(const Code&) = delete;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <token/registertype.hpp>
|
#include <token/registertype.hpp>
|
||||||
#include <token/tokentype.hpp>
|
#include <token/tokentype.hpp>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace Token
|
namespace Token
|
||||||
{
|
{
|
||||||
@@ -46,4 +47,6 @@ namespace Token
|
|||||||
|
|
||||||
void DebugPrint() const;
|
void DebugPrint() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void PrintTokens(std::vector<Token> const & tokens);
|
||||||
}
|
}
|
||||||
|
|||||||
22
include/wassembler.hpp
Normal file
22
include/wassembler.hpp
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <configuration.hpp>
|
||||||
|
#include <execute/virtualmachine.hpp>
|
||||||
|
#include <preprocessor/preprocessor.hpp>
|
||||||
|
#include <interpret/interpreter.hpp>
|
||||||
|
#include <token/tokenizer.hpp>
|
||||||
|
|
||||||
|
class Wassembler
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
Execute::VirtualMachine vm;
|
||||||
|
|
||||||
|
bool LoadLinesFromFile(std::string const & filePath, std::vector<std::string> & lines) const;
|
||||||
|
bool LoadTokens(std::vector<std::string> const & lines, std::vector<Token::Token> & tokens) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool LoadFromFile(std::string const & filePath);
|
||||||
|
|
||||||
|
void Run();
|
||||||
|
|
||||||
|
Wassembler() = default;
|
||||||
|
};
|
||||||
25
src/configuration.cpp
Normal file
25
src/configuration.cpp
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#include <configuration.hpp>
|
||||||
|
|
||||||
|
void Configuration::PrepareMemory(std::vector<std::uint8_t> & memory) const
|
||||||
|
{
|
||||||
|
memory.resize(memorySize);
|
||||||
|
|
||||||
|
for(auto const & pair : strings)
|
||||||
|
{
|
||||||
|
for(std::size_t i = 0; i < pair.second.size(); ++i)
|
||||||
|
{
|
||||||
|
auto const index = i + pair.first;
|
||||||
|
if (index >= memory.size())
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
memory[index] = pair.second[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Configuration::Configuration()
|
||||||
|
: memorySize(1024)
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
#include <execute/state.hpp>
|
|
||||||
|
|
||||||
namespace Execute
|
|
||||||
{
|
|
||||||
State::State(std::unordered_map<std::string, unsigned> const & _labelStatementIndice, unsigned const memorySize)
|
|
||||||
: currentStatement(0u),
|
|
||||||
nextStatement(1u),
|
|
||||||
labelStatementIndice(_labelStatementIndice),
|
|
||||||
interrupts(GetInterrupts()),
|
|
||||||
memory(memorySize),
|
|
||||||
stackPointer(0u),
|
|
||||||
terminated(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -9,11 +9,11 @@ namespace Execute
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
code.statements[state.currentStatement]->Execute(flags, state, registers);
|
codePtr->statements[state.currentStatement]->Execute(flags, state, registers);
|
||||||
}
|
}
|
||||||
catch(RuntimeError & ex)
|
catch(RuntimeError & ex)
|
||||||
{
|
{
|
||||||
terminated = true;
|
state.terminated = true;
|
||||||
std::puts("\nA fatal error occurred and execution has been halted:");
|
std::puts("\nA fatal error occurred and execution has been halted:");
|
||||||
std::printf("%s\n", ex.GetMessage().c_str());
|
std::printf("%s\n", ex.GetMessage().c_str());
|
||||||
|
|
||||||
@@ -21,21 +21,12 @@ namespace Execute
|
|||||||
}
|
}
|
||||||
|
|
||||||
state.currentStatement = state.nextStatement;
|
state.currentStatement = state.nextStatement;
|
||||||
if (state.currentStatement >= code.statements.size() || state.terminated)
|
if (state.currentStatement >= codePtr->statements.size())
|
||||||
{
|
{
|
||||||
terminated = true;
|
state.terminated = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VirtualMachine::VirtualMachine(Interpret::Code const & _code, unsigned const memorySize)
|
|
||||||
: flags(),
|
|
||||||
registers(),
|
|
||||||
state(_code.labelStatementIndice, memorySize),
|
|
||||||
terminated(false),
|
|
||||||
code(_code)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void VirtualMachine::Run()
|
void VirtualMachine::Run()
|
||||||
{
|
{
|
||||||
while(!IsTerminated())
|
while(!IsTerminated())
|
||||||
@@ -52,26 +43,29 @@ namespace Execute
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VirtualMachine::LoadConfiguration(Configuration const & c)
|
||||||
|
{
|
||||||
|
c.PrepareMemory(state.memory);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VirtualMachine::LoadCode(std::unique_ptr<Interpret::Code> code)
|
||||||
|
{
|
||||||
|
codePtr = std::move(code);
|
||||||
|
state.labelStatementIndice = &(codePtr->labelStatementIndice);
|
||||||
|
}
|
||||||
|
|
||||||
Flags const & VirtualMachine::GetFlags() const { return flags; }
|
Flags const & VirtualMachine::GetFlags() const { return flags; }
|
||||||
Registers const & VirtualMachine::GetRegisters() const { return registers; }
|
Registers const & VirtualMachine::GetRegisters() const { return registers; }
|
||||||
State const & VirtualMachine::GetState() const { return state; }
|
State const & VirtualMachine::GetState() const { return state; }
|
||||||
Interpret::Statement const * const VirtualMachine::GetCurrentStatement() const
|
Interpret::Statement const * const VirtualMachine::GetCurrentStatement() const
|
||||||
{
|
{
|
||||||
return code.statements[state.currentStatement].get();
|
return codePtr->statements[state.currentStatement].get();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VirtualMachine::IsTerminated() const { return terminated; }
|
bool VirtualMachine::IsTerminated() const { return state.terminated; }
|
||||||
|
|
||||||
VirtualMachine VirtualMachine::CreateFromCode(Interpret::Code const & code)
|
VirtualMachine::VirtualMachine()
|
||||||
{
|
{
|
||||||
unsigned memorySize = 1024;
|
state.interrupts = GetInterrupts();
|
||||||
auto const & userMemorySizeDeclared = code.declarations.find("MEMORY_SIZE");
|
|
||||||
if (userMemorySizeDeclared != code.declarations.end() && userMemorySizeDeclared->second >= 0)
|
|
||||||
{
|
|
||||||
memorySize = userMemorySizeDeclared->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::printf("Creating Wassembly virtual machine with %u bytes of memory.\n", memorySize);
|
|
||||||
return VirtualMachine(code, memorySize);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -26,8 +26,8 @@ namespace Interpret
|
|||||||
|
|
||||||
void JumpStatement::Execute(Execute::Flags & flags, Execute::State & state, Execute::Registers & registers)
|
void JumpStatement::Execute(Execute::Flags & flags, Execute::State & state, Execute::Registers & registers)
|
||||||
{
|
{
|
||||||
auto const & elem = state.labelStatementIndice.find(label);
|
auto const & elem = state.labelStatementIndice->find(label);
|
||||||
if (elem != state.labelStatementIndice.end())
|
if (elem != state.labelStatementIndice->end())
|
||||||
{
|
{
|
||||||
state.nextStatement = elem->second;
|
state.nextStatement = elem->second;
|
||||||
}
|
}
|
||||||
@@ -44,8 +44,8 @@ namespace Interpret
|
|||||||
|
|
||||||
void FunctionCallStatement::Execute(Execute::Flags & flags, Execute::State & state, Execute::Registers & registers)
|
void FunctionCallStatement::Execute(Execute::Flags & flags, Execute::State & state, Execute::Registers & registers)
|
||||||
{
|
{
|
||||||
auto const & elem = state.labelStatementIndice.find(label);
|
auto const & elem = state.labelStatementIndice->find(label);
|
||||||
if (elem == state.labelStatementIndice.end())
|
if (elem == state.labelStatementIndice->end())
|
||||||
{
|
{
|
||||||
throw Execute::MissingLabel(label);
|
throw Execute::MissingLabel(label);
|
||||||
}
|
}
|
||||||
|
|||||||
140
src/main.cpp
140
src/main.cpp
@@ -1,133 +1,5 @@
|
|||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <execute/virtualmachine.hpp>
|
#include <wassembler.hpp>
|
||||||
#include <fstream>
|
|
||||||
#include <interpret/errors.hpp>
|
|
||||||
#include <interpret/interpreter.hpp>
|
|
||||||
#include <token/errors.hpp>
|
|
||||||
#include <token/tokenizer.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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintTokens(std::vector<Token::Token> const & tokens)
|
|
||||||
{
|
|
||||||
std::puts("*** Tokenization result ***");
|
|
||||||
unsigned statementNumber = 0u;
|
|
||||||
std::printf("%02u - ", statementNumber);
|
|
||||||
for(unsigned i = 0u; i < tokens.size(); ++i)
|
|
||||||
{
|
|
||||||
auto const & token = tokens[i];
|
|
||||||
token.DebugPrint();
|
|
||||||
if (token.type == Token::TokenType::StatementEnd)
|
|
||||||
{
|
|
||||||
++statementNumber;
|
|
||||||
if (i + 1 < tokens.size())
|
|
||||||
{
|
|
||||||
std::printf("\n%02u - ", statementNumber);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::puts("");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintLabels(Interpret::Code const & code)
|
|
||||||
{
|
|
||||||
std::puts("\n*** Labels ***");
|
|
||||||
for(auto const & labelIndice : code.labelStatementIndice)
|
|
||||||
{
|
|
||||||
std::printf("Label %s points to statement %u\n", labelIndice.first.c_str(), labelIndice.second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Interpret::Code GetCodeFromFile(std::string const & filePath)
|
|
||||||
{
|
|
||||||
std::ifstream input(filePath);
|
|
||||||
if (!input.is_open())
|
|
||||||
{
|
|
||||||
std::printf("Error: Cannot open file %s for reading", filePath.c_str());
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<Token::Token> tokens;
|
|
||||||
Token::Tokenizer tokenizer;
|
|
||||||
std::vector<std::string> lines;
|
|
||||||
std::string line;
|
|
||||||
unsigned lineNumber = 0;
|
|
||||||
bool tokenizationError = false;
|
|
||||||
while(std::getline(input, line))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
tokenizer.Tokenize(line, lineNumber, tokens);
|
|
||||||
}
|
|
||||||
catch(Token::TokenizationError & err)
|
|
||||||
{
|
|
||||||
tokenizationError = true;
|
|
||||||
PrintTokenError(err, lines);
|
|
||||||
}
|
|
||||||
|
|
||||||
++lineNumber;
|
|
||||||
lines.push_back(line);
|
|
||||||
}
|
|
||||||
input.close();
|
|
||||||
|
|
||||||
// Validate the syntax
|
|
||||||
bool syntaxError = false;
|
|
||||||
for(auto const & token : tokens)
|
|
||||||
{
|
|
||||||
if (!token.isValid)
|
|
||||||
{
|
|
||||||
std::printf("Syntax error ");
|
|
||||||
PrintBadToken(token, lines);
|
|
||||||
syntaxError = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tokenizationError || syntaxError)
|
|
||||||
{
|
|
||||||
std::puts("Aborting due to syntax error(s)");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
Interpret::Interpreter interpreter;
|
|
||||||
Interpret::Code code;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
interpreter.Interpret(tokens, code);
|
|
||||||
}
|
|
||||||
catch(Interpret::InterpretationError & e)
|
|
||||||
{
|
|
||||||
PrintTokenError(e, lines);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char ** argv)
|
int main(int argc, char ** argv)
|
||||||
{
|
{
|
||||||
@@ -137,9 +9,13 @@ int main(int argc, char ** argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto const code = GetCodeFromFile(argv[1]);
|
Wassembler wassembler;
|
||||||
auto vm = Execute::VirtualMachine::CreateFromCode(code);
|
if (!wassembler.LoadFromFile(argv[1]))
|
||||||
vm.Run();
|
{
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
wassembler.Run();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -203,4 +203,28 @@ namespace Token
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PrintTokens(std::vector<Token> const & tokens)
|
||||||
|
{
|
||||||
|
std::puts("*** Tokenization result ***");
|
||||||
|
unsigned statementNumber = 0u;
|
||||||
|
std::printf("%02u - ", statementNumber);
|
||||||
|
for(unsigned i = 0u; i < tokens.size(); ++i)
|
||||||
|
{
|
||||||
|
auto const & token = tokens[i];
|
||||||
|
token.DebugPrint();
|
||||||
|
if (token.type == TokenType::StatementEnd)
|
||||||
|
{
|
||||||
|
++statementNumber;
|
||||||
|
if (i + 1 < tokens.size())
|
||||||
|
{
|
||||||
|
std::printf("\n%02u - ", statementNumber);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::puts("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
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