diff --git a/docs/sphinx_docs/_build/doctrees/environment.pickle b/docs/sphinx_docs/_build/doctrees/environment.pickle new file mode 100644 index 0000000..e9c9592 Binary files /dev/null and b/docs/sphinx_docs/_build/doctrees/environment.pickle differ diff --git a/docs/sphinx_docs/_build/doctrees/index.doctree b/docs/sphinx_docs/_build/doctrees/index.doctree new file mode 100644 index 0000000..d7f0037 Binary files /dev/null and b/docs/sphinx_docs/_build/doctrees/index.doctree differ diff --git a/docs/sphinx_docs/_build/doctrees/joy.doctree b/docs/sphinx_docs/_build/doctrees/joy.doctree new file mode 100644 index 0000000..1511b25 Binary files /dev/null and b/docs/sphinx_docs/_build/doctrees/joy.doctree differ diff --git a/docs/sphinx_docs/_build/doctrees/lib.doctree b/docs/sphinx_docs/_build/doctrees/lib.doctree new file mode 100644 index 0000000..681efe5 Binary files /dev/null and b/docs/sphinx_docs/_build/doctrees/lib.doctree differ diff --git a/docs/sphinx_docs/_build/doctrees/library.doctree b/docs/sphinx_docs/_build/doctrees/library.doctree new file mode 100644 index 0000000..cf28142 Binary files /dev/null and b/docs/sphinx_docs/_build/doctrees/library.doctree differ diff --git a/docs/sphinx_docs/_build/doctrees/notebooks/Categorical.doctree b/docs/sphinx_docs/_build/doctrees/notebooks/Categorical.doctree new file mode 100644 index 0000000..c6dc0a7 Binary files /dev/null and b/docs/sphinx_docs/_build/doctrees/notebooks/Categorical.doctree differ diff --git a/docs/sphinx_docs/_build/doctrees/notebooks/Derivatives_of_Regular_Expressions.doctree b/docs/sphinx_docs/_build/doctrees/notebooks/Derivatives_of_Regular_Expressions.doctree new file mode 100644 index 0000000..1e6f455 Binary files /dev/null and b/docs/sphinx_docs/_build/doctrees/notebooks/Derivatives_of_Regular_Expressions.doctree differ diff --git a/docs/sphinx_docs/_build/doctrees/notebooks/Developing.doctree b/docs/sphinx_docs/_build/doctrees/notebooks/Developing.doctree new file mode 100644 index 0000000..c628a79 Binary files /dev/null and b/docs/sphinx_docs/_build/doctrees/notebooks/Developing.doctree differ diff --git a/docs/sphinx_docs/_build/doctrees/notebooks/Generator_Programs.doctree b/docs/sphinx_docs/_build/doctrees/notebooks/Generator_Programs.doctree new file mode 100644 index 0000000..ccb3948 Binary files /dev/null and b/docs/sphinx_docs/_build/doctrees/notebooks/Generator_Programs.doctree differ diff --git a/docs/sphinx_docs/_build/doctrees/notebooks/Intro.doctree b/docs/sphinx_docs/_build/doctrees/notebooks/Intro.doctree new file mode 100644 index 0000000..005112d Binary files /dev/null and b/docs/sphinx_docs/_build/doctrees/notebooks/Intro.doctree differ diff --git a/docs/sphinx_docs/_build/doctrees/notebooks/Newton-Raphson.doctree b/docs/sphinx_docs/_build/doctrees/notebooks/Newton-Raphson.doctree new file mode 100644 index 0000000..4a86f59 Binary files /dev/null and b/docs/sphinx_docs/_build/doctrees/notebooks/Newton-Raphson.doctree differ diff --git a/docs/sphinx_docs/_build/doctrees/notebooks/NoUpdates.doctree b/docs/sphinx_docs/_build/doctrees/notebooks/NoUpdates.doctree new file mode 100644 index 0000000..53ec006 Binary files /dev/null and b/docs/sphinx_docs/_build/doctrees/notebooks/NoUpdates.doctree differ diff --git a/docs/sphinx_docs/_build/doctrees/notebooks/Ordered_Binary_Trees.doctree b/docs/sphinx_docs/_build/doctrees/notebooks/Ordered_Binary_Trees.doctree new file mode 100644 index 0000000..67405fe Binary files /dev/null and b/docs/sphinx_docs/_build/doctrees/notebooks/Ordered_Binary_Trees.doctree differ diff --git a/docs/sphinx_docs/_build/doctrees/notebooks/Quadratic.doctree b/docs/sphinx_docs/_build/doctrees/notebooks/Quadratic.doctree new file mode 100644 index 0000000..9506af3 Binary files /dev/null and b/docs/sphinx_docs/_build/doctrees/notebooks/Quadratic.doctree differ diff --git a/docs/sphinx_docs/_build/doctrees/notebooks/Recursion_Combinators.doctree b/docs/sphinx_docs/_build/doctrees/notebooks/Recursion_Combinators.doctree new file mode 100644 index 0000000..fd0934b Binary files /dev/null and b/docs/sphinx_docs/_build/doctrees/notebooks/Recursion_Combinators.doctree differ diff --git a/docs/sphinx_docs/_build/doctrees/notebooks/Replacing.doctree b/docs/sphinx_docs/_build/doctrees/notebooks/Replacing.doctree new file mode 100644 index 0000000..2ad1055 Binary files /dev/null and b/docs/sphinx_docs/_build/doctrees/notebooks/Replacing.doctree differ diff --git a/docs/sphinx_docs/_build/doctrees/notebooks/The_Four_Operations.doctree b/docs/sphinx_docs/_build/doctrees/notebooks/The_Four_Operations.doctree new file mode 100644 index 0000000..00fd5d3 Binary files /dev/null and b/docs/sphinx_docs/_build/doctrees/notebooks/The_Four_Operations.doctree differ diff --git a/docs/sphinx_docs/_build/doctrees/notebooks/Treestep.doctree b/docs/sphinx_docs/_build/doctrees/notebooks/Treestep.doctree new file mode 100644 index 0000000..91f5241 Binary files /dev/null and b/docs/sphinx_docs/_build/doctrees/notebooks/Treestep.doctree differ diff --git a/docs/sphinx_docs/_build/doctrees/notebooks/TypeChecking.doctree b/docs/sphinx_docs/_build/doctrees/notebooks/TypeChecking.doctree new file mode 100644 index 0000000..ad9a5c1 Binary files /dev/null and b/docs/sphinx_docs/_build/doctrees/notebooks/TypeChecking.doctree differ diff --git a/docs/sphinx_docs/_build/doctrees/notebooks/Types.doctree b/docs/sphinx_docs/_build/doctrees/notebooks/Types.doctree new file mode 100644 index 0000000..9ba07c8 Binary files /dev/null and b/docs/sphinx_docs/_build/doctrees/notebooks/Types.doctree differ diff --git a/docs/sphinx_docs/_build/doctrees/notebooks/Zipper.doctree b/docs/sphinx_docs/_build/doctrees/notebooks/Zipper.doctree new file mode 100644 index 0000000..22f043b Binary files /dev/null and b/docs/sphinx_docs/_build/doctrees/notebooks/Zipper.doctree differ diff --git a/docs/sphinx_docs/_build/doctrees/notebooks/index.doctree b/docs/sphinx_docs/_build/doctrees/notebooks/index.doctree new file mode 100644 index 0000000..d8c2f71 Binary files /dev/null and b/docs/sphinx_docs/_build/doctrees/notebooks/index.doctree differ diff --git a/docs/sphinx_docs/_build/doctrees/parser.doctree b/docs/sphinx_docs/_build/doctrees/parser.doctree new file mode 100644 index 0000000..1e0b37e Binary files /dev/null and b/docs/sphinx_docs/_build/doctrees/parser.doctree differ diff --git a/docs/sphinx_docs/_build/doctrees/pretty.doctree b/docs/sphinx_docs/_build/doctrees/pretty.doctree new file mode 100644 index 0000000..49a54bd Binary files /dev/null and b/docs/sphinx_docs/_build/doctrees/pretty.doctree differ diff --git a/docs/sphinx_docs/_build/doctrees/stack.doctree b/docs/sphinx_docs/_build/doctrees/stack.doctree new file mode 100644 index 0000000..c54b1d9 Binary files /dev/null and b/docs/sphinx_docs/_build/doctrees/stack.doctree differ diff --git a/docs/sphinx_docs/_build/doctrees/types.doctree b/docs/sphinx_docs/_build/doctrees/types.doctree new file mode 100644 index 0000000..b207837 Binary files /dev/null and b/docs/sphinx_docs/_build/doctrees/types.doctree differ diff --git a/docs/sphinx_docs/_build/html/.buildinfo b/docs/sphinx_docs/_build/html/.buildinfo new file mode 100644 index 0000000..73c8c3e --- /dev/null +++ b/docs/sphinx_docs/_build/html/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: d581c6009ec2b560e43b1edcc2912d38 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/sphinx_docs/_build/html/_images/omg.svg b/docs/sphinx_docs/_build/html/_images/omg.svg new file mode 100644 index 0000000..a3be69c --- /dev/null +++ b/docs/sphinx_docs/_build/html/_images/omg.svg @@ -0,0 +1,185 @@ + + + + + + +finite_state_machine + + +i + + +i + + +i->i + + +0 + + +j + +j + + +i->j + + +1 + + +h + + +h + + +h->i + + +0 + + +h->h + + +1 + + +a + +a + + +b + +b + + +a->b + + +0 + + +c + +c + + +a->c + + +1 + + +b->b + + +0 + + +d + +d + + +b->d + + +1 + + +c->b + + +0 + + +e + +e + + +c->e + + +1 + + +d->b + + +0 + + +f + +f + + +d->f + + +1 + + +e->b + + +0 + + +g + +g + + +e->g + + +1 + + +f->h + + +1 + + +f->b + + +0 + + +g->i + + +0 + + +g->g + + +1 + + +j->i + + +0 + + +j->h + + +1 + + + diff --git a/docs/sphinx_docs/_build/html/_modules/index.html b/docs/sphinx_docs/_build/html/_modules/index.html index 60816bb..a09f508 100644 --- a/docs/sphinx_docs/_build/html/_modules/index.html +++ b/docs/sphinx_docs/_build/html/_modules/index.html @@ -1,19 +1,17 @@ - + - + - - + + Overview: module code — Thun 0.4.1 documentation - - - - - - - + + + + + + @@ -28,24 +26,48 @@
[docs]def UnaryBuiltinWrapper(f): - ''' - Wrap functions that take one argument and return a single result. - ''' - @FunctionWrapper - @wraps(f) - def inner(stack, expression, dictionary): - (a, stack) = stack - result = f(a) - return (result, stack), expression, dictionary - return inner
+ ''' + Wrap functions that take one argument and return a single result. + ''' + @FunctionWrapper + @wraps(f) + def inner(stack, expression, dictionary): + (a, stack) = stack + result = f(a) + return (result, stack), expression, dictionary + return inner
[docs]class DefinitionWrapper(object): - ''' - Provide implementation of defined functions, and some helper methods. - ''' + ''' + Provide implementation of defined functions, and some helper methods. + ''' - def __init__(self, name, body_text, doc=None): - self.name = self.__name__ = name - self.body = text_to_expression(body_text) - self._body = tuple(iter_stack(self.body)) - self.__doc__ = doc or body_text - self._compiled = None + def __init__(self, name, body_text, doc=None): + self.name = self.__name__ = name + self.body = text_to_expression(body_text) + self._body = tuple(iter_stack(self.body)) + self.__doc__ = doc or body_text + self._compiled = None - def __call__(self, stack, expression, dictionary): - if self._compiled: - return self._compiled(stack, expression, dictionary) # pylint: disable=E1102 - expression = list_to_stack(self._body, expression) - return stack, expression, dictionary + def __call__(self, stack, expression, dictionary): + if self._compiled: + return self._compiled(stack, expression, dictionary) # pylint: disable=E1102 + expression = list_to_stack(self._body, expression) + return stack, expression, dictionary -
[docs] @classmethod - def parse_definition(class_, defi): - ''' - Given some text describing a Joy function definition parse it and - return a DefinitionWrapper. - ''' - return class_(*(n.strip() for n in defi.split(None, 1)))
+
[docs] @classmethod + def parse_definition(class_, defi): + ''' + Given some text describing a Joy function definition parse it and + return a DefinitionWrapper. + ''' + # At some point I decided that the definitions file should NOT + # use '==' to separate the name from the body. But somehow the + # xerblin\gui\default_joy_home\definitions.txt file didn't get + # the memo. Nor did the load_definitions() method. + # So I think the simplest way forward at the moment will be to + # edit this function to expect '=='. -
[docs] @classmethod - def add_definitions(class_, defs, dictionary): - ''' - Scan multi-line string defs for definitions and add them to the - dictionary. - ''' - for definition in _text_to_defs(defs): - class_.add_def(definition, dictionary)
+ name, part, body = defi.partition('==') + if part: + return class_(name.strip(), body.strip()) + raise ValueError("No '==' in definition text %r" % (defi,))
-
[docs] @classmethod - def add_def(class_, definition, dictionary, fail_fails=False): - ''' - Add the definition to the dictionary. - ''' - F = class_.parse_definition(definition) - dictionary[F.name] = F
+ # return class_(*(n.strip() for n in defi.split(None, 1))) - @classmethod - def load_definitions(class_, filename, dictionary): - with open(filename) as f: - lines = [line for line in f if '==' in line] - for line in lines: - class_.add_def(line, dictionary)
+
[docs] @classmethod + def add_definitions(class_, defs, dictionary): + ''' + Scan multi-line string defs for definitions and add them to the + dictionary. + ''' + for definition in _text_to_defs(defs): + class_.add_def(definition, dictionary)
+ +
[docs] @classmethod + def add_def(class_, definition, dictionary, fail_fails=False): + ''' + Add the definition to the dictionary. + ''' + F = class_.parse_definition(definition) + dictionary[F.name] = F
+ + @classmethod + def load_definitions(class_, filename, dictionary): + with open(filename) as f: + lines = [line for line in f if '==' in line] + for line in lines: + class_.add_def(line, dictionary) def _text_to_defs(text): - return ( - line.strip() - for line in text.splitlines() - if line and not line.startswith('#') - ) + return ( + line.strip() + for line in text.splitlines() + if line + and not line.startswith('#') + and '==' in line + ) # @@ -334,356 +361,356 @@
[docs]@inscribe @FunctionWrapper def inscribe_(stack, expression, dictionary): - ''' - Create a new Joy function definition in the Joy dictionary. A - definition is given as a string with a name followed by a double - equal sign then one or more Joy functions, the body. for example: + ''' + Create a new Joy function definition in the Joy dictionary. A + definition is given as a string with a name followed by a double + equal sign then one or more Joy functions, the body. for example: - sqr == dup mul + sqr == dup mul - If you want the definition to persist over restarts, enter it into - the definitions.txt resource. - ''' - definition, stack = stack - DefinitionWrapper.add_def(definition, dictionary, fail_fails=True) - return stack, expression, dictionary
+ If you want the definition to persist over restarts, enter it into + the definitions.txt resource. + ''' + definition, stack = stack + DefinitionWrapper.add_def(definition, dictionary, fail_fails=True) + return stack, expression, dictionary
[docs]@inscribe @SimpleFunctionWrapper def parse(stack): - '''Parse the string on the stack to a Joy expression.''' - text, stack = stack - expression = text_to_expression(text) - return expression, stack
+ '''Parse the string on the stack to a Joy expression.''' + text, stack = stack + expression = text_to_expression(text) + return expression, stack # @inscribe # @SimpleFunctionWrapper # def infer_(stack): -# '''Attempt to infer the stack effect of a Joy expression.''' -# E, stack = stack -# effects = infer_expression(E) -# e = list_to_stack([(fi, (fo, ())) for fi, fo in effects]) -# return e, stack +# '''Attempt to infer the stack effect of a Joy expression.''' +# E, stack = stack +# effects = infer_expression(E) +# e = list_to_stack([(fi, (fo, ())) for fi, fo in effects]) +# return e, stack
[docs]@inscribe @SimpleFunctionWrapper def getitem(stack): - ''' - :: + ''' + :: - getitem == drop first + getitem == drop first - Expects an integer and a quote on the stack and returns the item at the - nth position in the quote counting from 0. - :: + Expects an integer and a quote on the stack and returns the item at the + nth position in the quote counting from 0. + :: - [a b c d] 0 getitem - ------------------------- - a + [a b c d] 0 getitem + ------------------------- + a - ''' - n, (Q, stack) = stack - return pick(Q, n), stack
+ ''' + n, (Q, stack) = stack + return pick(Q, n), stack
[docs]@inscribe @SimpleFunctionWrapper def drop(stack): - ''' - :: + ''' + :: - drop == [rest] times + drop == [rest] times - Expects an integer and a quote on the stack and returns the quote with - n items removed off the top. - :: + Expects an integer and a quote on the stack and returns the quote with + n items removed off the top. + :: - [a b c d] 2 drop - ---------------------- - [c d] + [a b c d] 2 drop + ---------------------- + [c d] - ''' - n, (Q, stack) = stack - while n > 0: - try: - _, Q = Q - except ValueError: - raise IndexError - n -= 1 - return Q, stack
+ ''' + n, (Q, stack) = stack + while n > 0: + try: + _, Q = Q + except ValueError: + raise IndexError + n -= 1 + return Q, stack
[docs]@inscribe @SimpleFunctionWrapper def take(stack): - ''' - Expects an integer and a quote on the stack and returns the quote with - just the top n items in reverse order (because that's easier and you can - use reverse if needed.) - :: + ''' + Expects an integer and a quote on the stack and returns the quote with + just the top n items in reverse order (because that's easier and you can + use reverse if needed.) + :: - [a b c d] 2 take - ---------------------- - [b a] + [a b c d] 2 take + ---------------------- + [b a] - ''' - n, (Q, stack) = stack - x = () - while n > 0: - try: - item, Q = Q - except ValueError: - raise IndexError - x = item, x - n -= 1 - return x, stack
+ ''' + n, (Q, stack) = stack + x = () + while n > 0: + try: + item, Q = Q + except ValueError: + raise IndexError + x = item, x + n -= 1 + return x, stack
[docs]@inscribe @SimpleFunctionWrapper def choice(stack): - ''' - Use a Boolean value to select one of two items. - :: + ''' + Use a Boolean value to select one of two items. + :: - A B False choice - ---------------------- - A + A B False choice + ---------------------- + A - A B True choice - --------------------- - B + A B True choice + --------------------- + B - Currently Python semantics are used to evaluate the "truthiness" of the - Boolean value (so empty string, zero, etc. are counted as false, etc.) - ''' - (if_, (then, (else_, stack))) = stack - return then if if_ else else_, stack
+ Currently Python semantics are used to evaluate the "truthiness" of the + Boolean value (so empty string, zero, etc. are counted as false, etc.) + ''' + (if_, (then, (else_, stack))) = stack + return then if if_ else else_, stack
[docs]@inscribe @SimpleFunctionWrapper def select(stack): - ''' - Use a Boolean value to select one of two items from a sequence. - :: + ''' + Use a Boolean value to select one of two items from a sequence. + :: - [A B] False select - ------------------------ - A + [A B] False select + ------------------------ + A - [A B] True select - ----------------------- - B + [A B] True select + ----------------------- + B - The sequence can contain more than two items but not fewer. - Currently Python semantics are used to evaluate the "truthiness" of the - Boolean value (so empty string, zero, etc. are counted as false, etc.) - ''' - (flag, (choices, stack)) = stack - (else_, (then, _)) = choices - return then if flag else else_, stack
+ The sequence can contain more than two items but not fewer. + Currently Python semantics are used to evaluate the "truthiness" of the + Boolean value (so empty string, zero, etc. are counted as false, etc.) + ''' + (flag, (choices, stack)) = stack + (else_, (then, _)) = choices + return then if flag else else_, stack
[docs]@inscribe @SimpleFunctionWrapper def max_(S): - '''Given a list find the maximum.''' - tos, stack = S - return max(iter_stack(tos)), stack
+ '''Given a list find the maximum.''' + tos, stack = S + return max(iter_stack(tos)), stack
[docs]@inscribe @SimpleFunctionWrapper def min_(S): - '''Given a list find the minimum.''' - tos, stack = S - return min(iter_stack(tos)), stack
+ '''Given a list find the minimum.''' + tos, stack = S + return min(iter_stack(tos)), stack
[docs]@inscribe @SimpleFunctionWrapper def sum_(S): - ''' - Given a quoted sequence of numbers return the sum. - :: + ''' + Given a quoted sequence of numbers return the sum. + :: - sum == 0 swap [+] step + sum == 0 swap [+] step - ''' - tos, stack = S - return sum(iter_stack(tos)), stack
+ ''' + tos, stack = S + return sum(iter_stack(tos)), stack
[docs]@inscribe @SimpleFunctionWrapper def remove(S): - ''' - Expects an item on the stack and a quote under it and removes that item - from the the quote. The item is only removed once. - :: + ''' + Expects an item on the stack and a quote under it and removes that item + from the the quote. The item is only removed once. + :: - [1 2 3 1] 1 remove - ------------------------ - [2 3 1] + [1 2 3 1] 1 remove + ------------------------ + [2 3 1] - ''' - (tos, (second, stack)) = S - l = list(iter_stack(second)) - l.remove(tos) - return list_to_stack(l), stack
+ ''' + (tos, (second, stack)) = S + l = list(iter_stack(second)) + l.remove(tos) + return list_to_stack(l), stack
[docs]@inscribe @SimpleFunctionWrapper def unique(S): - '''Given a list remove duplicate items.''' - tos, stack = S - I = list(iter_stack(tos)) - return list_to_stack(sorted(set(I), key=I.index)), stack
+ '''Given a list remove duplicate items.''' + tos, stack = S + I = list(iter_stack(tos)) + return list_to_stack(sorted(set(I), key=I.index)), stack
[docs]@inscribe @SimpleFunctionWrapper def sort_(S): - '''Given a list return it sorted.''' - tos, stack = S - return list_to_stack(sorted(iter_stack(tos))), stack
+ '''Given a list return it sorted.''' + tos, stack = S + return list_to_stack(sorted(iter_stack(tos))), stack
[docs]@inscribe @SimpleFunctionWrapper def clear(stack): - '''Clear everything from the stack. - :: + '''Clear everything from the stack. + :: - clear == stack [pop stack] loop + clear == stack [pop stack] loop - ... clear - --------------- + ... clear + --------------- - ''' - return ()
+ ''' + return ()
[docs]@inscribe @SimpleFunctionWrapper def disenstacken(stack): - ''' - The disenstacken operator expects a list on top of the stack and makes that - the stack discarding the rest of the stack. - ''' - return stack[0]
+ ''' + The disenstacken operator expects a list on top of the stack and makes that + the stack discarding the rest of the stack. + ''' + return stack[0]
[docs]@inscribe @SimpleFunctionWrapper def reverse(S): - ''' - Reverse the list on the top of the stack. - :: + ''' + Reverse the list on the top of the stack. + :: - reverse == [] swap shunt - ''' - (tos, stack) = S - res = () - for term in iter_stack(tos): - res = term, res - return res, stack
+ reverse == [] swap shunt + ''' + (tos, stack) = S + res = () + for term in iter_stack(tos): + res = term, res + return res, stack
[docs]@inscribe @SimpleFunctionWrapper def concat_(S): - ''' - Concatinate the two lists on the top of the stack. - :: + ''' + Concatinate the two lists on the top of the stack. + :: - [a b c] [d e f] concat - ---------------------------- - [a b c d e f] + [a b c] [d e f] concat + ---------------------------- + [a b c d e f] - ''' - (tos, (second, stack)) = S - return concat(second, tos), stack
+ ''' + (tos, (second, stack)) = S + return concat(second, tos), stack
[docs]@inscribe @SimpleFunctionWrapper def shunt(stack): - ''' - Like concat but reverses the top list into the second. - :: + ''' + Like concat but reverses the top list into the second. + :: - shunt == [swons] step == reverse swap concat + shunt == [swons] step == reverse swap concat - [a b c] [d e f] shunt - --------------------------- - [f e d a b c] + [a b c] [d e f] shunt + --------------------------- + [f e d a b c] - ''' - (tos, (second, stack)) = stack - while tos: - term, tos = tos - second = term, second - return second, stack
+ ''' + (tos, (second, stack)) = stack + while tos: + term, tos = tos + second = term, second + return second, stack
[docs]@inscribe @SimpleFunctionWrapper def zip_(S): - ''' - Replace the two lists on the top of the stack with a list of the pairs - from each list. The smallest list sets the length of the result list. - ''' - (tos, (second, stack)) = S - accumulator = [ - (a, (b, ())) - for a, b in zip(iter_stack(tos), iter_stack(second)) - ] - return list_to_stack(accumulator), stack
+ ''' + Replace the two lists on the top of the stack with a list of the pairs + from each list. The smallest list sets the length of the result list. + ''' + (tos, (second, stack)) = S + accumulator = [ + (a, (b, ())) + for a, b in zip(iter_stack(tos), iter_stack(second)) + ] + return list_to_stack(accumulator), stack
[docs]@inscribe @SimpleFunctionWrapper def succ(S): - '''Increment TOS.''' - (tos, stack) = S - return tos + 1, stack
+ '''Increment TOS.''' + (tos, stack) = S + return tos + 1, stack
[docs]@inscribe @SimpleFunctionWrapper def pred(S): - '''Decrement TOS.''' - (tos, stack) = S - return tos - 1, stack
+ '''Decrement TOS.''' + (tos, stack) = S + return tos - 1, stack
[docs]@inscribe @SimpleFunctionWrapper def pm(stack): - ''' - Plus or minus - :: + ''' + Plus or minus + :: - a b pm - ------------- - a+b a-b + a b pm + ------------- + a+b a-b - ''' - a, (b, stack) = stack - p, m, = b + a, b - a - return m, (p, stack)
+ ''' + a, (b, stack) = stack + p, m, = b + a, b - a + return m, (p, stack)
[docs]def floor(n): - return int(math.floor(n))
+ return int(math.floor(n)) floor.__doc__ = math.floor.__doc__ @@ -691,27 +718,27 @@
[docs]@inscribe @SimpleFunctionWrapper def divmod_(S): - ''' - divmod(x, y) -> (quotient, remainder) + ''' + divmod(x, y) -> (quotient, remainder) - Return the tuple (x//y, x%y). Invariant: div*y + mod == x. - ''' - a, (b, stack) = S - d, m = divmod(a, b) - return d, (m, stack)
+ Return the tuple (x//y, x%y). Invariant: div*y + mod == x. + ''' + a, (b, stack) = S + d, m = divmod(a, b) + return d, (m, stack)
[docs]def sqrt(a): - ''' - Return the square root of the number a. - Negative numbers return complex roots. - ''' - try: - r = math.sqrt(a) - except ValueError: - assert a < 0, repr(a) - r = math.sqrt(-a) * 1j - return r
+ ''' + Return the square root of the number a. + Negative numbers return complex roots. + ''' + try: + r = math.sqrt(a) + except ValueError: + assert a < 0, repr(a) + r = math.sqrt(-a) * 1j + return r #def execute(S): @@ -724,20 +751,20 @@
[docs]@inscribe @SimpleFunctionWrapper def id_(stack): - '''The identity function.''' - return stack
+ '''The identity function.''' + return stack
[docs]@inscribe @SimpleFunctionWrapper def void(stack): - '''True if the form on TOS is void otherwise False.''' - form, stack = stack - return _void(form), stack
+ '''True if the form on TOS is void otherwise False.''' + form, stack = stack + return _void(form), stack def _void(form): - return any(not _void(i) for i in iter_stack(form)) + return any(not _void(i) for i in iter_stack(form)) @@ -749,42 +776,42 @@
[docs]@inscribe @FunctionWrapper def words(stack, expression, dictionary): - '''Print all the words in alphabetical order.''' - print(' '.join(sorted(dictionary))) - return stack, expression, dictionary
+ '''Print all the words in alphabetical order.''' + print(' '.join(sorted(dictionary))) + return stack, expression, dictionary
[docs]@inscribe @FunctionWrapper def sharing(stack, expression, dictionary): - '''Print redistribution information.''' - print("You may convey verbatim copies of the Program's source code as" - ' you receive it, in any medium, provided that you conspicuously' - ' and appropriately publish on each copy an appropriate copyright' - ' notice; keep intact all notices stating that this License and' - ' any non-permissive terms added in accord with section 7 apply' - ' to the code; keep intact all notices of the absence of any' - ' warranty; and give all recipients a copy of this License along' - ' with the Program.' - ' You should have received a copy of the GNU General Public License' - ' along with Thun. If not see <http://www.gnu.org/licenses/>.') - return stack, expression, dictionary
+ '''Print redistribution information.''' + print("You may convey verbatim copies of the Program's source code as" + ' you receive it, in any medium, provided that you conspicuously' + ' and appropriately publish on each copy an appropriate copyright' + ' notice; keep intact all notices stating that this License and' + ' any non-permissive terms added in accord with section 7 apply' + ' to the code; keep intact all notices of the absence of any' + ' warranty; and give all recipients a copy of this License along' + ' with the Program.' + ' You should have received a copy of the GNU General Public License' + ' along with Thun. If not see <http://www.gnu.org/licenses/>.') + return stack, expression, dictionary
[docs]@inscribe @FunctionWrapper def warranty(stack, expression, dictionary): - '''Print warranty information.''' - print('THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY' - ' APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE' - ' COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM' - ' "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR' - ' IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES' - ' OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE' - ' ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS' - ' WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE' - ' COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.') - return stack, expression, dictionary
+ '''Print warranty information.''' + print('THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY' + ' APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE' + ' COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM' + ' "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR' + ' IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES' + ' OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE' + ' ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS' + ' WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE' + ' COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.') + return stack, expression, dictionary # def simple_manual(stack): @@ -809,11 +836,11 @@
[docs]@inscribe @FunctionWrapper def help_(S, expression, dictionary): - '''Accepts a quoted symbol on the top of the stack and prints its docs.''' - ((symbol, _), stack) = S - word = dictionary[symbol] - print(HELP_TEMPLATE % (symbol, getdoc(word), symbol)) - return stack, expression, dictionary
+ '''Accepts a quoted symbol on the top of the stack and prints its docs.''' + ((symbol, _), stack) = S + word = dictionary[symbol] + print(HELP_TEMPLATE % (symbol, getdoc(word), symbol)) + return stack, expression, dictionary # @@ -842,215 +869,218 @@
[docs]@inscribe @FunctionWrapper def i(stack, expression, dictionary): - ''' - The i combinator expects a quoted program on the stack and unpacks it - onto the pending expression for evaluation. - :: + ''' + The i combinator expects a quoted program on the stack and unpacks it + onto the pending expression for evaluation. + :: - [Q] i - ----------- - Q + [Q] i + ----------- + Q - ''' - quote, stack = stack - return stack, concat(quote, expression), dictionary
+ ''' + try: + quote, stack = stack + except ValueError: + raise StackUnderflowError('Not enough values on stack.') + return stack, concat(quote, expression), dictionary
[docs]@inscribe @FunctionWrapper def x(stack, expression, dictionary): - ''' - :: + ''' + :: - x == dup i + x == dup i - ... [Q] x = ... [Q] dup i - ... [Q] x = ... [Q] [Q] i - ... [Q] x = ... [Q] Q + ... [Q] x = ... [Q] dup i + ... [Q] x = ... [Q] [Q] i + ... [Q] x = ... [Q] Q - ''' - quote, _ = stack - return stack, concat(quote, expression), dictionary
+ ''' + quote, _ = stack + return stack, concat(quote, expression), dictionary
[docs]@inscribe @FunctionWrapper def b(stack, expression, dictionary): - ''' - :: + ''' + :: - b == [i] dip i + b == [i] dip i - ... [P] [Q] b == ... [P] i [Q] i - ... [P] [Q] b == ... P Q + ... [P] [Q] b == ... [P] i [Q] i + ... [P] [Q] b == ... P Q - ''' - q, (p, (stack)) = stack - return stack, concat(p, concat(q, expression)), dictionary
+ ''' + q, (p, (stack)) = stack + return stack, concat(p, concat(q, expression)), dictionary
[docs]@inscribe @FunctionWrapper def dupdip(stack, expression, dictionary): - ''' - :: + ''' + :: - [F] dupdip == dup [F] dip + [F] dupdip == dup [F] dip - ... a [F] dupdip - ... a dup [F] dip - ... a a [F] dip - ... a F a + ... a [F] dupdip + ... a dup [F] dip + ... a a [F] dip + ... a F a - ''' - F, stack = stack - a = stack[0] - return stack, concat(F, (a, expression)), dictionary
+ ''' + F, stack = stack + a = stack[0] + return stack, concat(F, (a, expression)), dictionary
[docs]@inscribe @FunctionWrapper def infra(stack, expression, dictionary): - ''' - Accept a quoted program and a list on the stack and run the program - with the list as its stack. Does not affect the rest of the stack. - :: + ''' + Accept a quoted program and a list on the stack and run the program + with the list as its stack. Does not affect the rest of the stack. + :: - ... [a b c] [Q] . infra - ----------------------------- - c b a . Q [...] swaack + ... [a b c] [Q] . infra + ----------------------------- + c b a . Q [...] swaack - ''' - (quote, (aggregate, stack)) = stack - return aggregate, concat(quote, (stack, (S_swaack, expression))), dictionary
+ ''' + (quote, (aggregate, stack)) = stack + return aggregate, concat(quote, (stack, (S_swaack, expression))), dictionary
[docs]@inscribe @FunctionWrapper def genrec(stack, expression, dictionary): - ''' - General Recursion Combinator. - :: + ''' + General Recursion Combinator. + :: - [if] [then] [rec1] [rec2] genrec - --------------------------------------------------------------------- - [if] [then] [rec1 [[if] [then] [rec1] [rec2] genrec] rec2] ifte + [if] [then] [rec1] [rec2] genrec + --------------------------------------------------------------------- + [if] [then] [rec1 [[if] [then] [rec1] [rec2] genrec] rec2] ifte - From "Recursion Theory and Joy" (j05cmp.html) by Manfred von Thun: - "The genrec combinator takes four program parameters in addition to - whatever data parameters it needs. Fourth from the top is an if-part, - followed by a then-part. If the if-part yields true, then the then-part - is executed and the combinator terminates. The other two parameters are - the rec1-part and the rec2-part. If the if-part yields false, the - rec1-part is executed. Following that the four program parameters and - the combinator are again pushed onto the stack bundled up in a quoted - form. Then the rec2-part is executed, where it will find the bundled - form. Typically it will then execute the bundled form, either with i or - with app2, or some other combinator." + From "Recursion Theory and Joy" (j05cmp.html) by Manfred von Thun: + "The genrec combinator takes four program parameters in addition to + whatever data parameters it needs. Fourth from the top is an if-part, + followed by a then-part. If the if-part yields true, then the then-part + is executed and the combinator terminates. The other two parameters are + the rec1-part and the rec2-part. If the if-part yields false, the + rec1-part is executed. Following that the four program parameters and + the combinator are again pushed onto the stack bundled up in a quoted + form. Then the rec2-part is executed, where it will find the bundled + form. Typically it will then execute the bundled form, either with i or + with app2, or some other combinator." - The way to design one of these is to fix your base case [then] and the - test [if], and then treat rec1 and rec2 as an else-part "sandwiching" - a quotation of the whole function. + The way to design one of these is to fix your base case [then] and the + test [if], and then treat rec1 and rec2 as an else-part "sandwiching" + a quotation of the whole function. - For example, given a (general recursive) function 'F': - :: + For example, given a (general recursive) function 'F': + :: - F == [I] [T] [R1] [R2] genrec + F == [I] [T] [R1] [R2] genrec - If the [I] if-part fails you must derive R1 and R2 from: - :: + If the [I] if-part fails you must derive R1 and R2 from: + :: - ... R1 [F] R2 + ... R1 [F] R2 - Just set the stack arguments in front, and figure out what R1 and R2 - have to do to apply the quoted [F] in the proper way. In effect, the - genrec combinator turns into an ifte combinator with a quoted copy of - the original definition in the else-part: - :: + Just set the stack arguments in front, and figure out what R1 and R2 + have to do to apply the quoted [F] in the proper way. In effect, the + genrec combinator turns into an ifte combinator with a quoted copy of + the original definition in the else-part: + :: - F == [I] [T] [R1] [R2] genrec - == [I] [T] [R1 [F] R2] ifte + F == [I] [T] [R1] [R2] genrec + == [I] [T] [R1 [F] R2] ifte - Primitive recursive functions are those where R2 == i. - :: + Primitive recursive functions are those where R2 == i. + :: - P == [I] [T] [R] tailrec - == [I] [T] [R [P] i] ifte - == [I] [T] [R P] ifte + P == [I] [T] [R] tailrec + == [I] [T] [R [P] i] ifte + == [I] [T] [R P] ifte - ''' - (rec2, (rec1, stack)) = stack - (then, (if_, _)) = stack - F = (if_, (then, (rec1, (rec2, (S_genrec, ()))))) - else_ = concat(rec1, (F, rec2)) - return (else_, stack), (S_ifte, expression), dictionary
+ ''' + (rec2, (rec1, stack)) = stack + (then, (if_, _)) = stack + F = (if_, (then, (rec1, (rec2, (S_genrec, ()))))) + else_ = concat(rec1, (F, rec2)) + return (else_, stack), (S_ifte, expression), dictionary
[docs]@inscribe @FunctionWrapper def map_(S, expression, dictionary): - ''' - Run the quoted program on TOS on the items in the list under it, push a - new list with the results in place of the program and original list. - ''' - # (quote, (aggregate, stack)) = S - # results = list_to_stack([ - # joy((term, stack), quote, dictionary)[0][0] - # for term in iter_stack(aggregate) - # ]) - # return (results, stack), expression, dictionary - (quote, (aggregate, stack)) = S - if not aggregate: - return (aggregate, stack), expression, dictionary - batch = () - for term in iter_stack(aggregate): - s = term, stack - batch = (s, (quote, (S_infra, (S_first, batch)))) - stack = (batch, ((), stack)) - return stack, (S_infra, expression), dictionary
+ ''' + Run the quoted program on TOS on the items in the list under it, push a + new list with the results in place of the program and original list. + ''' + # (quote, (aggregate, stack)) = S + # results = list_to_stack([ + # joy((term, stack), quote, dictionary)[0][0] + # for term in iter_stack(aggregate) + # ]) + # return (results, stack), expression, dictionary + (quote, (aggregate, stack)) = S + if not aggregate: + return (aggregate, stack), expression, dictionary + batch = () + for term in iter_stack(aggregate): + s = term, stack + batch = (s, (quote, (S_infra, (S_first, batch)))) + stack = (batch, ((), stack)) + return stack, (S_infra, expression), dictionary
[docs]@inscribe @FunctionWrapper def primrec(stack, expression, dictionary): - ''' - From the "Overview of the language JOY": + ''' + From the "Overview of the language JOY": - > The primrec combinator expects two quoted programs in addition to a - data parameter. For an integer data parameter it works like this: If - the data parameter is zero, then the first quotation has to produce - the value to be returned. If the data parameter is positive then the - second has to combine the data parameter with the result of applying - the function to its predecessor.:: + > The primrec combinator expects two quoted programs in addition to a + data parameter. For an integer data parameter it works like this: If + the data parameter is zero, then the first quotation has to produce + the value to be returned. If the data parameter is positive then the + second has to combine the data parameter with the result of applying + the function to its predecessor.:: - 5 [1] [*] primrec + 5 [1] [*] primrec - > Then primrec tests whether the top element on the stack (initially - the 5) is equal to zero. If it is, it pops it off and executes one of - the quotations, the [1] which leaves 1 on the stack as the result. - Otherwise it pushes a decremented copy of the top element and - recurses. On the way back from the recursion it uses the other - quotation, [*], to multiply what is now a factorial on top of the - stack by the second element on the stack.:: + > Then primrec tests whether the top element on the stack (initially + the 5) is equal to zero. If it is, it pops it off and executes one of + the quotations, the [1] which leaves 1 on the stack as the result. + Otherwise it pushes a decremented copy of the top element and + recurses. On the way back from the recursion it uses the other + quotation, [*], to multiply what is now a factorial on top of the + stack by the second element on the stack.:: - n [Base] [Recur] primrec + n [Base] [Recur] primrec - 0 [Base] [Recur] primrec - ------------------------------ - Base + 0 [Base] [Recur] primrec + ------------------------------ + Base - n [Base] [Recur] primrec - ------------------------------------------ n > 0 - n (n-1) [Base] [Recur] primrec Recur + n [Base] [Recur] primrec + ------------------------------------------ n > 0 + n (n-1) [Base] [Recur] primrec Recur - ''' - recur, (base, (n, stack)) = stack - if n <= 0: - expression = concat(base, expression) - else: - expression = S_primrec, concat(recur, expression) - stack = recur, (base, (n - 1, (n, stack))) - return stack, expression, dictionary
+ ''' + recur, (base, (n, stack)) = stack + if n <= 0: + expression = concat(base, expression) + else: + expression = S_primrec, concat(recur, expression) + stack = recur, (base, (n - 1, (n, stack))) + return stack, expression, dictionary #def cleave(S, expression, dictionary): @@ -1070,26 +1100,26 @@
[docs]@inscribe @FunctionWrapper def branch(stack, expression, dictionary): - ''' - Use a Boolean value to select one of two quoted programs to run. + ''' + Use a Boolean value to select one of two quoted programs to run. - :: + :: - branch == roll< choice i + branch == roll< choice i - :: + :: - False [F] [T] branch - -------------------------- - F + False [F] [T] branch + -------------------------- + F - True [F] [T] branch - ------------------------- - T + True [F] [T] branch + ------------------------- + T - ''' - (then, (else_, (flag, stack))) = stack - return stack, concat(then if flag else else_, expression), dictionary
+ ''' + (then, (else_, (flag, stack))) = stack + return stack, concat(then if flag else else_, expression), dictionary ##@inscribe @@ -1123,224 +1153,227 @@
[docs]@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. + ''' + 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.:: + 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 + [[[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
+ ''' + 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)))) + (clause, rest) = conditions + if not rest: # clause is [D] + return clause + P, T = clause + return (P, (T, (_cond(rest, ()), (S_ifte, expression))))
[docs]@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. - :: + ''' + 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 + ... x [Q] dip + ------------------- + ... Q x - ''' - (quote, (x, stack)) = stack - expression = (x, expression) - return stack, concat(quote, expression), dictionary
+ ''' + try: + (quote, (x, stack)) = stack + except ValueError: + raise StackUnderflowError('Not enough values on stack.') + expression = (x, expression) + return stack, concat(quote, expression), dictionary
[docs]@inscribe @FunctionWrapper def dipd(S, expression, dictionary): - ''' - Like dip but expects two items. - :: + ''' + Like dip but expects two items. + :: - ... y x [Q] dip - --------------------- - ... Q y x + ... y x [Q] dip + --------------------- + ... Q y x - ''' - (quote, (x, (y, stack))) = S - expression = (y, (x, expression)) - return stack, concat(quote, expression), dictionary
+ ''' + (quote, (x, (y, stack))) = S + expression = (y, (x, expression)) + return stack, concat(quote, expression), dictionary
[docs]@inscribe @FunctionWrapper def dipdd(S, expression, dictionary): - ''' - Like dip but expects three items. - :: + ''' + Like dip but expects three items. + :: - ... z y x [Q] dip - ----------------------- - ... Q z y x + ... 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
+ ''' + (quote, (x, (y, (z, stack)))) = S + expression = (z, (y, (x, expression))) + return stack, concat(quote, expression), dictionary
[docs]@inscribe @FunctionWrapper def app1(S, expression, dictionary): - ''' - Given a quoted program on TOS and anything as the second stack item run - the program and replace the two args with the first result of the - program. - :: + ''' + Given a quoted program on TOS and anything as the second stack item run + the program and replace the two args with the first result of the + program. + :: - ... x [Q] . app1 - ----------------------------------- - ... [x ...] [Q] . infra first + ... x [Q] . app1 + ----------------------------------- + ... [x ...] [Q] . infra first - ''' - (quote, (x, stack)) = S - stack = (quote, ((x, stack), stack)) - expression = (S_infra, (S_first, expression)) - return stack, expression, dictionary
+ ''' + (quote, (x, stack)) = S + stack = (quote, ((x, stack), stack)) + expression = (S_infra, (S_first, expression)) + return stack, expression, dictionary
[docs]@inscribe @FunctionWrapper def app2(S, expression, dictionary): - '''Like app1 with two items. - :: + '''Like app1 with two items. + :: - ... y x [Q] . app2 - ----------------------------------- - ... [y ...] [Q] . infra first - [x ...] [Q] infra first + ... y x [Q] . app2 + ----------------------------------- + ... [y ...] [Q] . infra first + [x ...] [Q] infra first - ''' - (quote, (x, (y, stack))) = S - expression = (S_infra, (S_first, - ((x, stack), (quote, (S_infra, (S_first, - expression)))))) - stack = (quote, ((y, stack), stack)) - return stack, expression, dictionary
+ ''' + (quote, (x, (y, stack))) = S + expression = (S_infra, (S_first, + ((x, stack), (quote, (S_infra, (S_first, + expression)))))) + stack = (quote, ((y, stack), stack)) + return stack, expression, dictionary
[docs]@inscribe @FunctionWrapper def app3(S, expression, dictionary): - '''Like app1 with three items. - :: + '''Like app1 with three items. + :: - ... z y x [Q] . app3 - ----------------------------------- - ... [z ...] [Q] . infra first - [y ...] [Q] infra first - [x ...] [Q] infra first + ... z y x [Q] . app3 + ----------------------------------- + ... [z ...] [Q] . infra first + [y ...] [Q] infra first + [x ...] [Q] infra first - ''' - (quote, (x, (y, (z, stack)))) = S - expression = (S_infra, (S_first, - ((y, stack), (quote, (S_infra, (S_first, - ((x, stack), (quote, (S_infra, (S_first, - expression)))))))))) - stack = (quote, ((z, stack), stack)) - return stack, expression, dictionary
+ ''' + (quote, (x, (y, (z, stack)))) = S + expression = (S_infra, (S_first, + ((y, stack), (quote, (S_infra, (S_first, + ((x, stack), (quote, (S_infra, (S_first, + expression)))))))))) + stack = (quote, ((z, stack), stack)) + return stack, expression, dictionary
[docs]@inscribe @FunctionWrapper def step(S, expression, dictionary): - ''' - Run a quoted program on each item in a sequence. - :: + ''' + Run a quoted program on each item in a sequence. + :: - ... [] [Q] . step - ----------------------- - ... . + ... [] [Q] . step + ----------------------- + ... . - ... [a] [Q] . step - ------------------------ - ... a . Q + ... [a] [Q] . step + ------------------------ + ... a . Q - ... [a b c] [Q] . step - ---------------------------------------- - ... a . Q [b c] [Q] step + ... [a b c] [Q] . step + ---------------------------------------- + ... a . Q [b c] [Q] step - The step combinator executes the quotation on each member of the list - on top of the stack. - ''' - (quote, (aggregate, stack)) = S - if not aggregate: - return stack, expression, dictionary - head, tail = aggregate - stack = quote, (head, stack) - if tail: - expression = tail, (quote, (S_step, expression)) - expression = S_i, expression - return stack, expression, dictionary
+ The step combinator executes the quotation on each member of the list + on top of the stack. + ''' + (quote, (aggregate, stack)) = S + if not aggregate: + return stack, expression, dictionary + head, tail = aggregate + stack = quote, (head, stack) + if tail: + expression = tail, (quote, (S_step, expression)) + expression = S_i, expression + return stack, expression, dictionary
[docs]@inscribe @FunctionWrapper def times(stack, expression, dictionary): - ''' - times == [-- dip] cons [swap] infra [0 >] swap while pop - :: + ''' + times == [-- dip] cons [swap] infra [0 >] swap while pop + :: - ... n [Q] . times - --------------------- w/ n <= 0 - ... . + ... n [Q] . times + --------------------- w/ n <= 0 + ... . - ... 1 [Q] . times - ----------------------- - ... . Q + ... 1 [Q] . times + ----------------------- + ... . Q - ... n [Q] . times - ------------------------------------- w/ n > 1 - ... . Q (n - 1) [Q] times + ... n [Q] . times + ------------------------------------- w/ n > 1 + ... . Q (n - 1) [Q] times - ''' - # times == [-- dip] cons [swap] infra [0 >] swap while pop - (quote, (n, stack)) = stack - if n <= 0: - return stack, expression, dictionary - n -= 1 - if n: - expression = n, (quote, (S_times, expression)) - expression = concat(quote, expression) - return stack, expression, dictionary
+ ''' + # times == [-- dip] cons [swap] infra [0 >] swap while pop + (quote, (n, stack)) = stack + if n <= 0: + return stack, expression, dictionary + n -= 1 + if n: + expression = n, (quote, (S_times, expression)) + expression = concat(quote, expression) + return stack, expression, dictionary # The current definition above works like this: @@ -1362,48 +1395,57 @@
[docs]@inscribe @FunctionWrapper def loop(stack, expression, dictionary): - ''' - Basic loop combinator. - :: + ''' + Basic loop combinator. + :: - ... True [Q] loop - ----------------------- - ... Q [Q] loop + ... True [Q] loop + ----------------------- + ... Q [Q] loop - ... False [Q] loop - ------------------------ - ... + ... False [Q] loop + ------------------------ + ... - ''' - quote, (flag, stack) = stack - if flag: - expression = concat(quote, (quote, (S_loop, expression))) - return stack, expression, dictionary
+ ''' + 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
[docs]@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: - :: + ''' + 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 + G - a b [G] [E] [L] cmp - ------------------------- a = b - E + 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
+ 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), @@ -1412,46 +1454,46 @@ for F in ( - #divmod_ = pm = __(n2, n1), __(n4, n3) + #divmod_ = pm = __(n2, n1), __(n4, n3) - BinaryBuiltinWrapper(operator.eq), - BinaryBuiltinWrapper(operator.ge), - BinaryBuiltinWrapper(operator.gt), - BinaryBuiltinWrapper(operator.le), - BinaryBuiltinWrapper(operator.lt), - BinaryBuiltinWrapper(operator.ne), + BinaryBuiltinWrapper(operator.eq), + BinaryBuiltinWrapper(operator.ge), + BinaryBuiltinWrapper(operator.gt), + BinaryBuiltinWrapper(operator.le), + BinaryBuiltinWrapper(operator.lt), + BinaryBuiltinWrapper(operator.ne), - BinaryBuiltinWrapper(operator.xor), - BinaryBuiltinWrapper(operator.lshift), - BinaryBuiltinWrapper(operator.rshift), + BinaryBuiltinWrapper(operator.xor), + BinaryBuiltinWrapper(operator.lshift), + BinaryBuiltinWrapper(operator.rshift), - BinaryBuiltinWrapper(operator.and_), - BinaryBuiltinWrapper(operator.or_), + BinaryBuiltinWrapper(operator.and_), + BinaryBuiltinWrapper(operator.or_), - BinaryBuiltinWrapper(operator.add), - BinaryBuiltinWrapper(operator.floordiv), - BinaryBuiltinWrapper(operator.mod), - BinaryBuiltinWrapper(operator.mul), - BinaryBuiltinWrapper(operator.pow), - BinaryBuiltinWrapper(operator.sub), - BinaryBuiltinWrapper(operator.truediv), + BinaryBuiltinWrapper(operator.add), + BinaryBuiltinWrapper(operator.floordiv), + BinaryBuiltinWrapper(operator.mod), + BinaryBuiltinWrapper(operator.mul), + BinaryBuiltinWrapper(operator.pow), + BinaryBuiltinWrapper(operator.sub), +## BinaryBuiltinWrapper(operator.truediv), - UnaryBuiltinWrapper(bool), - UnaryBuiltinWrapper(operator.not_), + UnaryBuiltinWrapper(bool), + UnaryBuiltinWrapper(operator.not_), - UnaryBuiltinWrapper(abs), - UnaryBuiltinWrapper(operator.neg), - UnaryBuiltinWrapper(sqrt), + UnaryBuiltinWrapper(abs), + UnaryBuiltinWrapper(operator.neg), + UnaryBuiltinWrapper(sqrt), - UnaryBuiltinWrapper(floor), - UnaryBuiltinWrapper(round), - ): - inscribe(F) + UnaryBuiltinWrapper(floor), + UnaryBuiltinWrapper(round), + ): + inscribe(F) del F # Otherwise Sphinx autodoc will pick it up. for name, primitive in getmembers(genlib, isfunction): - inscribe(SimpleFunctionWrapper(primitive)) + inscribe(SimpleFunctionWrapper(primitive)) add_aliases(_dictionary, ALIASES) @@ -1461,10 +1503,34 @@ + +