changeset ff351c72293f in joypy/Joypy details: http://hg.osdn.jp/view/joypy/Joypy?cmd=changeset;node=ff351c72293f user: Simon Forman <sform****@hushm*****> date: Sat Jul 20 16:38:48 2019 -0700 description: Handle exceptions in comparison ops. You can't compare logic vars, so just bunt. changeset dc6666877cd1 in joypy/Joypy details: http://hg.osdn.jp/view/joypy/Joypy?cmd=changeset;node=dc6666877cd1 user: Simon Forman <sform****@hushm*****> date: Sat Jul 20 16:45:28 2019 -0700 description: Try to handle expressions in branch combinator. If the expression isn't 'true' or 'false' atoms then we assume it's a comparison expression and try to check its truth value. If this fails then it will try both branches, to allow for e.g. compilation. THis almost works, but there's a choice point or something that gets hit before it tries the false path, ?- joy(` [32 >] [++] [--] ifte`, Si, So). Si = [_2076|_2078], So = [_2076+1|_2078] ; wtf? + Si = [_2076|_2078], So = [[+], 1, _2076|_2078] ; Si = [_2076|_2078], So = [_2076-1|_2078] ; wtf? - Si = [_2076|_2078], So = [[-], 1, _2076|_2078] ; wtf? branch Si = [_2076|_2078], So = [[branch], [++], [--], _2076>32, _2076|_2078] ; wtf? swap Si = [_2076|_2078], So = [[swap, branch], [--], [++], _2076>32, _2076|_2078] ; wtf? first Si = [_2076|_2078], So = [[first, [++], [--], swap, branch], [_2076>32|_2078], _2076|_2078] etc... diffstat: thun/thun.pl | 57 +++++++++++++++++++++++++++++++++++++++++++-------------- 1 files changed, 43 insertions(+), 14 deletions(-) diffs (88 lines): diff -r 74a2447c4fe8 -r dc6666877cd1 thun/thun.pl --- a/thun/thun.pl Tue Jul 16 09:53:48 2019 -0700 +++ b/thun/thun.pl Sat Jul 20 16:45:28 2019 -0700 @@ -22,6 +22,30 @@ :- dynamic func/3. :- dynamic '≡'/2. + +/* +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), + _, + 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. +*/ + +term_expansion(comparison_operator(X), (func(X, [A, B|S], [C|S]) :- + F =.. [X, B, A], catch((F -> C=true ; C=false), _, C=F))). + +% I don't use Prolog-compatible op symbols in all cases. +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))). + + /* An entry point. */ @@ -128,18 +152,12 @@ func(bool, [_|S], [true|S]). -func(>, [A, B|S], [ true|S]) :- B > A. -func(>, [A, B|S], [false|S]) :- \+ B > A. -func(<, [A, B|S], [ true|S]) :- B < A. -func(<, [A, B|S], [false|S]) :- \+ B < A. -func(>=, [A, B|S], [ true|S]) :- B >= A. -func(>=, [A, B|S], [false|S]) :- \+ B >= A. -func(<=, [A, B|S], [ true|S]) :- B =< A. -func(<=, [A, B|S], [false|S]) :- \+ B =< A. -func(=, [A, B|S], [ true|S]) :- B =:= A. -func(=, [A, B|S], [false|S]) :- B =\= A. -func(<>, [A, B|S], [ true|S]) :- B =\= A. -func(<>, [A, B|S], [false|S]) :- B =:= A. +comparison_operator(>). +comparison_operator(<). +comparison_operator(>=). +comparison_operator(<=, =<). +comparison_operator(=, =:=). +comparison_operator(<>, =\=). /* @@ -174,8 +192,15 @@ combo(dupdip, [P, X|S], [X|S], Ei, Eo) :- append(P, [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(branch, [T, _, true|S], S, Ei, Eo) :- !, append(T, Ei, Eo). +combo(branch, [_, F, false|S], S, Ei, Eo) :- !, append(F, Ei, Eo). +combo(branch, [T, F, Expr|S], S, Ei, Eo) :- + catch( + (Expr -> append(T, Ei, Eo) ; append(F, Ei, Eo)), + _, + try_both_branches(T, F, Ei, Eo) % in case of error. + ). + combo(loop, [_, false|S], S, E, E ). combo(loop, [B, true|S], S, Ei, Eo) :- append(B, [B, loop|Ei], Eo). @@ -195,6 +220,10 @@ append(R0, [Quoted|R1], Else). +try_both_branches(T, _, Ei, Eo) :- append(T, Ei, Eo). +try_both_branches(_, F, Ei, Eo) :- append(F, Ei, Eo). + + /* Compiler */