Friday, August 31, 2007

Erlang Facebook API

While looking for online resources about Erlang / Facebook, I found out that Brian Fink has released his Erlang Implementation of the Facebook API as open source project at googlecode. Great.

Erlang JS compiler - dealing with objects

I did some more work on the Erlang based Javascript compiler proof-of-concept. Also set up a googlecode project named 'jserl', but not yet uploaded any code.
Javascript has some functional aspects, but is also object oriented. I have used message passing for modeling objects. For every object definition in Javascript a message loop gets injected into the generated Erlang code. And I also started to implement some native functions as provided by the Javascript Interpreter. So let's take a look at an example to see what currently works and how the generated Erlang code looks like:

Javascript code:

var argument_test = function (a) {
var b = a + 1;
return b;
};

var object_test = function (arg) {
var obj = { property: 'text' };
var test2 = obj.property;
return test2;
};

var native_functions_test = function (arg) {
return arg.length;
};

Compiled to a beam file this gives the following (expected and correct) results:

Eshell V5.5.5 (abort with ^G)
1> footest:argument_test(5).
6
2> footest:object_test(no_arg_dummy).
"text"
3> footest:native_functions_test("text").
4
4>

And here is how the Erlang source code (generated with erl_prettypr:format/1 from the abstract syntax tree) looks like:

-module(footest).
-compile(export_all).
argument_test(A) -> B = A + 1, B.
object_test(Arg) ->
Obj = obj_new("text"),
Test2 = case Obj of
Int when is_integer(Int) -> "not defiend (yet ?)";
Float when is_float(Float) -> "not defiend (yet ?)";
List when is_list(List) ->
case jserl:is_string(List) of
true -> "not defiend (yet ?)";
'_' -> "not defiend (yet ?)"
end;
Pid when is_pid(Pid) ->
jserl:rpc(Pid, {get, 'Property'});
'_' -> "not defiend (yet ?)"
end,
Test2.
native_functions_test(Arg) ->
case Arg of
Int when is_integer(Int) -> "not defiend (yet ?)";
Float when is_float(Float) -> "not defiend (yet ?)";
List when is_list(List) ->
case jserl:is_string(List) of
true -> length(Arg);
'_' -> "not defiend (yet ?)"
end;
Pid when is_pid(Pid) -> jserl:rpc(Pid, {get, 'Length'});
'_' -> "not defiend (yet ?)"
end.
obj(Property) ->
receive
{From, {get, 'Property'}} ->
From ! {self(), Property}, obj(Property);
{From, {set, 'Property', Val}} ->
From ! {self(), ok}, obj(Property);
{From, _Other} ->
From ! {self(), {err, no_such_member}}, obj(Property)
end.
obj_new(Property) -> spawn(fun () -> obj(Property) end).

Of course there is a lot of stuff missing, so it is currently more a pseudo script than an ECMA compliant Javascript compiler.