User loginNavigation |
Compiling Factor to JavascriptI've written a compiler for a subset of the Factor programing language targeting Javascript as the compiled language. The blogposts describing the compiler and its implementation are here: The actual working example is at: http://factor.bluishcoder.co.nz/responder/fjsc/ The compiler itself is written in Factor and runs on the server. In the example I take the users input, send it to the server via Ajax and eval the result when it comes back. The compiled javascript returned is displayed in a textarea for testing. I basically started it as a test project for my post on Compilers and Interpreters in Factor but it was a bit big for that. I shelved it for a while and decided to finish it while I'm not in paid employment. The main difference from 'real' Factor is that I don't support parsing words and I've not implemented much of the standard library. What parsing word functionality I wanted to support I built into the parser itself. The parser is written using Parser Combinators and produces an abstract syntax tree. I then compile this into Javascript. There is a parser to convert from a string of Factor code to the AST as well as from already parsed Factor quotations from the server Factor instance. This allows writing code on the server in Factor, and converting it to Javascript without having to do any string generation of Factor or Javascript code manually. I wanted to support continuations so I ended up generating the Javascript in continuation passing style. It results in ugly code but makes it easy to do callcc. An example of generated code (from '1 2 + alert'): factor.push_data(1, function() { factor.push_data(2, function() { factor.find_word("+").execute( function() { factor.find_word("alert").execute(factor.cont.next) }) }) }) The main problem with this approach is it will blow the browsers call stack pretty quickly. I use a workaround for this by counting the number of times I call the next continuation. When it reaches a certain threshold I pass it to setTimeout instead of calling it. This effectively jumps out of the call stack and starts it again. It also has the side benefit of releasing processor cycles to the browser and avoiding 'time consuming script' messages. I came across this approach in this LtU article. Apart from this I don't do any other optimisations yet. The continuations are multi-shot and can be attached to event handlers. For example, the following attaches a normal quotation to the onclick event handler of a button with id 'test': "click" "#test" elements [ "clicked" alert ] bind-event ; Or a continuation: [ [ >r "click" "#test" elements r> [ continue ] curry bind-event "Waiting for click on button" alert continue ] callcc0 drop "Click done!" alert ] callcc0 Factor has Erlang style concurrency (processes as lightweight threads and message passing) and I plan to port that library to the javascript version. I have a comet library that allows sending messages to and from the browser to Factor processes - I think it'd be pretty neat to be able to write processes on the browser in Factor that communicate to processes on the server in Factor. I hope this is interesting enough to post here - I usually don't write about stuff I wrote myself but I thought it would be interesting as other compiler->javascript projects have been discussed. At the very least it might prove useful as a playground for those who want to try out a concatenative language like Factor or Joy. By doublec at 2006-12-17 12:58 | LtU Forum | previous forum topic | next forum topic | other blogs | 7100 reads
|
Browse archives
Active forum topics |
Recent comments
27 weeks 2 days ago
27 weeks 2 days ago
27 weeks 2 days ago
49 weeks 3 days ago
1 year 1 week ago
1 year 3 weeks ago
1 year 3 weeks ago
1 year 5 weeks ago
1 year 10 weeks ago
1 year 10 weeks ago