Adding params to the docstrings.

This commit is contained in:
Simon Forman 2018-04-30 10:16:04 -07:00
parent 04e8f70dd2
commit dbb1fcf4a2
4 changed files with 104 additions and 43 deletions

View File

@ -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 = {}

View File

@ -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))

View File

@ -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:

View File

@ -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