Skip to content

Instantly share code, notes, and snippets.

@patrickgombert
Created August 11, 2013 14:33
Show Gist options
  • Save patrickgombert/6205156 to your computer and use it in GitHub Desktop.
Save patrickgombert/6205156 to your computer and use it in GitHub Desktop.
Indestructable Erlang REPL
-module(shell).
-export([loop/0, eval_loop/0, eval/2]).
read() ->
io:get_line("> ").
eval(String, Bindings) ->
{ok, Tokens, _} = erl_scan:string(String),
{ok, Parsed} = erl_parse:parse_exprs(Tokens),
erl_eval:exprs(Parsed, Bindings).
print(Output) ->
erlang:display(Output).
loop() ->
EvalPid = gen_eval(),
loop(orddict:new(), EvalPid).
loop(Bindings, EvalPid) ->
Read = read(),
case Read of
"?EXIT.\n" ->
print("goodbye!"),
halt();
_ ->
EvalPid ! {self(), Read, Bindings},
receive
{Value, NewBindings} ->
print(Value),
loop(NewBindings, EvalPid);
{'DOWN', _, process, _, _} ->
NewEvalPid = gen_eval(),
loop(Bindings, NewEvalPid)
end
end.
gen_eval() ->
EvalPid = spawn(?MODULE, eval_loop, []),
erlang:monitor(process, EvalPid),
EvalPid.
eval_loop() ->
receive
{Pid, String, Bindings} ->
{value, Value, NewBindings} = eval(String, Bindings),
Pid ! {Value, NewBindings},
eval_loop()
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment