Comparisions are literals too.

Also a bunch of reformatting.

Maybe I can modify the term_expansion/2 to also write the literal/1 clauses for math and comps?
This commit is contained in:
Simon Forman 2019-07-22 10:25:34 -07:00
parent 97a99ac3c4
commit 2ba9242b76
1 changed files with 36 additions and 17 deletions

View File

@ -1,5 +1,5 @@
%
% Copyright © 2018 Simon Forman
% Copyright © 2018, 2019 Simon Forman
%
% This file is part of Thun
%
@ -23,10 +23,12 @@
/*
To handle comparision operators the possibility of exceptions due to insufficiently instantiated
arguments must be handled. First try to make the comparison and set the result to a Boolean atom.
If an exception happens just leave the comparison expression as the result and some other function
or combinator will deal with it. Example:
To handle comparision operators the possibility of exceptions due to
insufficiently instantiated arguments must be handled. First try to make
the comparison and set the result to a Boolean atom. If an exception
happens just leave the comparison expression as the result and some other
function or combinator will deal with it. Example:
func(>, [A, B|S], [C|S]) :- catch(
(B > A -> C=true ; C=false),
@ -34,7 +36,8 @@ or combinator will deal with it. Example:
C=(B>A) % in case of error.
).
To save on conceptual overhead I've defined a term_expansion/2 that sets up the func/3 for each op.
To save on conceptual overhead I've defined a term_expansion/2 that sets
up the func/3 for each op.
*/
term_expansion(comparison_operator(X), (func(X, [A, B|S], [C|S]) :-
@ -44,7 +47,8 @@ term_expansion(comparison_operator(X), (func(X, [A, B|S], [C|S]) :-
term_expansion(comparison_operator(X, Y), (func(X, [A, B|S], [C|S]) :-
F =.. [Y, B, A], catch((F -> C=true ; C=false), _, C=F))).
% Likewise for math operators, try to evaluate, otherwise use the symbolic form.
% Likewise for math operators, try to evaluate, otherwise use the
% symbolic form.
term_expansion(math_operator(X), (func(X, [A, B|S], [C|S]) :-
F =.. [X, B, A], catch(C is F, _, C=F))).
@ -125,6 +129,16 @@ literal(_+_).
literal(_-_).
literal(_*_).
literal(_/_).
literal(_ mod _).
% Symbolic comparisons are literals.
literal(_>_).
literal(_<_).
literal(_>=_).
literal(_=<_).
literal(_=:=_).
literal(_=\=_).
/*
Functions
@ -191,7 +205,7 @@ joy_defs --> [].
assert_defs(DefsFile) :-
read_file_to_codes(DefsFile, Codes, []),
phrase(joy_defs, Codes).
phrase(joy_defs, Codes).
assert_def(def(Def, Body)) :-
retractall(def(Def, _)),
@ -238,15 +252,20 @@ combo(genrec, [R1, R0, Then, If|S],
append(R0, [Quoted|R1], Else).
/*
This is a crude but servicable implementation of map combinator.
Obviously it would be nice to take advantage of the implied parallelism.
Instead the quoted program, stack, and each term in the arg list are
transformed to a simple Joy expression that runs the program on a prepared
stack. These expressions are collected in a list and the whole thing is
evaluated with infra on an empty list, so the result is the mapped list.
This is a crude but servicable implementation of the map combinator.
The chief advantage of doing it this way (as opposed to using Prolog's map)
is that the whole state remains in the continuation expression.
Obviously it would be nice to take advantage of the implied parallelism.
Instead the quoted program, stack, and terms in the input list are
transformed to simple Joy expressions that run the quoted program on
prepared copies of the stack that each have one of the input terms on
top. These expressions are collected in a list and the whole thing is
evaluated (with infra) on an empty list, which becomes the output list.
The chief advantage of doing it this way (as opposed to using Prolog's
map) is that the whole state remains in the pending expression, so
there's nothing stashed in Prolog's call stack. This preserves the nice
property that you can interrupt the Joy evaluation and save or transmit
the stack+expression knowing that you have all the state.
*/
combo(map, [_, []|S], [[]|S], E, E ) :- !.
@ -280,7 +299,7 @@ jcmpl(Name, Expression, Rule) :-
Head =.. [func, Name, Si, So],
rule(Head, Gs, Rule).
rule(Head, [], Head ).
rule(Head, [], Head ).
rule(Head, [A|B], Head :- maplist(call, [A|B])).
sjc(Name, InputString) :- phrase(joy_parse(E), InputString), show_joy_compile(Name, E).