1
votes

Hello awesome community!

I've started learning erlang recently. (It's quite mind bending) :)

I can't seem to find an answer anywhere.... but as a way to learn, I'm trying to create a mini shell in my web browser.

For example, I want to enter some actual erlang code into a text box, press enter and return what ever the result is and display it on the web page.

> Awesome = 41 + 41.
> io:format("Awesome = ~p", Awesome).
> 82

I've set up a simple erlang server on my localhost on port 8891 and can easily connect to it. Is it possible to send it erlang code to run and output the response?

Any help would be appreciated! :)

1

1 Answers

3
votes

This can be achieved using erl_scan, erl_parse, erl_eval as mentioned in this link. The problem is for Variable bindings. Need to know the variable bindings when it is used in an expression (more difficult when it is inside a fun)

1> Expr="Awesome = 41 + 41.".
"Awesome = 41 + 41."
2> {ok, Tokens, _} = erl_scan:string(Expr).
{ok,[{var,1,'Awesome'},
     {'=',1},
     {integer,1,41},
     {'+',1},
     {integer,1,41},
     {dot,1}],
    1}
3> {ok, [Form]} = erl_parse:parse_exprs(Tokens).
{ok,[{match,1,
            {var,1,'Awesome'},
            {op,1,'+',{integer,1,41},{integer,1,41}}}]}
4> {value, Value, Binding} = erl_eval:expr(Form, []).
{value,82,[{'Awesome',82}]}

When the user enters Awesome = 41 + 41. in the browser you can send back the response as 82.

You also need to maintain the state of the Expression. That is the Binding should be maintained can be used as follows

5> FunStr ="io:format(\"Awesome = ~p\", [Awesome]).".
"io:format(\"Awesome = ~p\", [Awesome])."
6> {ok, Tokens1, _} = erl_scan:string(FunStr).
{ok,[{atom,1,io},
     {':',1},
     {atom,1,format},
     {'(',1},
     {string,1,"Awesome = ~p"},
     {',',1},
     {'[',1},
     {var,1,'Awesome'},
     {']',1},
     {')',1},
     {dot,1}],
    1}
7> {ok, [Form1]} = erl_parse:parse_exprs(Tokens1).
{ok,[{call,1,
           {remote,1,{atom,1,io},{atom,1,format}},
           [{string,1,"Awesome = ~p"},
            {cons,1,{var,1,'Awesome'},{nil,1}}]}]}
8> {value, Fun1, _} = erl_eval:expr(Form, Binding).
{value,82,[{'Awesome',82}]}

9> {value, V, _} = erl_eval:expr(Form1, Binding).
Awesome = 82{value,ok,[{'Awesome',82}]}

The Binding list should grow till the end of the session.