Any thoughts on how to add support for passing subroutines as arguments?

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

Any thoughts on how to add support for passing subroutines as arguments?

tungsten
Anyone have thoughts/ideas on how to add support for passing subroutines as arguments?

I'm not familiar with Java, but this is a standard feature in languages like Python and JavaScript.


class Main {

        method void main () {

                do testPassing( Output.printString );
        }

        method void testPassing( void f ) {

                do f ( "hello!" );
        }
}
Reply | Threaded
Open this post in threaded view
|

Re: Any thoughts on how to add support for passing subroutines as arguments?

cadet1620
Administrator
tungsten wrote
Anyone have thoughts/ideas on how to add support for passing subroutines as arguments?
Have you completed your compiler? This may not make much sense if you haven't done project 11 yet.

I think this could be added in a slightly kludgy manner without too much work.

Current Jack syntax:
expression:     term (op term)*

term:           integerConstant | stringConstant | keywordConstant | varName |
                varName '[' expression ']' | subroutineCall | 
                '(' expression ')' | unaryOp term
                
subroutineCall: subroutineName '(' expressionList ')' | 
                ( className | varName) '.' subroutineName '(' expressionList ')'
Although not required because Jack is an untyped language, there should be a new built-in type for function pointers. I think "pointer" would work as it implies a generic pointer (void* in C).  That will work for variables and parameters:
function void foo(pointer f) {
    var pointer fun;
There needs to be a way to assign a function address to a pointer that is unambiguous. Adding
term:           ... | subroutineAddr

subroutineAddr: className.subroutineName
will allow a bare Class.function to be used in all expressions so the address can be used in "let", "do" and function calls in expressions. It is a bit of a kludge since it syntactically allows pointer arithmetic.
let p = SomeClass.aFunction;
do f(SomeClass.aFunction);
The differentiation between a call in an expression and function address can be made when parsing subroutineCall and the '(' is not found.


There are currently 4 ways to call functions:
var Class c;
do Class.ctor();
do meth();         // this.meth()
do c.meth();
do Class.fun();
Syntactically, all of these will need to accept a variable name where they currently accept the function name.  If the parser encounters a variable instead of an undefined symbol, use the variables value instead of the function's name. (This is another kludge since the "c." or "Class." is required to determine what type of function/method is being called by the pointer, but otherwise is ignored.)

Tougher, but nice for table driven code, would be to allow indexed function pointers in the calls.
var Array handlers;
var int state;
do handlers[state]();

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

Re: Any thoughts on how to add support for passing subroutines as arguments?

tungsten
Hmm, I see. I can follow a fair bit of it, but I'll have to revisit your post a couple more times to fully understand what you've shared =)

I've finished the Jack to VM compiler. I'm in the process of extending it to support a couple of basic features I like that other programming languages have.
Reply | Threaded
Open this post in threaded view
|

Re: Any thoughts on how to add support for passing subroutines as arguments?

cadet1620
Administrator
I've added break and continue for while loops and removed the requirement for {} around single statement if/else/while clauses.  (Single statement while loop it not too useful in Jack ^8)

I've also added constants to make it easier to define structures like memory heap block headers. Syntax for those is:
const <name> '=' <integer> ';'

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

Re: Any thoughts on how to add support for passing subroutines as arguments?

tungsten
So far I've added for loops and compound assignments (+=, -= etc). I'll check out your earlier posts (especially on named constants) to see if I can also add support for those too.