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 a83657f..e187d12 100644 --- a/joy/gui/utils.py +++ b/joy/gui/utils.py @@ -7,7 +7,15 @@ from dulwich.repo import Repo COMMITTER = 'Joy ' -DEFAULT_JOY_HOME = '~/.joypy' +DEFAULT_JOY_HOME = expanduser(join('~', '.joypy')) + + +def is_numerical(s): + try: + float(s) + except ValueError: + return False + return True def home_dir(path): 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 () 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)). diff --git a/thun/thun.pl b/thun/thun.pl index fe7b7fe..262f3e0 100644 --- a/thun/thun.pl +++ b/thun/thun.pl @@ -236,6 +236,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). @@ -310,5 +317,31 @@ sjc(Name, InputString) :- phrase(joy_parse(E), InputString), show_joy_compile(Na expando, Body --> [Def], {def(Def, Body)}. contracto, [Def] --> {def(Def, Body)}, Body. -% phrase(expando, ExprIn, ExprOut). +% 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, "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(_, _) --> []. + +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 --> to_fixed_point(rebo(expando, grow )). +shrink --> to_fixed_point(rebo(contracto, shrink)). + + +% 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.