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
|
# 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
|
@inscribe
|
||||||
@FunctionWrapper
|
@FunctionWrapper
|
||||||
def app1(S, expression, dictionary):
|
def app1(S, expression, dictionary):
|
||||||
|
|
@ -277,68 +221,3 @@ def times(stack, expression, dictionary):
|
||||||
# return 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.::
|
It works by rewriting into a chain of nested `ifte` expressions, e.g.::
|
||||||
|
|
||||||
[[D]] cond
|
[[D]] cond
|
||||||
---------------- (Kind of pointless)
|
----------------
|
||||||
D
|
D
|
||||||
|
|
||||||
[[[IF] THEN] [D]] cond
|
[[[IF] THEN] [D]] cond
|
||||||
|
|
@ -2058,6 +2058,7 @@ def cond(stack, expr, dictionary):
|
||||||
----------------------------------- (multiple conditions)
|
----------------------------------- (multiple conditions)
|
||||||
[IF] [THEN] [[...] cond] ifte
|
[IF] [THEN] [[...] cond] ifte
|
||||||
|
|
||||||
|
|
||||||
The middle case isn't actually implemented. It's implied by the
|
The middle case isn't actually implemented. It's implied by the
|
||||||
base case and the "multiple conditions" case.
|
base case and the "multiple conditions" case.
|
||||||
'''
|
'''
|
||||||
|
|
@ -2081,6 +2082,69 @@ def cond(stack, expr, dictionary):
|
||||||
return 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__':
|
if __name__ == '__main__':
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue