Erlang Central

Difference between revisions of "String Eval"

From ErlangCentral Wiki

m
Line 15: Line 15:
 
{value,3,[{'A',3}]}
 
{value,3,[{'A',3}]}
 
</code>
 
</code>
 +
 +
  
 
Now, this is an admittedly baroque way to determine the value of 1 + 2, but it does give you interesting access to the inner workings of the Erlang interpreter.  
 
Now, this is an admittedly baroque way to determine the value of 1 + 2, but it does give you interesting access to the inner workings of the Erlang interpreter.  
 +
 +
In addition, you can bind in variables into the string as shown in the test module below:
 +
<code>
 +
-module(test).
 +
 +
-export([test/0]).
 +
 +
test()->
 +
    String="Results=A+B/2.",
 +
    {ok,ErlTokens,_}=erl_scan:string(String),
 +
    io:format("ErlTokens are ~p~n",[ErlTokens]),
 +
    {ok,ErlAbsForm}=erl_parse:parse_exprs(ErlTokens),
 +
    io:format("ErlAbsForm are ~p~n",[ErlAbsForm]),
 +
    Bindings=erl_eval:add_binding('A',20,erl_eval:new_bindings()),
 +
    NewBindings=erl_eval:add_binding('B',45,Bindings),
 +
    io:format("The bindings are ~p~n",[erl_eval:bindings(NewBindings)]),
 +
    io:format("Going into erl_eval:exprs~n",[]),
 +
    {value,Value,_}=erl_eval:exprs(ErlAbsForm,NewBindings),
 +
    io:format("Value is ~p~n",[Value]).
 +
</code>
 +
 +
You can compile and run this in the shell:
 +
<code>
 +
(arrian@psyduck)17> c(test).
 +
{ok,test}
 +
(arrian@psyduck)18> test:test().
 +
ErlTokens are [{var,1,'Results'},
 +
              {'=',1},
 +
              {var,1,'A'},
 +
              {'+',1},
 +
              {var,1,'B'},
 +
              {'/',1},
 +
              {integer,1,2},
 +
              {dot,1}]
 +
ErlAbsForm are [{match,1,
 +
                      {var,1,'Results'},
 +
                      {op,1,
 +
                          '+',
 +
                          {var,1,'A'},
 +
                          {op,1,'/',{var,1,'B'},{integer,1,2}}}}]
 +
The bindings are [{'A',20},{'B',45}]
 +
Going into erl_eval:exprs
 +
Value is 42.5000
 +
ok
 +
(arrian@psyduck)19>           
 +
</code>
 +
  
 
[[Category:CookBook]][[Category:StringRecipes]]
 
[[Category:CookBook]][[Category:StringRecipes]]

Revision as of 22:17, 21 November 2006

Problem

You want to evaluate Erlang code stored in a string.

Solution

Use erl_scan:string/1 to convert the string into a list of tokens, then use erl_parse:parse_exprs/1 to generate the Erlang intermediate representation, then finally use erl_eval:exprs/2 to generate the final output:

eval(S,Environ) ->
    {ok,Scanned,_} = erl_scan:string(S),
    {ok,Parsed} = erl_parse:parse_exprs(Scanned),
    erl_eval:exprs(Parsed,Environ).

1> eval("A = 1 + 2.",[]).
{value,3,[{'A',3}]}


Now, this is an admittedly baroque way to determine the value of 1 + 2, but it does give you interesting access to the inner workings of the Erlang interpreter.

In addition, you can bind in variables into the string as shown in the test module below:

-module(test).

-export([test/0]).

test()->
    String="Results=A+B/2.",
    {ok,ErlTokens,_}=erl_scan:string(String),
    io:format("ErlTokens are ~p~n",[ErlTokens]),
    {ok,ErlAbsForm}=erl_parse:parse_exprs(ErlTokens),
    io:format("ErlAbsForm are ~p~n",[ErlAbsForm]),
    Bindings=erl_eval:add_binding('A',20,erl_eval:new_bindings()),
    NewBindings=erl_eval:add_binding('B',45,Bindings),
    io:format("The bindings are ~p~n",[erl_eval:bindings(NewBindings)]),
    io:format("Going into erl_eval:exprs~n",[]),
    {value,Value,_}=erl_eval:exprs(ErlAbsForm,NewBindings),
    io:format("Value is ~p~n",[Value]).

You can compile and run this in the shell:

(arrian@psyduck)17> c(test).
{ok,test}
(arrian@psyduck)18> test:test().
ErlTokens are [{var,1,'Results'},
               {'=',1},
               {var,1,'A'},
               {'+',1},
               {var,1,'B'},
               {'/',1},
               {integer,1,2},
               {dot,1}]
ErlAbsForm are [{match,1,
                       {var,1,'Results'},
                       {op,1,
                           '+',
                           {var,1,'A'},
                           {op,1,'/',{var,1,'B'},{integer,1,2}}}}]
The bindings are [{'A',20},{'B',45}]
Going into erl_eval:exprs
Value is 42.5000
ok
(arrian@psyduck)19>            


online casino tips play free online casino slots slots online bonus gambling online bingo on line casinos online casino tips casino games online online casino net bet online casino