Adding params to the docstrings.
This commit is contained in:
parent
04e8f70dd2
commit
dbb1fcf4a2
20
joy/joy.py
20
joy/joy.py
|
|
@ -42,11 +42,11 @@ def joy(stack, expression, dictionary, viewer=None):
|
||||||
or functions. Literals are put onto the stack and functions are
|
or functions. Literals are put onto the stack and functions are
|
||||||
executed.
|
executed.
|
||||||
|
|
||||||
|
:param stack stack: The stack.
|
||||||
:param quote stack: The stack.
|
:param stack expression: The expression to evaluate.
|
||||||
:param quote expression: The expression to evaluate.
|
:param dict dictionary: A ``dict`` mapping names to Joy functions.
|
||||||
:param dict dictionary: A `dict` mapping names to Joy functions.
|
|
||||||
:param function viewer: Optional viewer function.
|
:param function viewer: Optional viewer function.
|
||||||
|
:rtype: (stack, (), dictionary)
|
||||||
|
|
||||||
'''
|
'''
|
||||||
while expression:
|
while expression:
|
||||||
|
|
@ -67,6 +67,13 @@ def joy(stack, expression, dictionary, viewer=None):
|
||||||
def run(text, stack, dictionary, viewer=None):
|
def run(text, stack, dictionary, viewer=None):
|
||||||
'''
|
'''
|
||||||
Return the stack resulting from running the Joy code text on the stack.
|
Return the stack resulting from running the Joy code text on the stack.
|
||||||
|
|
||||||
|
:param str text: Joy code.
|
||||||
|
:param stack stack: The stack.
|
||||||
|
:param dict dictionary: A ``dict`` mapping names to Joy functions.
|
||||||
|
:param function viewer: Optional viewer function.
|
||||||
|
:rtype: (stack, (), dictionary)
|
||||||
|
|
||||||
'''
|
'''
|
||||||
expression = text_to_expression(text)
|
expression = text_to_expression(text)
|
||||||
return joy(stack, expression, dictionary, viewer)
|
return joy(stack, expression, dictionary, viewer)
|
||||||
|
|
@ -77,6 +84,11 @@ def repl(stack=(), dictionary=None):
|
||||||
Read-Evaluate-Print Loop
|
Read-Evaluate-Print Loop
|
||||||
|
|
||||||
Accept input and run it on the stack, loop.
|
Accept input and run it on the stack, loop.
|
||||||
|
|
||||||
|
:param stack stack: The stack.
|
||||||
|
:param dict dictionary: A ``dict`` mapping names to Joy functions.
|
||||||
|
:rtype: stack
|
||||||
|
|
||||||
'''
|
'''
|
||||||
if dictionary is None:
|
if dictionary is None:
|
||||||
dictionary = {}
|
dictionary = {}
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ def text_to_expression(text):
|
||||||
Any unbalanced square brackets will raise a ParseError.
|
Any unbalanced square brackets will raise a ParseError.
|
||||||
|
|
||||||
:param str text: Text to convert.
|
:param str text: Text to convert.
|
||||||
:rtype: quote
|
:rtype: stack
|
||||||
:raises ParseError: if the parse fails.
|
:raises ParseError: if the parse fails.
|
||||||
'''
|
'''
|
||||||
return _parse(_tokenize(text))
|
return _parse(_tokenize(text))
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,24 @@
|
||||||
# along with Thun. If not see <http://www.gnu.org/licenses/>.
|
# along with Thun. If not see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
'''
|
'''
|
||||||
Pretty printing support.
|
Pretty printing support, e.g.::
|
||||||
|
|
||||||
|
Joy? 23 18 * 99 +
|
||||||
|
. 23 18 mul 99 add
|
||||||
|
23 . 18 mul 99 add
|
||||||
|
23 18 . mul 99 add
|
||||||
|
414 . 99 add
|
||||||
|
414 99 . add
|
||||||
|
513 .
|
||||||
|
|
||||||
|
513 <-top
|
||||||
|
|
||||||
|
joy?
|
||||||
|
|
||||||
|
On each line the stack is printed with the top to the right, then a ``.`` to
|
||||||
|
represent the current locus of processing, then the pending expression to the
|
||||||
|
left.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
# (Kinda clunky and hacky. This should be swapped out in favor of much
|
# (Kinda clunky and hacky. This should be swapped out in favor of much
|
||||||
# smarter stuff.)
|
# smarter stuff.)
|
||||||
|
|
@ -29,29 +46,36 @@ from .stack import expression_to_string, stack_to_string
|
||||||
|
|
||||||
class TracePrinter(object):
|
class TracePrinter(object):
|
||||||
'''
|
'''
|
||||||
This is what does the formatting, e.g.::
|
This is what does the formatting. You instantiate it and pass the ``viewer()``
|
||||||
|
method to the :py:func:`joy.joy.joy` function, then print it to see the
|
||||||
Joy? 23 18 * 99 +
|
trace.
|
||||||
. 23 18 mul 99 add
|
|
||||||
23 . 18 mul 99 add
|
|
||||||
23 18 . mul 99 add
|
|
||||||
414 . 99 add
|
|
||||||
414 99 . add
|
|
||||||
513 .
|
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.history = []
|
self.history = []
|
||||||
|
|
||||||
def viewer(self, stack, expression):
|
def viewer(self, stack, expression):
|
||||||
'''Pass this method as the viewer to joy() function.'''
|
'''
|
||||||
|
Record the current stack and expression in the TracePrinter's history.
|
||||||
|
Pass this method as the ``viewer`` argument to the :py:func:`joy.joy.joy` function.
|
||||||
|
|
||||||
|
:param stack quote: A stack.
|
||||||
|
:param stack expression: A stack.
|
||||||
|
'''
|
||||||
self.history.append((stack, expression))
|
self.history.append((stack, expression))
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return '\n'.join(self.go())
|
return '\n'.join(self.go())
|
||||||
|
|
||||||
def go(self):
|
def go(self):
|
||||||
|
'''
|
||||||
|
Return a list of strings, one for each entry in the history, prefixed
|
||||||
|
with enough spaces to align all the interpreter dots.
|
||||||
|
|
||||||
|
This method is called internally by the ``__str__()`` method.
|
||||||
|
|
||||||
|
:rtype: list(str)
|
||||||
|
'''
|
||||||
max_stack_length = 0
|
max_stack_length = 0
|
||||||
lines = []
|
lines = []
|
||||||
for stack, expression in self.history:
|
for stack, expression in self.history:
|
||||||
|
|
|
||||||
|
|
@ -18,12 +18,13 @@
|
||||||
# along with Thun. If not see <http://www.gnu.org/licenses/>.
|
# along with Thun. If not see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
'''
|
'''
|
||||||
When talking about Joy we use the terms "stack", "list", "sequence",
|
When talking about Joy we use the terms "stack", "quote", "sequence",
|
||||||
"quote" and others to mean the same thing: a simple linear datatype that
|
"list", and others to mean the same thing: a simple linear datatype that
|
||||||
permits certain operations such as iterating and pushing and popping
|
permits certain operations such as iterating and pushing and popping
|
||||||
values from (at least) one end.
|
values from (at least) one end.
|
||||||
|
|
||||||
We use the `cons list`_, a venerable two-tuple recursive sequence datastructure, where the
|
There is no "Stack" Python class, instead we use the `cons list`_, a
|
||||||
|
venerable two-tuple recursive sequence datastructure, where the
|
||||||
empty tuple ``()`` is the empty stack and ``(head, rest)`` gives the recursive
|
empty tuple ``()`` is the empty stack and ``(head, rest)`` gives the recursive
|
||||||
form of a stack with one or more items on it::
|
form of a stack with one or more items on it::
|
||||||
|
|
||||||
|
|
@ -51,33 +52,36 @@ incoming tuple and assigning values to the names. (Note that Python
|
||||||
syntax doesn't require parentheses around tuples used in expressions
|
syntax doesn't require parentheses around tuples used in expressions
|
||||||
where they would be redundant.)
|
where they would be redundant.)
|
||||||
|
|
||||||
|
Unfortunately, the Sphinx documentation generator, which is used to generate this
|
||||||
|
web page, doesn't handle tuples in the function parameters. And in Python 3, this
|
||||||
|
syntax was removed entirely. Instead you would have to write::
|
||||||
|
|
||||||
|
def dup(stack):
|
||||||
|
head, tail = stack
|
||||||
|
return head, (head, tail)
|
||||||
|
|
||||||
|
|
||||||
|
We have two very simple functions, one to build up a stack from a Python
|
||||||
|
iterable and another to iterate through a stack and yield its items
|
||||||
|
one-by-one in order. There are also two functions to generate string representations
|
||||||
|
of stacks. They only differ in that one prints the terms in stack from left-to-right while the other prints from right-to-left. In both functions *internal stacks* are
|
||||||
|
printed left-to-right. These functions are written to support :doc:`../pretty`.
|
||||||
|
|
||||||
.. _cons list: https://en.wikipedia.org/wiki/Cons#Lists
|
.. _cons list: https://en.wikipedia.org/wiki/Cons#Lists
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
##We have two very simple functions to build up a stack from a Python
|
|
||||||
##iterable and also to iterate through a stack and yield its items
|
|
||||||
##one-by-one in order, and two functions to generate string representations
|
|
||||||
##of stacks::
|
|
||||||
##
|
|
||||||
## list_to_stack()
|
|
||||||
##
|
|
||||||
## iter_stack()
|
|
||||||
##
|
|
||||||
## expression_to_string() (prints left-to-right)
|
|
||||||
##
|
|
||||||
## stack_to_string() (prints right-to-left)
|
|
||||||
##
|
|
||||||
##
|
|
||||||
##A word about the stack data structure.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def list_to_stack(el, stack=()):
|
def list_to_stack(el, stack=()):
|
||||||
'''Convert a Python list (or other sequence) to a Joy stack::
|
'''Convert a Python list (or other sequence) to a Joy stack::
|
||||||
|
|
||||||
[1, 2, 3] -> (1, (2, (3, ())))
|
[1, 2, 3] -> (1, (2, (3, ())))
|
||||||
|
|
||||||
|
:param list el: A Python list or other sequence (iterators and generators
|
||||||
|
won't work because ``reverse()`` is called on ``el``.)
|
||||||
|
:param stack stack: A stack, optional, defaults to the empty stack.
|
||||||
|
:rtype: stack
|
||||||
|
|
||||||
'''
|
'''
|
||||||
for item in reversed(el):
|
for item in reversed(el):
|
||||||
stack = item, stack
|
stack = item, stack
|
||||||
|
|
@ -85,7 +89,11 @@ def list_to_stack(el, stack=()):
|
||||||
|
|
||||||
|
|
||||||
def iter_stack(stack):
|
def iter_stack(stack):
|
||||||
'''Iterate through the items on the stack.'''
|
'''Iterate through the items on the stack.
|
||||||
|
|
||||||
|
:param stack stack: A stack.
|
||||||
|
:rtype: iterator
|
||||||
|
'''
|
||||||
while stack:
|
while stack:
|
||||||
item, stack = stack
|
item, stack = stack
|
||||||
yield item
|
yield item
|
||||||
|
|
@ -98,6 +106,9 @@ def stack_to_string(stack):
|
||||||
The items are written right-to-left::
|
The items are written right-to-left::
|
||||||
|
|
||||||
(top, (second, ...)) -> '... second top'
|
(top, (second, ...)) -> '... second top'
|
||||||
|
|
||||||
|
:param stack stack: A stack.
|
||||||
|
:rtype: str
|
||||||
'''
|
'''
|
||||||
f = lambda stack: reversed(list(iter_stack(stack)))
|
f = lambda stack: reversed(list(iter_stack(stack)))
|
||||||
return _to_string(stack, f)
|
return _to_string(stack, f)
|
||||||
|
|
@ -110,6 +121,9 @@ def expression_to_string(expression):
|
||||||
The items are written left-to-right::
|
The items are written left-to-right::
|
||||||
|
|
||||||
(top, (second, ...)) -> 'top second ...'
|
(top, (second, ...)) -> 'top second ...'
|
||||||
|
|
||||||
|
:param stack expression: A stack.
|
||||||
|
:rtype: str
|
||||||
'''
|
'''
|
||||||
return _to_string(expression, iter_stack)
|
return _to_string(expression, iter_stack)
|
||||||
|
|
||||||
|
|
@ -132,7 +146,16 @@ def pushback(quote, expression):
|
||||||
'''Concatinate quote onto expression.
|
'''Concatinate quote onto expression.
|
||||||
|
|
||||||
In joy [1 2] [3 4] would become [1 2 3 4].
|
In joy [1 2] [3 4] would become [1 2 3 4].
|
||||||
|
|
||||||
|
:param stack quote: A stack.
|
||||||
|
:param stack expression: A stack.
|
||||||
|
:raises RuntimeError: if quote is larger than sys.getrecursionlimit().
|
||||||
|
:rtype: stack
|
||||||
'''
|
'''
|
||||||
|
# This is the fastest implementation, but will trigger
|
||||||
|
# RuntimeError: maximum recursion depth exceeded
|
||||||
|
# on quotes longer than sys.getrecursionlimit().
|
||||||
|
return (quote[0], pushback(quote[1], expression)) if quote else expression
|
||||||
|
|
||||||
# Original implementation.
|
# Original implementation.
|
||||||
|
|
||||||
|
|
@ -149,15 +172,17 @@ def pushback(quote, expression):
|
||||||
## expression = item, expression
|
## expression = item, expression
|
||||||
## return expression
|
## return expression
|
||||||
|
|
||||||
# This is the fastest, but will trigger
|
|
||||||
# RuntimeError: maximum recursion depth exceeded
|
|
||||||
# on quotes longer than sys.getrecursionlimit().
|
|
||||||
return (quote[0], pushback(quote[1], expression)) if quote else expression
|
|
||||||
|
|
||||||
|
|
||||||
def pick(s, n):
|
def pick(s, n):
|
||||||
'''
|
'''
|
||||||
Find the nth item on the stack. (Pick with zero is the same as "dup".)
|
Return the nth item on the stack.
|
||||||
|
|
||||||
|
:param stack s: A stack.
|
||||||
|
:param int n: An index into the stack.
|
||||||
|
:raises ValueError: if ``n`` is less than zero.
|
||||||
|
:raises IndexError: if ``n`` is equal to or greater than the length of ``s``.
|
||||||
|
:rtype: whatever
|
||||||
'''
|
'''
|
||||||
if n < 0:
|
if n < 0:
|
||||||
raise ValueError
|
raise ValueError
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue