~eshel/eshellisp

42c97cd7ce8e8c87db99449c79a4fa343877340a — Eshel Yaron 2 years ago df2144d
ADDED: Bootstrapped Scheme REPL
5 files changed, 51 insertions(+), 11 deletions(-)

M Makefile
A lisp/read_eval_write.scm
A lisp/repl.scm
M prolog/eshellisp/eval.pl
M prolog/eshellisp/read.pl
M Makefile => Makefile +1 -0
@@ 13,6 13,7 @@ lint:

check: lint $(PACKAGE)
	./$(PACKAGE) test/suite.scm
	echo "(+ 1 2)" | ./$(PACKAGE) lisp/read_eval_write.scm

$(PACKAGE): $(SOURCES)
	$(PROLOG) --undefined=error -O -o $@ -c prolog/$(PACKAGE)/main.pl

A lisp/read_eval_write.scm => lisp/read_eval_write.scm +2 -0
@@ 0,0 1,2 @@
(import (scheme base))
(test 'read-eval (eval (read)) 3)

A lisp/repl.scm => lisp/repl.scm +3 -0
@@ 0,0 1,3 @@
(define repl () (write (eval (read))) (repl))

(repl)

M prolog/eshellisp/eval.pl => prolog/eshellisp/eval.pl +37 -7
@@ 21,15 21,19 @@ evaluate_program(Forms, File, Layout, Vars, Value0, Value) :-

evaluate_forms(_, _, _, _, exception(What, Where), exception(What, Where), []) :-
    !.
evaluate_forms([H|T], File, [PH|PT], Vars, Value0, Value, [Value1|RT]) :-
evaluate_forms([H|T], File, Layouts, Vars, Value0, Value, [Value1|RT]) :-
    !,
    layouts_parts(Layouts, PH, PT),
    evaluate_form(H, File, PH, Vars, Value0, Value1),
    evaluate_forms(T, File, PT, Vars, Value1, Value, RT).
evaluate_forms([], _, _, _, Value, Value, []).


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

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


@@ 37,22 41,29 @@ evaluate_form([import, SpecList], File, layout(_, _, [_, SpecLayout]), Vars, Val
        access_file(Path, read)
    ->  read_program(file(Path), Program, [positions(Positions)]),
        evaluate_program(Program, Path, Positions, Vars, Value0, Value)
    ;   Value = exception(import_error(Spec), File:SpecLayout)
    ;   sub_layout(2, Layout, SpecLayout),
        Value = exception(import_error(Spec), File:SpecLayout)
    ).
evaluate_form([define, Name, Args | Body], File, layout(_, _, [_, _, _ | PBody]), _, _, quote(Name)) :-
evaluate_form([define, Name, Args | Body], File, Layout, _, _, quote(Name)) :-
    !,
    retractall(defined(Name, _, _, _, _)),
    asserta(defined(Name, Args, Body, File, PBody)).
evaluate_form([if, Cond, Then, Else], File, layout(_, _, [_, PCond, PThen, PElse]), Vars, R0, R) :-
    sub_layouts(3, Layout, BodyLayout),
    asserta(defined(Name, Args, Body, File, BodyLayout)).
evaluate_form([if, Cond, Then, Else], File, Layout, Vars, R0, R) :-
    !,
    sub_layout(2, Layout, PCond),
    sub_layout(3, Layout, PThen),
    sub_layout(4, Layout, PElse),
    evaluate_form(Cond, File, PCond, Vars, R0, R1),
    (   R1 == '#f'
    ->  Next = Else, PNext = PElse
    ;   Next = Then, PNext = PThen
    ),
    evaluate_form(Next, File, PNext, Vars, R1, R).
evaluate_form([Name | Args], File, layout(_, _, [PName | PArgs]), Vars, Value0, Value) :-
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)
    ->  (   maplist([Arg,Val,Arg=Val]>>true, A, Vals, Vars1)


@@ 89,5 100,24 @@ primitive('<=',     [_, _], '#f') :- !.
primitive('equal?', [A, A], '#t') :- !.
primitive('equal?', [_, _], '#f') :- !.
primitive('equal?', [_, _], '#f') :- !.
primitive('read',   []    , O) :- !, read_form(O).
primitive('eval',   [O]   , R) :- !, evaluate_form(O, R).
primitive('write',  [O]   , '#t') :- !, write_form(O).
primitive('raise',  [O]   , exception(O)) :- !.


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


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


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

M prolog/eshellisp/read.pl => prolog/eshellisp/read.pl +8 -4
@@ 1,5 1,6 @@
:- module(eshellisp_read,
          [ read_program/3   % +Stream, -Program, +Options
          [ read_program/3,   % +Stream, -Program, +Options
            read_form/1
          ]).




@@ 23,6 24,12 @@ read_program(Stream, Program, Options) :-
    phrase_from_stream(tokens(Tokens), Stream),
    parse(Tokens, 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, _).

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


@@ 50,7 57,6 @@ token(nl) --> [10], !.
token(ws) --> [32], !.


:- det(ws//2).
ws(position(L0, C0, O0), position(L, C, O)) -->
    [ws],
    !,


@@ 69,8 75,6 @@ ws(P, P) --> !.



:- det(form_components/3).

form(symbol(Name),
     position(StartLine, StartColumn, StartOffset),
     position(StartLine, EndColumn, EndOffset)) -->