[erlang-questions] Programmatic interface to the shell

Joe Armstrong erlang@REDACTED
Mon Aug 10 20:13:02 CEST 2015


On Mon, Aug 10, 2015 at 7:17 PM, Éric Pailleau <eric.pailleau@REDACTED> wrote:
> Hello Joe,
>
> In bottom of this code
>
> https://github.com/erlang/otp/blob/maint/lib/observer/src/observer_procinfo.erl
>
> Is a simple io server, thanks to Dan Gudmunson.
> This may help ?

I'm not sure how?

/Joe

> Regards
>
>
> Le 10 août 2015 19:08, Joe Armstrong <erlang@REDACTED> a écrit :
>>
>> Wonderful - thanks
>>
>> The main problem now is that the error messages are not exactly the same
>> as in the shell.
>>
>> ie: The above code for X/0 says
>>
>> > Send(P, "X/0.").
>> ** exception error: an error occurred when evaluating an arithmetic expression
>>
>> But X/0. in the shell says:
>>
>> > X/0.
>> ** exception error: an error occurred when evaluating an arithmetic expression
>>      in operator  '/'/2
>>         called as 4 / 0
>>
>> Do you have any idea how to dig out the error message so it's exactly the same?
>>
>> I'm asking because I'm writing a tutorial in a "markdown like" language
>> and I want to automate production of examples :-)
>>
>>
>> Thanks again
>>
>> /Joe
>>
>>
>>
>>
>>
>>
>>
>> On Mon, Aug 10, 2015 at 6:23 PM, Fred Hebert <mononcqc@REDACTED> wrote:
>> > On 08/10, Joe Armstrong wrote:
>> >>
>> >> Hello,
>> >>
>> >> Is there a *simple* programmatic interface to the Erlang shell?
>> >>
>> >> I'd like a module "shell_interface" that works like this:
>> >>
>> >>      Pid = shell_interface:new_shell(),
>> >>
>> >> Returns a new process that behaves like the Erlang shell
>> >>
>> >>      OutStr = shell_interface:eval(Pid, InStr)
>> >>
>> >
>> > Short answer is no. The Erlang shell in the `shell' module asks for
>> > information via the IO protocol and pulls it in, rather than you pushing it
>> > out.
>> >
>> > There's ways to inject yourself in there, but it's not simple.
>> >
>> >> This behaves like the Erlang shell. InStr should be what I typed into the
>> >> shell. OutStr should be what the shell replied.
>> >>
>> >> For this purpose we can assume that InStr represents a complete
>> >> sequence of expressions.
>> >>
>> >
>> > This sounds more like an evaluator/interpreter:
>> >
>> >    1> {ok, Tokens, _} = erl_scan:string("X + 4 * lists:sum([1,2,3,4]).").
>> >    ...
>> >    2> {ok, [Form]} = erl_parse:parse_exprs(Tokens).
>> >    ...
>> >    3> Bindings = erl_eval:add_binding('X', 17, erl_eval:new_bindings()).
>> >    [{'X',17}]
>> >    4> {value, Value, _} = erl_eval:expr(Form, Bindings).
>> >    {value,57,[{'X',17}]}
>> >    5> Value.
>> >    57
>> >
>> > With these basic forms it becomes doable to write a mini-shell the way you'd
>> > like it.
>> >
>> >    Eval = fun EvalLoop(Bindings) ->
>> >        receive
>> >            {cmd, Caller, Ref, String} ->
>> >                try
>> >                    {ok, Tokens, _} = erl_scan:string(String),
>> >                    %% many forms can be comma-separated
>> >                    {ok, Forms} = erl_parse:parse_exprs(Tokens),
>> >                    %% eval individually
>> >                    {value, Val, NewBindings} = erl_eval:exprs(Forms,
>> > Bindings),
>> >                    Caller ! {ok, Ref, Val},
>> >                    EvalLoop(NewBindings)
>> >                catch
>> >                    T:R ->
>> >                        Caller ! {raise, Ref, T, R},
>> >                        EvalLoop(Bindings)
>> >                end
>> >        end end.
>> >
>> >    Send = fun(Pid, String) ->
>> >        Ref = erlang:monitor(process, Pid),
>> >        Pid ! {cmd, self(), Ref, String},
>> >        receive
>> >            {ok, Ref, Value} -> Value;
>> >            {raise, Ref, T, R} -> erlang:T(R)
>> >        end end.
>> >
>> >    18> P = spawn(fun() -> Eval([]) end).
>> >    <0.62.0>
>> >    19> Send(P, "X=2+2.").
>> >    4
>> >    20> Send(P, "X*X.").
>> >    16
>> >    21> Send(P, "X/0.").
>> >    ** exception error: an error occurred when evaluating an arithmetic
>> > expression
>> >    22> Send(P, "X.").
>> >    4
>> >
>> > And there  you have an evaluator. It doesn't support all the stuff like
>> > 'h().' and whatnot, but is close enough otherwise.
>> >
>> _______________________________________________
>> erlang-questions mailing list
>> erlang-questions@REDACTED
>> http://erlang.org/mailman/listinfo/erlang-questions



More information about the erlang-questions mailing list