NestedCall Test Fail

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

NestedCall Test Fail

charlie101010
I have been able to pass the SimpleFunction test and have been trying to debug my code for hours.

Any advice is welcome.

Here is my call, function and return assembly code snippets.  While debugging, it appeared that I am not correctly returning the "return value"...but I cant figure out the issue.

Function:

"("  + fileName + "." + className + "." + functName +")"

Call:

"@"+ fileName + "." + self.currentClass + "$ret" + str(self.retcount),
                        'D=A',
                        '@SP',
                        'A=M',
                        'M=D',
                        '@SP',
                        'M=M+1',
                        '@LCL',
                        'D=M',
                        '@SP',
                        'A=M',
                        'M=D',
                        '@SP',
                        'M=M+1',
                        '@ARG',
                        'D=M',
                        '@SP',
                        'A=M',
                        'M=D',
                        '@SP',
                        'M=M+1',
                        '@THIS',
                        'D=M',
                        '@SP',
                        'A=M',
                        'M=D',
                        '@SP',
                        'M=M+1',
                        '@THAT',
                        'D=M',
                        '@SP',
                        'A=M',
                        'M=D',
                        '@SP',
                        'M=M+1',
                        '@5',
                        'D=A',
                        '@SP',
                        'D=M-D',
                        '@' + nArgs,
                        'D=D-A',
                        '@ARG',
                        'M=D',
                        '@SP',
                        'D=M',
                        '@LCL',
                        'M=D',
                        '@' + fileName + "." + className + '.' + functName,
                        '0; JMP',
                        '(' + fileName + "." + self.currentClass + "$ret" + str(self.retcount) + ')',

Return:

"@LCL",
                "D=M",
                "@endFrame",
                "M=D",
                "@5",
                "D=A",
                "@endFrame",
                "D=M-D",
                "@retAddr",
                "M=D",
                "@SP",
                "M=M-1",
                "A=M",
                "D=M",
                "@ARG",
                "A=M",
                "M=D",
                "@ARG",
                "D=M",
                "@SP",
                "M=D+1",
                "@endFrame",
                "A=M-1",
                "D=M",
                "@THAT",
                "M=D",
                "@2",
                "D=A",
                "@endFrame",
                "A=M-D",
                "D=M",
                "@THIS",
                "M=D",
                "@3",
                "D=A",
                "@endFrame",
                "A=M-D",
                "D=M",
                "@ARG",
                "M=D",
                "@4",
                "D=A",
                "@endFrame",
                "A=M-D",
                "D=M",
                "@LCL",
                "M=D",
                "@retAddr",
                "A=M",
                "0; JMP"
                ]
Reply | Threaded
Open this post in threaded view
|

Re: NestedCall Test Fail

cadet1620
Administrator
First things I see:

Functions need to be called from different classes so the labels used for function names in the ASM must not be modified with file or class names. Write them exactly as they appear in the VM code.

writeFunction() is not initializing the local segment to 0.

Ideas that help debugging:

Add the call/return pseudocode as comments in the long lists of ASM commands.
ret_asm = (
    "@LCL",         # FRAME = LCL
    "D=M",
    "@endFrame",
    "M=D",

    "@5",           # RET = *(FRAME-5)
    "D=A",
Add the VM code as comments in the generated ASM code:
    A=A-1
    M=0
// call Output.create 12
    @$RIP$195
    D=A
    @R13
    M=D
    @Output.create
    D=A
    @R14
    M=D
    @12
    D=A
    @$CALL$
    0;JMP
($RIP$195)
// pop temp 0
    @SP
    AM=M-1
My translator only writes these comments if it is run with  a '-d' option, but it is OK to always write them.

--Mark
Reply | Threaded
Open this post in threaded view
|

Re: NestedCall Test Fail

charlie101010
Thanks for the debugging tip.  I will add comments for each step...that sounds really helpful.

I have initialized the local segments to zero now (kind of ugly code at the moment...but it works).

As for the label and call naming convention, I was a bit confused by that from the videos.



I tried following the description from that slide, so I ended up with syntax like:

(Sys.Sys.main)
@Sys.Sys$ret0

where it is fileName.className.functionName and fileName.ClassName$ret + incrementing value


Is that incorrect?  What would be the correct syntax for the Sys.main function in the Sys.vm file?  An example would be really helpful.

I appreciate the help!

Charlie
Reply | Threaded
Open this post in threaded view
|

Re: NestedCall Test Fail

cadet1620
Administrator
The VM translator does not deal with class names. The file name is added to some, but not all, symbols as in that table.

It's an evil plot meant to lead you astray that the function names in VM files look like they have class names. 8^)

Actually, they all have class names because they come from the Jack compiler, which is class based. To the VM translator, '.' is just another character that is legal in a functionName.

Given the commands
    "function Main.main 0" in file Main.vm
    "call Main.main 0" in file Sys.vm

The functionName is "Main.main" from the VM translator's perspective, so the ASM for the function's entry point will be
    (Main.main)

The call will end with
    @Main.main
    0;JMP
(or code to that effect)

This is so that functions in different VM files can call each other.

--Mark