- Literals
- Global / local variable handling
- Operators (except of dot operator, for objects)
- Functions
- Built-in global functions
I am not targeting the Erlang VM directly (beside of the Erlang compiler source code, there doesen't exist any formal specification or at least documentation about the Erlang VM internals in general and specifically the VM opcodes). What I do is transforming the Javascript source code AST to an Erlang AST. This involves a lot of trickery, because Erlang doesn't allow variable re-assignments (this is good and also necessary in the context of Erlang concurrency), but most Javascript code is just a bunch of variable re-assignments, so I have to model it somehow and I have choosen to model it differently for global Javascript variables (Erlang process dictionary) and local variables (normal Erlang variables). One interesting thing about having an Erlang AST of Javascript source code is the possibility of pretty-printing Erlang source code. Let's take a look at a Javascript example from the test cases:
function test() {
var a=0, b="Bananas";
switch (b) {
case "Oranges":
a = 1;
break;
case "Apples":
a = 2;
break;
case "Papayas":
case "Bananas":
a = 2.5;
a = 3;
break;
default:
a = 4;
}
return a;
}
If I pretty print the AST (just before compiling it, and this is even done automatically at verbose ErlyJS compiling settings) I get the following Erlang source code:
js_test() ->This kind of source code translation is extremely useful while developing and debugging the ErlyJS compiler and analyzing test cases.
V78 = 0,
V80 = "Bananas",
{V152} = case V80 of
"Oranges" -> V170 = 1, {V170};
"Apples" -> V88 = 2, {V88};
X when X == "Papayas"; X == "Bananas" ->
V270 = 2.5, V288 = 3, {V288};
_ -> V32 = 4, {V32}
end,
V152.
7 comments:
How can you transfer code from a imperative language to a functional one, aren't you going to lose a lot of the benefits of erlang if you have to have all this state?
Matthew, you are loosing the benefits of Erlang the language, if the alternative would be to code directly in Erlang. But ErlyJS is for scenarios where Erlang the language is not a viable option for client applications, but the server is written in Erlang.
I have to say you have some rather interesting Erlang projects. I'm curious of why you chose to compile to erlang instead of using an external js interpreter via like a C bridge?
A C bridge is a portability and maintenance nightmare (ask CouchDB guys), and worst, it is drastically limiting scalability. Let's take a Comet Server for example. Every process represents a client connection and owns the socket, and I want to run the client app within that process.
Btw., I had a C-bridge to spidermonkey, just for parsing the Javascript sourcecode, but it was more trouble than benefit and I didn't like the way the AST was represented and I spent just too much time maintaining that C code, so I wrote my own parser in Erlang.
Awesome. It would make testing generated javascript much easier if one were to develop an Erlang-based web framework which does JS code generation...
How do you map mutable data structure (like array, hash table) to Erlang? Using ETS or process dictionary? But both of them are not garbage collected.
Hello,
What about this project ? I am currently working on a Javascript obfuscator written ir Erlang, and your Javascript parser should be interesting to understand.
Thank you
Post a Comment