Basic arithmetic and jump labels
This commit is contained in:
133
src/main.cpp
Normal file
133
src/main.cpp
Normal file
@@ -0,0 +1,133 @@
|
||||
#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;
|
||||
}
|
||||
Reference in New Issue
Block a user