0

I've been working on a VM Translator as part of the nand2tetris course and I have spent ages trying to debug this error to no avail. I have tried catching the error but then it throws a debug assertion error: vector subscript out of range.

Here is a couple of snippets, ill try to include everywhere that it is called.


int Parser::arg2() {

    int arg2 = 0;

    try {
        if (currentCommand.find(" ") != string::npos)
            arg2 = stoi(currentCommand.substr(currentCommand.find_last_of(" "), currentCommand.length()));
        return arg2;
    }
    catch (const std::invalid_argument& ia ) {
        cerr << "Invalid argument: " << ia.what() << endl;
        return 0;
    }
    catch (const std::out_of_range & oor) {
        cerr << "Out of range: " << oor.what() << endl;
        return 0;
    }

    return 0;
} 

This is where the error is throwing, and the following is where I am calling it from:

for (const auto& entry : fs::recursive_directory_iterator(dir)) {
        ostringstream oss;
        oss << entry;
        string file = oss.str();

        if (file.find(".vm") != string::npos) {
            Parser parser(file);

            while (true) {
                parser.advance();
                if (!parser.hasMoreCommands()) break;
                if (parser.commandType() == "C_ARITHMETIC") writer.writeArithmetic(parser.command());

                if (parser.commandType() == "C_BRANCHING") writer.writeBranching(parser.command(), parser.arg1(), parser.arg2());
                if (parser.commandType() == "C_POP") writer.writePushPop("C_POP", parser.arg1(), parser.arg2());
                if (parser.commandType() == "C_PUSH") writer.writePushPop("C_PUSH", parser.arg1(), parser.arg2());
            }
        }
        else continue;  
    }

When debugging I have tried commenting out the writeBranching line and that removed the error which leads me to think that there is something wrong with the method so here is that one also:

void Writer::writeBranching(string command, string name, int numArgs) {
    cout << "HITTING:" << command << endl;
    if (command == "goto") writeGoTo(name); return;
    if (command == "if-goto") writeIf(name); return;
    if (command == "label") writeLabel(name); return;
    if (command == "call") writeCall(name, numArgs); return;
    if (command == "function") writeFunction(name, numArgs); return;
    if (command == "return") writeReturn(); return;
}

Using the debugger and stepping through was not much help, it can successfully run and parse all of these methods at least once before it crashes so i'm quite lost.

Here is the file that I am parsing:

function Main.fibonacci 0
push argument 0
push constant 2
lt                     // checks if n<2
if-goto IF_TRUE
goto IF_FALSE
label IF_TRUE          // if n<2, return n
push argument 0        
return
label IF_FALSE         // if n>=2, returns fib(n-2)+fib(n-1)
push argument 0
push constant 2
sub
call Main.fibonacci 1  // computes fib(n-2)
push argument 0
push constant 1
sub
call Main.fibonacci 1  // computes fib(n-1)
add                    // returns fib(n-1) + fib(n-2)
return

And finally the output of the first parse over (I am lead to beleive it is crashing before the translation stage):

function Main.fibonacci 0
push argument 0
ARG 0
push constant 2
constant 2
lt
if-goto IF_TRUE
Invalid argument: invalid stoi argument
goto IF_FALSE
Invalid argument: invalid stoi argument
label IF_TRUE
Invalid argument: invalid stoi argument
push argument 0
Invalid argument: invalid stoi argument
ARG 0
return
cillsley
  • 37
  • 8
  • 1
    Can't even tell where the `vector` is, but I can tell you `if (command == "goto") writeGoTo(name); return;` is wrong. The return will always be reached. This is a good place for `else if` and allowing the function to exit on its own when it reaches the end. – user4581301 Dec 12 '19 at 17:00
  • 1
    `vector subscript out of range` suggests that you are using operator `[]` on something and the index (subscript) provided is out of range. Try to find all of the uses of `[` and change them to `.at()` method and you will get a nice and debuggable exception instead. – Yksisarvinen Dec 12 '19 at 17:01
  • 1
    `vector subscript out of range` sounds like this is being run using Visual C++ in debug mode. Thus the debugger should say exactly what is causing this, by simply looking at the call stack to see where the vector is being accessed. – PaulMcKenzie Dec 12 '19 at 17:05
  • Side note: since the function is very regular you could make a `std::map commands` that maps `"goto"` to `writeGoTo` and then replace calls to `writeBranching` with `commands[command](name, numArgs);` or similar. – user4581301 Dec 12 '19 at 17:07
  • It breaks at line 1450 in vector.h, not throwing inside of the file itself anymore. It was pointing at where it says arg2 = stoi... before. – cillsley Dec 12 '19 at 17:09
  • @cillsley Look at the call stack, don't look at the actual runtime code. See which function *your* program is calling to create the error. – PaulMcKenzie Dec 12 '19 at 19:33

0 Answers0