It's not easy. We can't make it into a primitive, because CPS conversion assumes that primitives will never need access to continuations, and thus does not transform primitive calls to CPS form.
- call the APPLY() function, which just POPs the two elements, PUSHes all the elements of the arg list one after one, then call the closure (maybe after changing the continuation argument of that closure by hand, at runtime) ?
That's a runtime behavior, for sure, and probably a few cases should be hard-coded in the generated C file. E.g., (apply + '(1 2)) should be translated to (+ 1 2), then to 3, if nothing bad (redefinition of '+ or 'apply by the user) happened. But in the general case, you can't know.
Anyway, we will eventually have to implement an interpreter in the generated code, to deal with dynamic stuff. Maybe closures should be made available through a hashtable mapping their name(s) to actual code, and not only through a hard-coded array as it is now ?
> - call the APPLY() function, which just POPs the two elements, PUSHes all the elements of the arg list one after one, then call the closure (maybe after changing the continuation argument of that closure by hand, at runtime) ?
Which continuation argument do you pass?
Suppose it's like this:
(%car (%apply foo bar))
Then foo is:
(set foo
(fn (a b)
(ccc
(fn (k)
(a k b)))))
Question: How does '%apply get access to the continuation, in order to pass to 'foo, which passes it to 'ccc ?
Remember, calling a function consists of the following steps:
1. Push the closure
2. Push the continuation
3. Push the arguments
The problem is step 2: continuation.
Possibly we need to insert the default 'apply during the same step as inserting the default 'ccc ? Then we could define '%apply as accepting the function, the continuation, and a plain list of arguments.
> Anyway, we will eventually have to implement an interpreter in the generated code, to deal with dynamic stuff. Maybe closures should be made available through a hashtable mapping their name(s) to actual code, and not only through a hard-coded array as it is now ?
s/closure/global variable/, maybe?
I think what we could do is, we add a pointer to an obj in the symbol structure. If the symbol is in the GLOBAL() array, this pointer points to that entry, otherwise to a malloc()'ed location.