From: Simon Forman Date: Wed, 6 Jun 2018 14:56:24 +0000 (-0700) Subject: Added cond and cmp to library. X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=37c34fc54f09b7375b4da5e83aa8eef2ab6bef18;p=joypy%2FThun.git Added cond and cmp to library. --- diff --git a/joy/library.py b/joy/library.py index 1797697..98f44d8 100644 --- a/joy/library.py +++ b/joy/library.py @@ -1142,6 +1142,43 @@ def ifte(stack, expression, dictionary): @inscribe @FunctionWrapper +def cond(stack, expression, dictionary): + ''' + like a case statement; works by rewriting into a chain of ifte. + + [..[[Bi] Ti]..[D]] -> ... + + + [[[B0] T0] [[B1] T1] [D]] cond + ----------------------------------------- + [B0] [T0] [[B1] [T1] [D] ifte] ifte + + ''' + conditions, stack = stack + if conditions: + expression = _cond(conditions, expression) + try: + # Attempt to preload the args to first ifte. + (P, (T, (E, expression))) = expression + except ValueError: + # If, for any reason, the argument to cond should happen to contain + # only the default clause then this optimization will fail. + pass + else: + stack = (E, (T, (P, stack))) + return stack, expression, dictionary + + +def _cond(conditions, expression): + (clause, rest) = conditions + if not rest: # clause is [D] + return clause + P, T = clause + return (P, (T, (_cond(rest, ()), (S_ifte, expression)))) + + +@inscribe +@FunctionWrapper def dip(stack, expression, dictionary): ''' The dip combinator expects a quoted program on the stack and below it @@ -1360,6 +1397,30 @@ def loop(stack, expression, dictionary): return stack, expression, dictionary +@inscribe +@FunctionWrapper +def cmp_(stack, expression, dictionary): + ''' + cmp takes two values and three quoted programs on the stack and runs + one of the three depending on the results of comparing the two values: + + a b [G] [E] [L] cmp + ------------------------- a > b + G + + a b [G] [E] [L] cmp + ------------------------- a = b + E + + a b [G] [E] [L] cmp + ------------------------- a < b + L + ''' + L, (E, (G, (b, (a, stack)))) = stack + expression = pushback(G if a > b else L if a < b else E, expression) + return stack, expression, dictionary + + #def nullary(S, expression, dictionary): # ''' # Run the program on TOS and return its first result without consuming