Switch to functions from classes for FunctionWrappers.

This commit is contained in:
Simon Forman 2018-04-21 15:20:46 -07:00
parent a682537597
commit f7e78b6050
1 changed files with 33 additions and 36 deletions

View File

@ -24,6 +24,7 @@ returns a dictionary of Joy functions suitable for use with the joy()
function. function.
''' '''
from inspect import getdoc from inspect import getdoc
from functools import wraps
import operator, math import operator, math
from .parser import text_to_expression, Symbol from .parser import text_to_expression, Symbol
@ -152,61 +153,52 @@ step_zero == 0 roll> step
) )
class FunctionWrapper(object): def FunctionWrapper(f):
''' '''Set name attribute.'''
Allow functions to have a nice repr(). if not f.__doc__:
raise ValueError('Function %s must have doc string.' % f.__name__)
At some point it's likely this class and its subclasses would gain f.name = f.__name__.rstrip('_') # Don't shadow builtins.
machinery to support type checking and inference. return f
'''
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 __repr__(self):
return self.name
class SimpleFunctionWrapper(FunctionWrapper): def SimpleFunctionWrapper(f):
''' '''
Wrap functions that take and return just a stack. Wrap functions that take and return just a stack.
''' '''
@FunctionWrapper
def __call__(self, stack, expression, dictionary): @wraps(f)
return self.f(stack), expression, dictionary def inner(stack, expression, dictionary):
return f(stack), expression, dictionary
return inner
class BinaryBuiltinWrapper(FunctionWrapper): def BinaryBuiltinWrapper(f):
''' '''
Wrap functions that take two arguments and return a single result. Wrap functions that take two arguments and return a single result.
''' '''
@FunctionWrapper
def __call__(self, stack, expression, dictionary): @wraps(f)
def inner(stack, expression, dictionary):
(a, (b, stack)) = stack (a, (b, stack)) = stack
result = self.f(b, a) result = f(b, a)
return (result, stack), expression, dictionary return (result, stack), expression, dictionary
return inner
class UnaryBuiltinWrapper(FunctionWrapper): def UnaryBuiltinWrapper(f):
''' '''
Wrap functions that take one argument and return a single result. Wrap functions that take one argument and return a single result.
''' '''
@FunctionWrapper
def __call__(self, stack, expression, dictionary): @wraps(f)
def inner(stack, expression, dictionary):
(a, stack) = stack (a, stack) = stack
result = self.f(a) result = f(a)
return (result, stack), expression, dictionary return (result, stack), expression, dictionary
return inner
class DefinitionWrapper(FunctionWrapper): class DefinitionWrapper(object):
''' '''
Provide implementation of defined functions, and some helper methods. Provide implementation of defined functions, and some helper methods.
''' '''
@ -692,12 +684,15 @@ floor.__doc__ = math.floor.__doc__
@inscribe @inscribe
@SimpleFunctionWrapper @SimpleFunctionWrapper
def divmod_(S): def divmod_(S):
'''
divmod(x, y) -> (quotient, remainder)
Return the tuple (x//y, x%y). Invariant: div*y + mod == x.
'''
a, (b, stack) = S a, (b, stack) = S
d, m = divmod(a, b) d, m = divmod(a, b)
return d, (m, stack) return d, (m, stack)
divmod_.__doc__ = divmod.__doc__
def sqrt(a): def sqrt(a):
''' '''
@ -738,12 +733,14 @@ def rolldown(S):
@inscribe @inscribe
@SimpleFunctionWrapper @SimpleFunctionWrapper
def id_(stack): def id_(stack):
'''The identity function.'''
return stack return stack
@inscribe @inscribe
@SimpleFunctionWrapper @SimpleFunctionWrapper
def void(stack): def void(stack):
'''True if the form on TOS is void otherwise False.'''
form, stack = stack form, stack = stack
return _void(form), stack return _void(form), stack