cond
This commit is contained in:
@@ -75,99 +75,6 @@ S_times = Symbol('times')
|
||||
# return (q, (p, stack)), expression, dictionary
|
||||
|
||||
|
||||
@inscribe
|
||||
@FunctionWrapper
|
||||
def branch(stack, expression, dictionary):
|
||||
'''
|
||||
Use a Boolean value to select one of two quoted programs to run.
|
||||
|
||||
::
|
||||
|
||||
branch == roll< choice i
|
||||
|
||||
::
|
||||
|
||||
False [F] [T] branch
|
||||
--------------------------
|
||||
F
|
||||
|
||||
True [F] [T] branch
|
||||
-------------------------
|
||||
T
|
||||
|
||||
'''
|
||||
(then, (else_, (flag, stack))) = stack
|
||||
return stack, concat(then if flag else else_, expression), dictionary
|
||||
|
||||
|
||||
@inscribe
|
||||
@FunctionWrapper
|
||||
def ifte(stack, expression, dictionary):
|
||||
'''
|
||||
If-Then-Else Combinator
|
||||
::
|
||||
|
||||
... [if] [then] [else] ifte
|
||||
---------------------------------------------------
|
||||
... [[else] [then]] [...] [if] infra select i
|
||||
|
||||
|
||||
|
||||
|
||||
... [if] [then] [else] ifte
|
||||
-------------------------------------------------------
|
||||
... [else] [then] [...] [if] infra first choice i
|
||||
|
||||
|
||||
Has the effect of grabbing a copy of the stack on which to run the
|
||||
if-part using infra.
|
||||
'''
|
||||
(else_, (then, (if_, stack))) = stack
|
||||
expression = (S_infra, (S_first, (S_choice, (S_i, expression))))
|
||||
stack = (if_, (stack, (then, (else_, stack))))
|
||||
return stack, expression, dictionary
|
||||
|
||||
|
||||
@inscribe
|
||||
@FunctionWrapper
|
||||
def cond(stack, expression, dictionary):
|
||||
'''
|
||||
This combinator works like a case statement. It expects a single quote
|
||||
on the stack that must contain zero or more condition quotes and a
|
||||
default quote. Each condition clause should contain a quoted predicate
|
||||
followed by the function expression to run if that predicate returns
|
||||
true. If no predicates return true the default function runs.
|
||||
|
||||
It works by rewriting into a chain of nested `ifte` expressions, e.g.::
|
||||
|
||||
[[[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):
|
||||
|
||||
Reference in New Issue
Block a user