Function name doesn't match class name: Main.main

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Function name doesn't match class name: Main.main

fishboy1887
I am getting this error but cannot find any information on it in either TECS edition 2 or this forum. If I were to guess, the error is stemming from the way I am handling subroutines and do statements.

My compileDo method:
void CompilationEngine::compileDo() {
    tokenizer.advance();  // 'do'
   
    // Handle the subroutine call directly
    std::string identifier = tokenizer.identifier();
    tokenizer.advance();

    std::string subroutineName;
    int nArgs = 0;

    if (tokenizer.getCurrentToken() == ".") {
        tokenizer.advance();
        std::string methodName = tokenizer.identifier();
        tokenizer.advance(); // Advance past method name

        auto [kind, index] = getVariableInfo(identifier);
        if (kind != "none") {
            // Method call on another object
            vmWriter.writePush(kind, index);
            subroutineName = symbolTableClass.typeOf(identifier) + "." + methodName;
            nArgs = compileExpressionList() + 1;
        } else {
            // Function call
            subroutineName = identifier + "." + methodName;
            nArgs = compileExpressionList() + 1;
        }
    } else {
        // Method call on the current object
        subroutineName = currentClass + "." + identifier;
        vmWriter.writePush("pointer", 0);
        nArgs = compileExpressionList() + 1;
    }

    tokenizer.advance();  // Advance past the closing parenthesis ')'
    vmWriter.writeCall(subroutineName, nArgs);
    tokenizer.advance();  // Advance past ';'
    vmWriter.writePop("temp", 0);  // Discard the return value of the call
    // vmWriter.writeReturn(); <-- I am unsure of whether to include this or not
}

The section to handle identifiers inside of CompileExpression.compileTerm:
case JackTokenizer::TokenElements::IDENTIFIER: {
            std::string curIdentifier = tokenizer.identifier();
            tokenizer.advance();
            if (tokenizer.getCurrentToken() == "[") {
                // varName '[' expression ']'
                auto [kind, index] = getVariableInfo(curIdentifier);
                vmWriter.writePush(kind, index, "// compileTerm, line 441: " + curIdentifier);
                tokenizer.advance();  // Advance past '['
                compileExpression();
                tokenizer.advance();  // Advance past ']'
                vmWriter.writeArithmetic("add");
                vmWriter.writePop("pointer", 1);
                vmWriter.writePush("that", 0);
            } else if (tokenizer.getCurrentToken() == "(" || tokenizer.getCurrentToken() == ".") {
                // Handle subroutine call directly within compileTerm
                std::string subroutineName;
                int nArgs = 0;

                if (tokenizer.getCurrentToken() == ".") {
                    tokenizer.advance();
                    std::string methodName = tokenizer.identifier();
                    tokenizer.advance(); // Advance past method name

                    auto [kind, index] = getVariableInfo(curIdentifier);
                    if (kind != "none") {
                        // Method call on another object
                        vmWriter.writePush(kind, index);
                        subroutineName = symbolTableSubroutine.typeOf(curIdentifier) + "." + methodName;
                        nArgs = compileExpressionList() + 1;
                    } else {
                        // Function call
                        subroutineName = curIdentifier + "." + methodName;
                        nArgs = compileExpressionList();
                    }
                } else {
                    // Method call on the current object
                    subroutineName = currentClass + "." + curIdentifier;
                    vmWriter.writePush("pointer", 0);
                    nArgs = compileExpressionList() + 1;
                }

                tokenizer.advance();  // Advance past the closing parenthesis ')'
                vmWriter.writeCall(subroutineName, nArgs);
            } else {
                // Attribute access
                auto [kind, index] = getVariableInfo(curIdentifier);
                if (kind != "none") {
                    vmWriter.writePush(kind, index, "// compileTerm, line 490: " + curIdentifier);
                }
            }
            break;

I understand this code is a nightmare to look at, so here is the repo to see the full thing: https://github.com/blacknand/nand2tetris/tree/compiler_II/10_jack_compiler/Compiler

If anyone thinks it is better to start from scratch then I will, I feel like I am missing something crucial because it just does not click for me.
Reply | Threaded
Open this post in threaded view
|

Re: Function name doesn't match class name: Main.main

pm100
If I recall this is due to the fact that the file name is incorrect, Main.main has to be in a file called Main.vm. And note that its case sensitive, even on windows.
Reply | Threaded
Open this post in threaded view
|

Re: Function name doesn't match class name: Main.main

fishboy1887
Yeah that was the issue. Thanks
Reply | Threaded
Open this post in threaded view
|

Re: Function name doesn't match class name: Main.main

pm100
FYI, std::location::line will give you the current line number in the c++ source file rather than hard coding like you have when generating comments
Reply | Threaded
Open this post in threaded view
|

Re: Function name doesn't match class name: Main.main

fishboy1887
Thanks for the tip but I am using C++17 and std::source_location was introduced in C++20.