Distinguishing method call from subroutine call in a method

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

Distinguishing method call from subroutine call in a method

phayter
When compiling the body of a method I don’t see how to distinguish a call to another method of the class from a subroutine call, specifically the push of THIS in one case but not the other. Example:

class MyClass {
    field int x, y;
    constructor MyClass new(int Ax) {
        x = Ax;
        y = doubleX(); // forward reference to method pushing THIS
        x = tripleX(x); // forward reference to subroutine without THIS
    }
    Method int doubleX() {
        x = 2 * x;
        return x;
    }
    Function int tripleX(x) {
        return 3 * x;
    }
}

In the case of the y assignment the compiler needs to distinguish this is a method call (and push THIS) and in the case of the second x assignment to distinguish as a subroutine call and not push THIS. Both the doubleX and tripleX calls appear legitimate per the grammar and/or sample code. I could not find a discussion of this situation in Edition 2.

Is there something I am misinterpreting or missing?
Reply | Threaded
Open this post in threaded view
|

Re: Distinguishing method call from subroutine call in a method

ashort
been a while since I've taken this class, but if I remember right, a function call must have a class name before it.  Consider these examples for a class named 'Foo':

class Foo {
        …
        method void f() {

                var Bar b; //declares a local var of class type Bar
                var int i; //declares local var of primitive type int
                …

                do g(); //calls method g of the current class on this object
                do Foo.p(3); //calls function p of the current class
                do Bar.h(); //calls function h of class Bar
                let b = Bar.r(); //calls function or constructor r of class Bar
                do b.q(); //calls method q of class Bar on the b object
                let i = w(b.s(), Foo.t()); //calls method w on this object. the args are
                                                                        //the results of calling method s on object b,
                                                                        //and function or constructor t of class Foo
        …
        }
}
Reply | Threaded
Open this post in threaded view
|

Re: Distinguishing method call from subroutine call in a method

phayter
Thanks for the quick response!

Attached is an annotated snapshot of the Jack grammar (edition 2, but that should not make a difference). Expressions are used by the do and let statements. In Expressions, the subroutineCall is defined as either subroutineName(expList) or className|varName.subroutineName(expList)

By my reading, the pre-pending of either className or varName to subroutineName is not required. So this leads me to the question of the identify of a subroutineName without a className or a varName -- is it a method or is it a function (with the method requiring a THIS argument)?

Jack Grammar - Subroutine detail
Reply | Threaded
Open this post in threaded view
|

Re: Distinguishing method call from subroutine call in a method

ashort
With no class name or var name, it’s a method, not a function.
Reply | Threaded
Open this post in threaded view
|

Re: Distinguishing method call from subroutine call in a method

ashort
In the 2nd edition of the book, this is explained on page 184 (chapter 9). It explains exactly the difference between a function/constructor call and a method call.
Reply | Threaded
Open this post in threaded view
|

Re: Distinguishing method call from subroutine call in a method

phayter
Thanks for the page reference in Edition 2.

It appears there is discrepancy / nuance between the formal grammar of figure 10.5 and the text on page 184. Unless I am misinterpreting figure 10.5; nonetheless I appreciate the written explanation.

I also just realized as your note came in that it is possible to distinguish between a function and a method not by parsing, but by the subroutine symbol table. A method will have an entry for THIS as ARG 0 and a function will not.

Thanks again!
Reply | Threaded
Open this post in threaded view
|

Re: Distinguishing method call from subroutine call in a method

WBahn
Administrator
This post was updated on .
In reply to this post by phayter
One thing to keep in mind is that the compiler has to make it's decisions based on the context of each file independent of other files, since the order of compilation is not defined.

Hence, a "bare" subroutine call (one that is not dereferenced using a period before it) is interpreted as a method of the current class.

If you have identifier.subroutine, then the compiler looks in its symbol table to see if there is a variable associated with that identifier. If it finds it, then it assumes that the subroutine is a method of the class associated with the identifier and calls that method, passing that variables memory address as the first argument. If no variable is associated with that identifier, then the identifier is assumed to be the name of a class and the subroutine is a function in that class.

EDIT: Bare subroutine calls are interpreted as method calls, not functions as I had originally wrote. Thanks to ashort for pointing out my error.
Reply | Threaded
Open this post in threaded view
|

Re: Distinguishing method call from subroutine call in a method

ashort
You wrote “ is interpreted as a function of the current class”

I believe you meant to say “method” not function, if we want to be crystal clear about function versus method.   Seems you used “function” loosely, like the word “subroutine”
Reply | Threaded
Open this post in threaded view
|

Re: Distinguishing method call from subroutine call in a method

phayter
Yes, thanks for clarifying my terminology
Reply | Threaded
Open this post in threaded view
|

Re: Distinguishing method call from subroutine call in a method

WBahn
Administrator
In reply to this post by ashort
Yes, you are correct. It's been several years since I looked at the details of Jack, specifically, in depth and I was thinking in terms of a more generic case that is overridden by the Jack spec.

I'll go back and correct my post so that it doesn't cause confusion in the future.