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