3 ms·
an important limitation of javascript means this will never quite be a complete implementation: Continuations are not implemented. I had started on a CPS-based
by staticshock 19y ago
an important limitation of javascript means this will never quite be a complete implementation:
Continuations are not implemented. I had started on a CPS-based interpreter, but then realized that JavaScript lacks tail-call optimization and has a recursion limit of 1000 calls, which'll make any CPS-transformation blow the stack.
looks like a good piece of code otherwise, though.
- tlrobinson 19y agoThis guy implemented a continuation-based syntax highlighter in JavaScript: http://marijn.haverbeke.nl/codemirror/story.html http://marijn.haverbeke.nl/codemirror/story.html I'm not sure how relevant it is to implementing Arc, but never say never. JavaScript is Turing complete, after all...
- nostrademons 19y agoThat approach could work. He's storing the current continuation as a global variable, which I never thought of, because typically you want your interpreters to be self-contained. (I was also working off Guy Steele's toy CPS interpreter, which passes cont in and then ends each function with a tailcall to another function or the invocation of the continuation.) But I can't see any real reason why the global won't work; it'll get stored in a data structure when the continuation is captured, and since stack frames are normal JavaScript objects in ArcLite, the garbage collector will hold on to them. It'll mean that any loop that may call back into the interpreter has to be rewritten as a tail-recursive function though, with the tail call being saved into the global continuation variable. Could be quite a bit of overhead.
- tlrobinson 19y agoI believe you can use the "with" operator in JavaScript to use any object as the global object (normally "window" in the browser). I'm not sure how useful that could be, but it might help make it self contained.
- nostrademons 19y ago"with" is dangerous, because it makes it impossible to tell lexically whether you're assigning to an object or to a global variable. If you mistype a variable or pass an object of the wrong type in to "with", you can find yourself with very difficult-to-track-down bugs. In practice I'd only use it with a bunch of assertions, which could bloat the code significantly. Chris Double suggested another alternative over on Proggit: tailcall to window.setTimeout with a delay of 0. This is effectively a trampoline; the continuation gets pushed onto a timer, the eval function returns, then JavaScript picks up again where it should. As a nice side effect, it gives the browser's event loop a chance to run, which eliminates any chance of locking up the machine. Pretty elegant solution, though I'm guessing there's a significant performance penalty.
- marijn 19y agoThat is not a global variable, it is a closed-over variable, which, in terms of self-containedness, is a whole different beast. See also http://marijn.haverbeke.nl/cps/ http://marijn.haverbeke.nl/cps/ .
- marijn 19y agoYou can fake tail calls with window.setTimeout(continuation, 0)