From 6a94c12b9bea7998f143a0cc56426917da05da12 Mon Sep 17 00:00:00 2001 From: Simon Forman Date: Fri, 2 Aug 2019 18:30:43 -0700 Subject: [PATCH 1/8] Get the path separator right on windows. It used to use: C:\Users\sforman/.joypy which worked, but ew. --- joy/gui/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/joy/gui/utils.py b/joy/gui/utils.py index a83657f..3b7abfa 100644 --- a/joy/gui/utils.py +++ b/joy/gui/utils.py @@ -7,7 +7,7 @@ from dulwich.repo import Repo COMMITTER = 'Joy ' -DEFAULT_JOY_HOME = '~/.joypy' +DEFAULT_JOY_HOME = expanduser(join('~', '.joypy')) def home_dir(path): From cb0078f3bc657e220dbc69494a5ced2242374860 Mon Sep 17 00:00:00 2001 From: Simon Forman Date: Sat, 3 Aug 2019 17:56:25 -0700 Subject: [PATCH 2/8] Gnarly fun with metaprogramming. --- thun/thun.pl | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/thun/thun.pl b/thun/thun.pl index b611059..f1d87b5 100644 --- a/thun/thun.pl +++ b/thun/thun.pl @@ -292,5 +292,45 @@ sjc(Name, InputString) :- phrase(joy_parse(E), InputString), show_joy_compile(Na expando, Body --> [Def], {def(Def, Body)}. contracto, [Def] --> {def(Def, Body)}, Body. +% Apply expando/contracto more than once, and descend into sub-lists. +% The K term is one of expando or contracto, and the J term is used +% on sub-lists, i.e. expando/grow and contracto/shrink. +% BTW, "crbo" and "rebo" are meaningless names, don't break your brain +% trying to figure them out. + +rebo(K, J) --> K , rebo(K, J). +rebo(K, J), [E] --> [[H|T]], !, {call(J, [H|T], E)}, rebo(K, J). +rebo(K, J), [A] --> [ A ], !, rebo(K, J). +rebo(_, _) --> []. + +crbo(K, J, Ei, Eo) :- + phrase(rebo(K, J), Ei, E), % Apply expando/grow or contracto/shrink... + (Ei=E -> Eo=E ; crbo(K, J, E, Eo)). % ...until a fixed-point is reached. + +grow(Ei, Eo) :- crbo(expando, grow, Ei, Eo). +shrink(Ei, Eo) :- crbo(contracto, shrink, Ei, Eo). + + +/* +?- E=[foo,bar,swap,cons,baz],phrase(shrink, E, ExprOut). +E = [foo, bar, swap, cons, baz], +ExprOut = [foo, bar, swons, baz]. + +?- E=[foo, bar, swons, baz],phrase(grow, E, ExprOut). +E = [foo, bar, swons, baz], +ExprOut = [foo, bar, swap, cons, baz]. + +*/ + + +% ... --> [] | [_], ... . + +% for the ellipsis operator +% http://swi-prolog.996271.n3.nabble.com/DCG-idioms-td3117.html which references: +% David B. Searls, Investigating the Linguistics of DNA with Definite Clause Grammars. NACLP 1989. + % phrase(expando, ExprIn, ExprOut). +% E=[foo,bar,swap,cons,baz],phrase((...,contracto,...), E, ExprOut). +% E = [foo, bar, swap, cons, baz], +% ExprOut = [swons, baz] \ No newline at end of file From 3b1a89d1c4aa91759b8f8687ea4c2af1e2d92526 Mon Sep 17 00:00:00 2001 From: Simon Forman Date: Sat, 3 Aug 2019 19:01:00 -0700 Subject: [PATCH 3/8] Minor refactor. crbo/4 to to_fixed_point/3 --- thun/thun.pl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/thun/thun.pl b/thun/thun.pl index f1d87b5..9b4d4e9 100644 --- a/thun/thun.pl +++ b/thun/thun.pl @@ -295,20 +295,20 @@ contracto, [Def] --> {def(Def, Body)}, Body. % Apply expando/contracto more than once, and descend into sub-lists. % The K term is one of expando or contracto, and the J term is used % on sub-lists, i.e. expando/grow and contracto/shrink. -% BTW, "crbo" and "rebo" are meaningless names, don't break your brain -% trying to figure them out. +% BTW, "rebo" is a meaningless name, don't break your brain +% trying to figure it out. rebo(K, J) --> K , rebo(K, J). rebo(K, J), [E] --> [[H|T]], !, {call(J, [H|T], E)}, rebo(K, J). rebo(K, J), [A] --> [ A ], !, rebo(K, J). rebo(_, _) --> []. -crbo(K, J, Ei, Eo) :- - phrase(rebo(K, J), Ei, E), % Apply expando/grow or contracto/shrink... - (Ei=E -> Eo=E ; crbo(K, J, E, Eo)). % ...until a fixed-point is reached. +to_fixed_point(DCG, Ei, Eo) :- + phrase(DCG, Ei, E), % Apply DCG... + (Ei=E -> Eo=E ; to_fixed_point(DCG, E, Eo)). % ...until a fixed-point is reached. -grow(Ei, Eo) :- crbo(expando, grow, Ei, Eo). -shrink(Ei, Eo) :- crbo(contracto, shrink, Ei, Eo). +grow(Ei, Eo) :- to_fixed_point(rebo(expando, grow ), Ei, Eo). +shrink(Ei, Eo) :- to_fixed_point(rebo(contracto, shrink), Ei, Eo). /* From 177d6cd433a31071e54e0cc76f12e3eeac78b981 Mon Sep 17 00:00:00 2001 From: Simon Forman Date: Sat, 3 Aug 2019 19:01:45 -0700 Subject: [PATCH 4/8] Experiment in formatting stacks for output. Tracing, sort of... --- thun/metalogical.pl | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/thun/metalogical.pl b/thun/metalogical.pl index 201fd86..caf4b04 100644 --- a/thun/metalogical.pl +++ b/thun/metalogical.pl @@ -10,7 +10,7 @@ tmi(var(A)) :- var(A). % Meta-logical print trace. % (Could also be captured in a list or something instead.) -tmi(thun(E, Si, _)) :- portray_clause(Si-E), fail. +tmi(thun(E, Si, _)) :- frump(Si, E), fail. tmi(Goal) :- checky(Goal), @@ -24,6 +24,33 @@ checky(Goal) :- Goal \= number(_), Goal \= !. + +format_state(Stack, Expression, Codes) :- + reverse(Stack, RStack), + phrase(format_stack(RStack), RStackCodes), + phrase(format_stack(Expression), ExpressionCodes), + append(RStackCodes, [32, 46, 32|ExpressionCodes], Codes). + + +frump(Stack, Expression) :- + format_state(Stack, Expression, Codes), + maplist(put_code, Codes), nl. + +% do(In) :- phrase(format_stack(In), Codes), maplist(put_code, Codes). + +% Print Joy expressions as text. + +format_stack(Tail) --> {var(Tail)}, !, [46, 46, 46]. +format_stack([T]) --> format_term(T), !. +format_stack([T|S]) --> format_term(T), " ", format_stack(S). +format_stack([]) --> []. + +format_term(N) --> {number(N), number_codes(N, Codes)}, Codes. +format_term(A) --> { atom(A), atom_codes(A, Codes)}, Codes. +format_term([A|As]) --> "[", format_stack([A|As]), "]". + + + /* [debug] ?- tmi(thun([1, 2, swap], Si, So)). From a3f863ff186e22941edfb9eb20ba807ae7c24366 Mon Sep 17 00:00:00 2001 From: Simon Forman Date: Sat, 3 Aug 2019 19:02:24 -0700 Subject: [PATCH 5/8] Move is_numerical() to joy.gui.utils. --- joy/gui/textwidget.py | 3 ++- joy/gui/utils.py | 8 ++++++++ joy/gui/world.py | 10 +--------- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/joy/gui/textwidget.py b/joy/gui/textwidget.py index 9eea55b..08c1734 100644 --- a/joy/gui/textwidget.py +++ b/joy/gui/textwidget.py @@ -49,7 +49,8 @@ import os, sys from joy.utils.stack import stack_to_string from .mousebindings import MouseBindingsMixin -from .world import World, is_numerical +from .utils import is_numerical +from .world import World def make_gui(dictionary): diff --git a/joy/gui/utils.py b/joy/gui/utils.py index 3b7abfa..e187d12 100644 --- a/joy/gui/utils.py +++ b/joy/gui/utils.py @@ -10,6 +10,14 @@ COMMITTER = 'Joy ' DEFAULT_JOY_HOME = expanduser(join('~', '.joypy')) +def is_numerical(s): + try: + float(s) + except ValueError: + return False + return True + + def home_dir(path): '''Return the absolute path of an existing directory.''' diff --git a/joy/gui/world.py b/joy/gui/world.py index 4fe4514..14c8dac 100644 --- a/joy/gui/world.py +++ b/joy/gui/world.py @@ -28,14 +28,7 @@ from joy.joy import run from joy.parser import Symbol from joy.utils.stack import stack_to_string from joy.utils.types import type_check - - -def is_numerical(s): - try: - float(s) - except ValueError: - return False - return True +from .utils import is_numerical class World(object): @@ -121,7 +114,6 @@ class World(object): class StackDisplayWorld(World): - def __init__(self, repo, filename, rel_filename, dictionary=None, text_widget=None): self.filename = filename stack = self.load_stack() or () From 0048ee212d96e2c6b359c6a59a91d348a6dbca74 Mon Sep 17 00:00:00 2001 From: Simon Forman Date: Sun, 4 Aug 2019 09:28:01 -0700 Subject: [PATCH 6/8] loop combinator handles ambiguity. remove some old notes. --- thun/thun.pl | 32 +++++++------------------------- 1 file changed, 7 insertions(+), 25 deletions(-) diff --git a/thun/thun.pl b/thun/thun.pl index 9b4d4e9..7f6dbc0 100644 --- a/thun/thun.pl +++ b/thun/thun.pl @@ -223,6 +223,13 @@ combo(branch, [T, F, Expr|S], S, Ei, Eo) :- combo(loop, [_, false|S], S, E, E ). combo(loop, [B, true|S], S, Ei, Eo) :- append(B, [B, loop|Ei], Eo). +combo(loop, [B, Expr|S], S, Ei, Eo) :- + \+ Expr = true, \+ Expr = false, + catch( % Try Expr and do one or the other, + (Expr -> append(B, [B, loop|Ei], Eo) ; Ei=Eo), + _, % If Expr don't grok, try both branches. + (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). @@ -309,28 +316,3 @@ to_fixed_point(DCG, Ei, Eo) :- grow(Ei, Eo) :- to_fixed_point(rebo(expando, grow ), Ei, Eo). shrink(Ei, Eo) :- to_fixed_point(rebo(contracto, shrink), Ei, Eo). - - -/* -?- E=[foo,bar,swap,cons,baz],phrase(shrink, E, ExprOut). -E = [foo, bar, swap, cons, baz], -ExprOut = [foo, bar, swons, baz]. - -?- E=[foo, bar, swons, baz],phrase(grow, E, ExprOut). -E = [foo, bar, swons, baz], -ExprOut = [foo, bar, swap, cons, baz]. - -*/ - - -% ... --> [] | [_], ... . - -% for the ellipsis operator -% http://swi-prolog.996271.n3.nabble.com/DCG-idioms-td3117.html which references: -% David B. Searls, Investigating the Linguistics of DNA with Definite Clause Grammars. NACLP 1989. - -% phrase(expando, ExprIn, ExprOut). - -% E=[foo,bar,swap,cons,baz],phrase((...,contracto,...), E, ExprOut). -% E = [foo, bar, swap, cons, baz], -% ExprOut = [swons, baz] \ No newline at end of file From 4ea77cf1beb0b7cdca4c21503e9fb33cfcb727a0 Mon Sep 17 00:00:00 2001 From: Simon Forman Date: Wed, 7 Aug 2019 11:40:49 -0700 Subject: [PATCH 7/8] Integer DCGs that work in both directions. --- thun/thun.pl | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/thun/thun.pl b/thun/thun.pl index 7f6dbc0..ba8b483 100644 --- a/thun/thun.pl +++ b/thun/thun.pl @@ -220,7 +220,6 @@ combo(branch, [T, F, Expr|S], S, Ei, Eo) :- (append(T, 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(loop, [B, Expr|S], S, Ei, Eo) :- @@ -316,3 +315,14 @@ to_fixed_point(DCG, Ei, Eo) :- grow(Ei, Eo) :- to_fixed_point(rebo(expando, grow ), Ei, Eo). shrink(Ei, Eo) :- to_fixed_point(rebo(contracto, shrink), Ei, Eo). + + +% format_n(N) --> {number(N), !, number_codes(N, Codes)}, Codes. +% format_n(N) --> signed_digits(Codes), !, {number_codes(N, Codes)}. + +% signed_digits([45|Codes]) --> [45], !, digits(Codes). +% signed_digits( Codes ) --> digits(Codes). + +% digits([Ch|Chars]) --> [Ch], {code_type(Ch, digit)}, digits(Chars). +% digits([]), [Ch] --> [Ch], {code_type(Ch, space) ; Ch=0'] }. +% digits([], [], _). % Match if followed by space, ], or nothing. From 976b8302be087d3ef7e196b1887d7b812000b3df Mon Sep 17 00:00:00 2001 From: Simon Forman Date: Wed, 7 Aug 2019 23:28:28 -0700 Subject: [PATCH 8/8] grow/shrink as DCGs. --- thun/thun.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/thun/thun.pl b/thun/thun.pl index ba8b483..4cc91f9 100644 --- a/thun/thun.pl +++ b/thun/thun.pl @@ -313,8 +313,8 @@ to_fixed_point(DCG, Ei, Eo) :- phrase(DCG, Ei, E), % Apply DCG... (Ei=E -> Eo=E ; to_fixed_point(DCG, E, Eo)). % ...until a fixed-point is reached. -grow(Ei, Eo) :- to_fixed_point(rebo(expando, grow ), Ei, Eo). -shrink(Ei, Eo) :- to_fixed_point(rebo(contracto, shrink), Ei, Eo). +grow --> to_fixed_point(rebo(expando, grow )). +shrink --> to_fixed_point(rebo(contracto, shrink)). % format_n(N) --> {number(N), !, number_codes(N, Codes)}, Codes.