dipd, dipdd, cmp
This commit is contained in:
parent
f640f437f1
commit
8778f12b68
|
|
@ -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))
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue