function.
'''
from inspect import getdoc
+from functools import wraps
import operator, math
from .parser import text_to_expression, Symbol
)
-class FunctionWrapper(object):
- '''
- Allow functions to have a nice repr().
-
- At some point it's likely this class and its subclasses would gain
- machinery to support type checking and inference.
- '''
-
- def __init__(self, f):
- self.f = f
- self.name = f.__name__.rstrip('_') # Don't shadow builtins.
- self.__doc__ = f.__doc__ or str(f)
-
- def __call__(self, stack, expression, dictionary):
- '''
- Functions in general receive and return all three.
- '''
- return self.f(stack, expression, dictionary)
+def FunctionWrapper(f):
+ '''Set name attribute.'''
+ if not f.__doc__:
+ raise ValueError('Function %s must have doc string.' % f.__name__)
+ f.name = f.__name__.rstrip('_') # Don't shadow builtins.
+ return f
- def __repr__(self):
- return self.name
-
-class SimpleFunctionWrapper(FunctionWrapper):
+def SimpleFunctionWrapper(f):
'''
Wrap functions that take and return just a stack.
'''
+ @FunctionWrapper
+ @wraps(f)
+ def inner(stack, expression, dictionary):
+ return f(stack), expression, dictionary
+ return inner
- def __call__(self, stack, expression, dictionary):
- return self.f(stack), expression, dictionary
-
-class BinaryBuiltinWrapper(FunctionWrapper):
+def BinaryBuiltinWrapper(f):
'''
Wrap functions that take two arguments and return a single result.
'''
-
- def __call__(self, stack, expression, dictionary):
+ @FunctionWrapper
+ @wraps(f)
+ def inner(stack, expression, dictionary):
(a, (b, stack)) = stack
- result = self.f(b, a)
+ result = f(b, a)
return (result, stack), expression, dictionary
+ return inner
-class UnaryBuiltinWrapper(FunctionWrapper):
+def UnaryBuiltinWrapper(f):
'''
Wrap functions that take one argument and return a single result.
'''
-
- def __call__(self, stack, expression, dictionary):
+ @FunctionWrapper
+ @wraps(f)
+ def inner(stack, expression, dictionary):
(a, stack) = stack
- result = self.f(a)
+ result = f(a)
return (result, stack), expression, dictionary
+ return inner
-class DefinitionWrapper(FunctionWrapper):
+class DefinitionWrapper(object):
'''
Provide implementation of defined functions, and some helper methods.
'''
@inscribe
@SimpleFunctionWrapper
def divmod_(S):
+ '''
+ 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)
-divmod_.__doc__ = divmod.__doc__
-
def sqrt(a):
'''
@inscribe
@SimpleFunctionWrapper
def id_(stack):
+ '''The identity function.'''
return stack
@inscribe
@SimpleFunctionWrapper
def void(stack):
+ '''True if the form on TOS is void otherwise False.'''
form, stack = stack
return _void(form), stack