From 8778f12b682574802bcf3468cd3d3eb0060684e1 Mon Sep 17 00:00:00 2001 From: Simon Forman Date: Mon, 12 Sep 2022 15:17:32 -0700 Subject: [PATCH] dipd, dipdd, cmp --- implementations/Python/joy/library.py | 121 -------------------------- implementations/Python/simplejoy.py | 66 +++++++++++++- 2 files changed, 65 insertions(+), 122 deletions(-) diff --git a/implementations/Python/joy/library.py b/implementations/Python/joy/library.py index 2c9d0f9..de7aa3e 100644 --- a/implementations/Python/joy/library.py +++ b/implementations/Python/joy/library.py @@ -75,62 +75,6 @@ S_times = Symbol('times') # return (q, (p, stack)), expression, dictionary -@inscribe -@FunctionWrapper -def dip(stack, expression, dictionary): - ''' - The dip combinator expects a quoted program on the stack and below it - some item, it hoists the item into the expression and runs the program - on the rest of the stack. - :: - - ... x [Q] dip - ------------------- - ... Q x - - ''' - try: - (quote, (x, stack)) = stack - except ValueError: - raise StackUnderflowError('Not enough values on stack.') - expression = (x, expression) - return stack, concat(quote, expression), dictionary - - -@inscribe -@FunctionWrapper -def dipd(S, expression, dictionary): - ''' - Like dip but expects two items. - :: - - ... y x [Q] dip - --------------------- - ... Q y x - - ''' - (quote, (x, (y, stack))) = S - expression = (y, (x, expression)) - return stack, concat(quote, expression), dictionary - - -@inscribe -@FunctionWrapper -def dipdd(S, expression, dictionary): - ''' - Like dip but expects three items. - :: - - ... z y x [Q] dip - ----------------------- - ... Q z y x - - ''' - (quote, (x, (y, (z, stack)))) = S - expression = (z, (y, (x, expression))) - return stack, concat(quote, expression), dictionary - - @inscribe @FunctionWrapper def app1(S, expression, dictionary): @@ -277,68 +221,3 @@ def times(stack, expression, dictionary): # return stack, expression, dictionary -@inscribe -@FunctionWrapper -def loop(stack, expression, dictionary): - ''' - Basic loop combinator. - :: - - ... True [Q] loop - ----------------------- - ... Q [Q] loop - - ... False [Q] loop - ------------------------ - ... - - ''' - try: - quote, stack = stack - except ValueError: - raise StackUnderflowError('Not enough values on stack.') - if not isinstance(quote, tuple): - raise NotAListError('Loop body not a list.') - try: - (flag, stack) = stack - except ValueError: - raise StackUnderflowError('Not enough values on stack.') - if flag: - expression = concat(quote, (quote, (S_loop, expression))) - 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 = concat(G if a > b else L if a < b else E, expression) - return stack, expression, dictionary - - -# FunctionWrapper(cleave), -# FunctionWrapper(while_), - - - -for name, primitive in getmembers(genlib, isfunction): - inscribe(SimpleFunctionWrapper(primitive)) - - diff --git a/implementations/Python/simplejoy.py b/implementations/Python/simplejoy.py index 79c4015..d796a66 100755 --- a/implementations/Python/simplejoy.py +++ b/implementations/Python/simplejoy.py @@ -2046,7 +2046,7 @@ def cond(stack, expr, dictionary): It works by rewriting into a chain of nested `ifte` expressions, e.g.:: [[D]] cond - ---------------- (Kind of pointless) + ---------------- D [[[IF] THEN] [D]] cond @@ -2058,6 +2058,7 @@ def cond(stack, expr, dictionary): ----------------------------------- (multiple conditions) [IF] [THEN] [[...] cond] ifte + The middle case isn't actually implemented. It's implied by the base case and the "multiple conditions" case. ''' @@ -2081,6 +2082,69 @@ def cond(stack, expr, dictionary): return stack, expr, dictionary +@inscribe +def dipd(stack, expr, dictionary): + ''' + The dipd combinator is like dip but expects two items. + + ... y x [Q] dipd + ---------------------- + ... Q y x + + ''' + quote, x, y, stack = get_n_items(3, stack) + isnt_stack(quote) + expr = push_quote((y, (x, ())), expr) + expr = push_quote(quote, expr) + return stack, expr, dictionary + + +@inscribe +def dipdd(stack, expr, dictionary): + ''' + The dipdd combinator is like dip but expects three items. + + ... y x z [Q] dipdd + ------------------------- + ... Q y x z + + ''' + quote, x, y, z, stack = get_n_items(3, stack) + isnt_stack(quote) + expr = push_quote((z, (y, (x, ()))), expr) + expr = push_quote(quote, expr) + return stack, expr, dictionary + + +@inscribe +def cmp_(stack, expr, 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 = get_n_items(5, stack) + isnt_stack(L) + isnt_stack(E) + isnt_stack(G) + isnt_int(b) + isnt_int(a) + expr = push_quote(G if a > b else L if a < b else E, expr) + return stack, expr, dictionary + + if __name__ == '__main__': import sys