Bluish Coder

Programming Languages, Martials Arts and Computers. The Weblog of Chris Double.


2006-12-18

Continuations added to fjsc

I've added support for continuations to the Factor to Javascript compiler. The public interface is the same as the standard Factor continuation support. Namely the 'callcc0', 'callcc1', 'continue' and 'continue-with' words.

This involved quite a few changes to the internals of the compiler. The Javascript generated code is now in continuation passing style (CPS). It makes the generated code harder to understand but exposes the continuations directly. This is what the expression '1 2 + alert' gets compiled to:

factor.push_data(1,
       function() {
         factor.push_data(2,
           function() {
             factor.find_word("+").execute(
               function() {
                 factor.find_word("alert").execute(factor.cont.next)
             })
           })
         })

I do no optimisation of the code yet so its not that efficient. I can work on that later as I'm more interested in getting this working at the moment.

Javascript does not have tail call optimisation so this form of transformation will eventually overflow the call stack given a long enough word definition. To work around this I keep a count of each continuation called and when it exceeds a threshold I pass the next one to setTimeout and exit immediately.

This has the effect of jumping out of the call stack and has the side effect of occasionally giving the browser some processing, which prevents the 'this script seems to be running for a long time...' type of error.

Another change is I've moved to using the jQuery library for the Ajax and DOM manipulation support. This seems to be easier to use when doing POST requests, and has some nice DOM routines. In the bootstrap.factor file that gets run on startup by the browser I have a few simple examples of calling jQuery from Factor:

: elements ( string -- result )
  #! Call JQuery's $ function
  window { "result" } "" "$" { "string" } alien-invoke ;

: html ( string -- element ) 
  #! Set the innerHTML of element using jQuery
  { } "" "html" { "string" } alien-invoke ;

: bind-event ( name element quot -- )
  >function swap { } "" "bind" { "string" "function" } alien-invoke ;

In the main REPL page I've added a DIV with the id 'playground' for experimenting with the interface. 'example1' creates a button in this div:

: example1 ( -- )
  "<button id='test'>Press Me</button>" "#playground" elements html ;

Clicking the button does nothing though. An event handler that calls a quotation can be added with 'bind-event':

: example2 ( -- )
  "click" "#test" elements [ "clicked" alert ] bind-event ;

Clicking the button now displays the alert. Continuations can be used from event handlers:

: example3 ( -- )
  [
    [
      >r "click" "#test" elements r> [ continue ] curry bind-event
      "Waiting for click on button" alert
      continue
    ] callcc0
    drop "Click done!" alert 
  ] callcc0 ;

This example captures a continuation and curries it to the [ continue ] quotation which is bound to the event. So clicking the button will run the continuation. This continuation is the "Click Done!" part of the word. Clicking the button will display that message. And it can be clicked multiple times to resume the continuation multiple times.

Other additions to the fjsc system include:

Retain Stack
i
The retain stack has been added. >r and r> work as expected.
Vocabulary Support
Words now belong to Vocabularies. I don't have USE:, USING: or IN: yet as I don't support parsing words. Instead there is "in", "use" and "using" which work in a similar manner: "scratchpad" in { "kernel" "math" } using "foo" use
Quotations on the server compilable to Javascript
Previously you could only compile strings of Factor code to Javascript. Now you can compile quotations as well. This allows generation of Javascript without have to do any string concatenation. When compiling from a quotation, the vocabs for the words in the quotation will match the vocabs for the words that are executed in Javascript. When compiling strings, as there is no USE information, it looks up the word in the current USE list at run time. "1 2 +" fjsc-parse fjsc-compile . [ 1 2 + ] fjsc-parse fjsc-compile .

On my list to add are:

  • DOM wrappers
  • A better REPL
  • Better code generation
  • Documentation
  • Threads and Concurrency

Tags


This site is accessable over tor as hidden service mh7mkfvezts5j6yu.onion, or Freenet using key:
USK@1ORdIvjL2H1bZblJcP8hu2LjjKtVB-rVzp8mLty~5N4,8hL85otZBbq0geDsSKkBK4sKESL2SrNVecFZz9NxGVQ,AQACAAE/bluishcoder/-44/


Tags

Archives
Links