Files
wassembly/src/main.cpp

133 lines
2.9 KiB
C++

#include <cstdio>
#include <execute/virtualmachine.hpp>
#include <fstream>
#include <interpret/errors.hpp>
#include <interpret/interpreter.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::TokenError const & err, std::vector<std::string> const & lines)
{
std::printf("%s ", err.errorMsg.c_str());
PrintBadToken(err.errorToken, lines);
}
int main(int argc, char ** argv)
{
if (argc != 2)
{
std::puts("Usage: wassembly [filename.wasm]");
return 1;
}
std::ifstream input(argv[1]);
if (!input.is_open())
{
std::printf("Error: Cannot open file %s for reading", argv[1]);
return 1;
}
std::vector<Token::Token> tokens;
Token::Tokenizer tokenizer;
std::vector<std::string> lines; // DEBUG
std::string line;
unsigned lineNumber = 0;
while(std::getline(input, line))
{
tokenizer.Tokenize(line, lineNumber, tokens);
++lineNumber;
lines.push_back(line); // DEBUG
}
input.close();
// DEBUG
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("");
}
}
}
// END DEBUG
// Validate the syntax
bool syntaxOk = true;
for(auto const & token : tokens)
{
if (!token.isValid)
{
std::printf("Syntax error ");
PrintBadToken(token, lines);
syntaxOk = false;
}
}
if (!syntaxOk)
{
std::puts("Aborting due to syntax error(s)");
return 1;
}
Interpret::Interpreter interpreter;
Interpret::Code code;
try
{
interpreter.Interpret(tokens, code);
}
catch(Interpret::TokenError & e)
{
PrintTokenError(e, lines);
return 1;
}
// DEBUG
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);
}
std::puts("\n*** Execution ***");
Execute::VirtualMachine vm(code);
for(unsigned i = 0u; i < 900000; ++i)
{
vm.SingleStep();
auto const & registers = vm.GetRegisters();
std::printf("A=%i B=%i C=%i D=%i\n", registers.A, registers.B, registers.C, registers.D);
auto const & flags = vm.GetFlags();
std::printf("-\n"); // TODO
auto const & state = vm.GetState();
std::printf("current_statement=%i\n", state.currentStatement);
std::puts("Press any key to step...");
std::getchar();
}
// END DEBUG
return 0;
}