Thun/thun/gnu-prolog/junk/gthun.pl

121 lines
2.4 KiB
Prolog

:- op(990, xfy, =-).
:- dynamic((=-)/2).
:- initialization(loop).
/*
Parser
*/
joy_parse([T|S]) --> blanks, joy_term(T), blanks, joy_parse(S).
joy_parse([]) --> [].
joy_term(N) --> num(N), !.
joy_term(S) --> [0'[], !, joy_parse(S), [0']].
joy_term(A) --> chars(Chars), !, {atom_codes(A, Chars)}.
/*
Interpreter.
*/
thun([], S, S).
thun( [Lit|E], Si, So) :- literal(Lit), !, thun(E, [Lit|Si], So).
thun( [Func|E], Si, So) :- func(Func, Si, S), !, thun(E, S, So).
thun([Combo|E], Si, So) :- combo(Combo, Si, S, E, Eo), !, thun(Eo, S, So).
thun(Err, S, [Err|S]) :- write('Unknown term!'), nl.
/*
Literals
*/
literal(V) :- var(V).
literal(I) :- number(I).
literal([]).
literal([_|_]).
literal(true).
literal(false).
/*
Functions
*/
func(cons, [A, B|S], [[B|A]|S]).
func(swap, [A, B|S], [B, A|S]).
func(dup, [A|S], [A, A|S]).
func(pop, [_|S], S ).
func(uncons, Si, So) :- func(cons, So, Si).
func(+, [A, B|S], [B+A|S]).
func(=, [A|S], [B|S]) :- B is A.
func(clear, _, []).
func(stack, S, [S|S]).
/*
Definitions
*/
% This is NOT the Continuation-Passing Style
%
% func(Name, Si, So) :- Name =- Body, thun(Body, Si, So).
func(inscribe, [Definition|S], S) :-
Definition = [Name|Body],
atom(Name),
assertz(Name =- Body).
swons =- [swap, cons].
x =- [dup, i].
unit =- [[], cons].
enstacken =- [stack, [clear], dip].
% This IS the Continuation-Passing Style
%
combo(Name, S, S, Ei, Eo) :- Name =- Body, append(Body, Ei, Eo).
/*
Combinators
*/
combo(i, [P|S], S, Ei, Eo) :- append(P, Ei, Eo).
combo(dip, [P, X|S], S, Ei, Eo) :- append(P, [X|Ei], Eo).
combo(dipd, [P, X, Y|S], S, Ei, Eo) :- append(P, [Y, X|Ei], Eo).
combo(branch, [T, _, true|S], S, Ei, Eo) :- append(T, Ei, Eo).
combo(branch, [_, F, false|S], S, Ei, Eo) :- append(F, Ei, Eo).
combo(loop, [_, false|S], S, E, E ).
combo(loop, [B, true|S], S, Ei, Eo) :- append(B, [B, loop|Ei], Eo).
combo(step, [_, []|S], S, E, E ).
combo(step, [P, [X]|S], [X|S], Ei, Eo) :- !, append(P, Ei, Eo).
combo(step, [P, [X|Z]|S], [X|S], Ei, Eo) :- append(P, [Z, P, step|Ei], Eo).
/*
Main Loop
*/
loop :- line(Line), loop(Line, [], _Out).
loop([eof], S, S) :- !.
loop( Line, In, Out) :-
do_line(Line, In, S),
write(S), nl,
line(NextLine), !,
loop(NextLine, S, Out).
do_line(Line, In, Out) :- phrase(joy_parse(E), Line), thun(E, In, Out).
do_line(_Line, S, S) :- write('Err'), nl.