#include #include #include #include #include #include void PrintBadToken(Token::Token const & token, std::vector 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 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 tokens; Token::Tokenizer tokenizer; std::vector 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; }