Switch to functions from classes for FunctionWrappers.
This commit is contained in:
parent
a682537597
commit
f7e78b6050
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue