~eshel/eshellisp

1a56b974c74115af3999db9b519278618ecdb032 — Eshel Yaron 1 year, 11 months ago 384ebde
ENHANCHED: Better REPL interaction and stacktraces
4 files changed, 54 insertions(+), 16 deletions(-)

M prolog/eshellisp/eval.pl
M prolog/eshellisp/read.pl
M prolog/eshellisp/write.pl
A scheme/stacktrace.scm
M prolog/eshellisp/eval.pl => prolog/eshellisp/eval.pl +16 -10
@@ 30,9 30,9 @@ evaluate_forms([], _, _, _, Value, Value, []).


evaluate_form(Form, Value) :-
    evaluate_form(Form, dynamic, dynamic, [], '#f', Value).
    evaluate_form(Form, dyn, dyn, [], '#f', Value).

evaluate_form(_, _, _, _, exception(What, Where), exception(What, Where)) :- !.
evaluate_form(_, File, Layout, _, exception(What, Where), exception(What, [File:Layout|Where])) :- !.
evaluate_form([import, SpecList], File, Layout, Vars, Value0, Value) :-
    !,
    Spec =.. SpecList,


@@ 42,7 42,7 @@ evaluate_form([import, SpecList], File, Layout, Vars, Value0, Value) :-
    ->  read_program(file(Path), Program, [positions(Positions)]),
        evaluate_program(Program, Path, Positions, Vars, Value0, Value)
    ;   sub_layout(2, Layout, SpecLayout),
        Value = exception(import_error(Spec), File:SpecLayout)
        Value = exception(import_error(Spec), [File:SpecLayout])
    ).
evaluate_form([define, Name, Args | Body], File, Layout, _, _, quote(Name)) :-
    !,


@@ 65,7 65,9 @@ evaluate_form([Name | Args], File, Layout, Vars, Value0, Value) :-
    sub_layout(1, Layout, PName),
    sub_layouts(1, Layout, PArgs),
    evaluate_forms(Args, File, PArgs, Vars, Value0, Value1, Vals),
    (   defined(Name, A, Body, F, P)
    (   Value1 = exception(What, Where)
    ->  Value  = exception(What, [File:Layout|Where])
    ;   defined(Name, A, Body, F, P)
    ->  (   maplist([Arg,Val,Arg=Val]>>true, A, Vals, Vars1)
        ->  append(Vars1, Vars, Vars2),
            evaluate_program(Body, F, P, Vars2, Value1, Value)


@@ 73,14 75,18 @@ evaluate_form([Name | Args], File, Layout, Vars, Value0, Value) :-
        )
    ;   primitive(Name, Vals, Value2)
    ->  (   Value2 = exception(What)
        ->  Value  = exception(What, File:PName)
        ->  Value  = exception(What, [File:PName])
        ;   Value  = Value2
        )
    ;   Value = exception(no_such_function(Name), File:PName)
    ;   Value = exception(no_such_function(Name), [File:PName])
    ).
evaluate_form(quote(E), _, _, _, _, E) :- !.
evaluate_form('#t', _, _, _, _, '#t') :- !.
evaluate_form('#f', _, _, _, _, '#f') :- !.
evaluate_form('#end-of-file', _, _, _, _, _) :-
    !,
    write_form('#end-of-file'),
    halt(0).
evaluate_form(Number, _, _, _, _, Number) :-
    number(Number),
    !.


@@ 89,7 95,7 @@ evaluate_form(Symbol, File, Layout, Vars, _, Value) :-
    !,
    (   memberchk(Symbol=Value, Vars)
    ->  true
    ;   Value = exception(no_such_symbol(Symbol), File:Layout)
    ;   Value = exception(no_such_symbol(Symbol), [File:Layout])
    ).




@@ 114,18 120,18 @@ primitive('cdr',    [O] , exception(no_cons(O))) :- !.



sub_layout(_, dynamic, dynamic) :- !.
sub_layout(_, dyn, dyn) :- !.
sub_layout(N, layout(_, _, Subs), Sub) :-
    !,
    nth1(N, Subs, Sub).


sub_layouts(_, dynamic, dynamic) :- !.
sub_layouts(_, dyn, dyn) :- !.
sub_layouts(Skip, layout(_, _, Subs0), Subs) :-
    !,
    length(Prefix, Skip),
    append(Prefix, Subs, Subs0).


layouts_parts(dynamic, dynamic, dynamic) :- !.
layouts_parts(dyn, dyn, dyn) :- !.
layouts_parts([H|T], H, T).

M prolog/eshellisp/read.pl => prolog/eshellisp/read.pl +6 -3
@@ 27,9 27,12 @@ read_program(Stream, Program, Options) :-
read_form(Expression) :-
    prompt1('% '),
    read_line_to_codes(current_input, Codes),
    phrase(tokens(Tokens), Codes),
    phrase(forms([Form], position(1, 0, 0), _), Tokens),
    form_components(Form, Expression, _).
    (   Codes == end_of_file
    ->  Expression = '#end-of-file'
    ;   phrase(tokens(Tokens), Codes),
        phrase(forms([Form], position(1, 0, 0), _), Tokens),
        form_components(Form, Expression, _)
    ).

parse(Tokens, Expressions, Options) :-
    phrase(forms(Forms, position(1, 0, 0), _), Tokens),

M prolog/eshellisp/write.pl => prolog/eshellisp/write.pl +25 -3
@@ 2,19 2,22 @@
          [ write_form/1   % +Value
          ]).


write_form(Value) :-
    print_message(information, eshellisp(Value)).


:- multifile prolog:message//1.

prolog:message(eshellisp(Value)) -->
    !,
    form(Value).

form(exception(What, Path:layout(position(Line, Column, _), _, _))) -->

form(exception(What, [H|T])) -->
    !,
    { absolute_file_name(Path, Abs) },
    [ 'Exception ~w at ~w:~w:~w'-[What, Abs, Line, Column] ].
    exception(What, H),
    stack(T).
form(quote(Value)) -->
    !,
    [ '\''-[] ],


@@ 48,3 51,22 @@ cdr(Form) -->
    [ ' . '-[] ],
    form(Form),
    [ ')'-[] ].


exception(What, dyn:dyn) -->
    !,
    [ 'Exception ~w'-[What] ].
exception(What, Path:layout(position(Line, Column, _), _, _)) -->
    !,
    { absolute_file_name(Path, Abs) },
    [ 'Exception ~w at '-[What], url(Abs:Line:Column) ].

stack([dyn:dyn|T]) -->
    !,
    stack(T).
stack([Path:layout(position(Line, Column, _), _, _)|T]) -->
    !,
    { absolute_file_name(Path, Abs) },
    [ nl, '    Called from '-[], url(Abs:Line:Column) ],
    stack(T).
stack([]) --> !.

A scheme/stacktrace.scm => scheme/stacktrace.scm +7 -0
@@ 0,0 1,7 @@
(define foo (a) (cdr a))
(define bar (a) (car a))

(write (+ 1 (bar
             (foo
              (foo
               '(2 3))))))