changeset b85fe6c1d110 in joypy/Joypy details: http://hg.osdn.jp/view/joypy/Joypy?cmd=changeset;node=b85fe6c1d110 user: Simon Forman <sform****@hushm*****> date: Sat Jul 20 16:57:19 2019 -0700 description: If I comment out the WTF handler... ...then the branch combinator works as intended. (Although the constraint-based stuff was also cool, it would have captured information from the comparison.) ?- joy(`[32 >] [++] [--] ifte`, Si, So). Si = [_6598|_6600], So = [_6598+1|_6600] ; Si = [_6598|_6600], So = [_6598-1|_6600] ; false. ?- sjc(hmm, `[32 >] [++] [--] ifte`). func(hmm, [A|B], [A+1|B]). true ; func(hmm, [A|B], [A-1|B]). true ; false. changeset e270947ee8c7 in joypy/Joypy details: http://hg.osdn.jp/view/joypy/Joypy?cmd=changeset;node=e270947ee8c7 user: Simon Forman <sform****@hushm*****> date: Sat Jul 20 17:19:35 2019 -0700 description: WTF error handler. Made it check that the unknown term really isn't a literal, definition, function, or combinator. changeset fa294f364037 in joypy/Joypy details: http://hg.osdn.jp/view/joypy/Joypy?cmd=changeset;node=fa294f364037 user: Simon Forman <sform****@hushm*****> date: Sat Jul 20 17:32:03 2019 -0700 description: Replace ≡ with plain ol' def/2. As much fun as it was using ≡ as an operator, now that all the defs live in a text file you don't see it in the Prolog code anymore. This way I get to use sweet sweet ASCII (except for the © symbol in the copyright notice.) changeset c0d894761421 in joypy/Joypy details: http://hg.osdn.jp/view/joypy/Joypy?cmd=changeset;node=c0d894761421 user: Simon Forman <sform****@hushm*****> date: Sat Jul 20 17:36:58 2019 -0700 description: Fold try_both_branches/4 into branch combo. changeset f2d71c5ad139 in joypy/Joypy details: http://hg.osdn.jp/view/joypy/Joypy?cmd=changeset;node=f2d71c5ad139 user: Simon Forman <sform****@hushm*****> date: Sat Jul 20 19:26:11 2019 -0700 description: Add mod, gcd, and hypot; term_expansion for math ops. diffstat: thun/defs.txt | 4 +++- thun/thun.pl | 56 +++++++++++++++++++++++++++++++++++++------------------- 2 files changed, 40 insertions(+), 20 deletions(-) diffs (150 lines): diff -r dc6666877cd1 -r f2d71c5ad139 thun/defs.txt --- a/thun/defs.txt Sat Jul 20 16:45:28 2019 -0700 +++ b/thun/defs.txt Sat Jul 20 19:26:11 2019 -0700 @@ -9,7 +9,7 @@ b == [i] dip i binary == unary popd ccons == cons cons -cleave == fork [popd] dip +cleave == fork popdd codireco == cons dip rest cons dinfrirst == dip infrst disenstacken == ? [uncons ?] loop pop @@ -22,7 +22,9 @@ flatten == [] swap [concat] step fork == [i] app2 fourth == rest third +gcd == true [tuck mod dup 0 >] loop pop grba == [stack popd] dip +hypot == [sqr] ii + sqrt ifte == [nullary] dipd swap branch ii == [dip] dupdip i infra == swons swaack [i] dip swaack diff -r dc6666877cd1 -r f2d71c5ad139 thun/thun.pl --- a/thun/thun.pl Sat Jul 20 16:45:28 2019 -0700 +++ b/thun/thun.pl Sat Jul 20 19:26:11 2019 -0700 @@ -18,9 +18,8 @@ % :- use_module(library(clpfd)). :- use_module(library(dcg/basics)). -:- op(990, xfy, ≡). % for Joy definitions. :- dynamic func/3. -:- dynamic '≡'/2. +:- dynamic def/2. /* @@ -45,6 +44,14 @@ 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. + +term_expansion(math_operator(X), (func(X, [A, B|S], [C|S]) :- + F =.. [X, B, A], catch(C is F, _, C=F))). + +term_expansion(math_operator(X, Y), (func(X, [A, B|S], [C|S]) :- + F =.. [Y, B, A], catch(C is F, _, C=F))). + /* An entry point. @@ -83,12 +90,24 @@ thun([], S, S). thun( [Lit|E], Si, So) :- literal(Lit), !, thun(E, [Lit|Si], So). -thun( [Def|E], Si, So) :- Def ≡ Body, !, append(Body, E, Eo), thun(Eo, Si, So). +thun( [Def|E], Si, So) :- def(Def, Body), !, append(Body, E, Eo), thun(Eo, 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). % Some error handling. -thun([Unknown|E], Si, So) :- write("wtf? "), writeln(Unknown), So = [[Unknown|E]|Si]. + +thun([Unknown|E], Si, So) :- + damned_thing(Unknown), + write("wtf? "), + writeln(Unknown), + So = [[Unknown|E]|Si]. + +damned_thing(It) :- + \+ literal(It), + \+ def(It, _), + \+ func(It, _, _), + \+ combo(It, _, _, _, _). + /* Literals @@ -117,10 +136,11 @@ func(pop, [_|S], S ). % Symbolic math. Compute the answer, or derivative, or whatever, later. -func(+, [A, B|S], [B + A|S]). -func(-, [A, B|S], [B - A|S]). -func(*, [A, B|S], [B * A|S]). -func(/, [A, B|S], [B / A|S]). +math_operator(+). +math_operator(-). +math_operator(*). +math_operator(/). +math_operator(mod). % Attempt to calculate the value of a symbolic math expression. func(calc, [A|S], [B|S]) :- B is A. @@ -164,7 +184,7 @@ Definitions */ -joy_def(Def ≡ Body) --> symbol(Def), blanks, "==", joy_parse(Body). +joy_def(def(Def, Body)) --> symbol(Def), blanks, "==", joy_parse(Body). joy_defs([Def|Defs]) --> blanks, joy_def(Def), blanks, joy_defs(Defs). joy_defs([]) --> []. @@ -177,7 +197,9 @@ read_defs(DefsFile, Defs), forall(member(Def, Defs), assert_def(Def)). -assert_def(Def≡Body) :- retractall(Def≡_), assertz(Def≡Body). +assert_def(def(Def, Body)) :- + retractall(def(Def, _)), + assertz(def(Def, Body)). :- assert_defs("defs.txt"). @@ -195,10 +217,10 @@ 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( + catch( % Try Expr and do one or the other, (Expr -> append(T, Ei, Eo) ; append(F, Ei, Eo)), - _, - try_both_branches(T, F, Ei, Eo) % in case of error. + _, % If Expr don't grok, try both branches. + (append(T, Ei, Eo) ; append(F, Ei, Eo)) ). @@ -220,10 +242,6 @@ 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 */ @@ -246,8 +264,8 @@ % Simple DCGs to expand/contract definitions. -expando, Body --> [Def], {Def ≡ Body}. -contracto, [Def] --> {Def ≡ Body}, Body. +expando, Body --> [Def], {def(Def, Body)}. +contracto, [Def] --> {def(Def, Body)}, Body. % phrase(expando, ExprIn, ExprOut).