Two wrappers

One for math ops, the other for Boolean.

Fixes: https://todo.sr.ht/~sforman/thun-der/13
This commit is contained in:
Simon Forman 2022-04-05 10:02:01 -07:00
parent 68f6e210e5
commit 2fb27971f1
3 changed files with 49 additions and 29 deletions

View File

@ -140,7 +140,7 @@ def interp(stack=(), dictionary=None):
except NotAnIntError: except NotAnIntError:
print('Not an integer.') print('Not an integer.')
except NotAListError as e: except NotAListError as e:
print(e) # 'Not a list.' print(e)
except: except:
print_exc() print_exc()
print(stack_to_string(stack)) print(stack_to_string(stack))

View File

@ -141,9 +141,9 @@ def SimpleFunctionWrapper(f):
return inner return inner
def BinaryBuiltinWrapper(f): def BinaryMathWrapper(f):
''' '''
Wrap functions that take two arguments and return a single result. Wrap functions that take two numbers and return a single result.
''' '''
@FunctionWrapper @FunctionWrapper
@wraps(f) @wraps(f)
@ -152,13 +152,33 @@ def BinaryBuiltinWrapper(f):
(a, (b, stack)) = stack (a, (b, stack)) = stack
except ValueError: except ValueError:
raise StackUnderflowError('Not enough values on stack.') raise StackUnderflowError('Not enough values on stack.')
# Boolean predicates like "or" fail here. :( if ( not isinstance(a, int)
## if ( not isinstance(a, int) or not isinstance(b, int)
## or not isinstance(b, int) # bool is int in Python.
## or isinstance(a, bool) # Because bools are ints in Python. or isinstance(a, bool)
## or isinstance(b, bool) or isinstance(b, bool)
):
raise NotAnIntError
result = f(b, a)
return (result, stack), expression, dictionary
return inner
def BinaryLogicWrapper(f):
'''
Wrap functions that take two numbers and return a single result.
'''
@FunctionWrapper
@wraps(f)
def inner(stack, expression, dictionary):
try:
(a, (b, stack)) = stack
except ValueError:
raise StackUnderflowError('Not enough values on stack.')
## if (not isinstance(a, bool)
## or not isinstance(b, bool)
## ): ## ):
## raise NotAnIntError ## raise NotABoolError
result = f(b, a) result = f(b, a)
return (result, stack), expression, dictionary return (result, stack), expression, dictionary
return inner return inner
@ -1331,27 +1351,27 @@ for F in (
#divmod_ = pm = __(n2, n1), __(n4, n3) #divmod_ = pm = __(n2, n1), __(n4, n3)
BinaryBuiltinWrapper(operator.eq), BinaryMathWrapper(operator.eq),
BinaryBuiltinWrapper(operator.ge), BinaryMathWrapper(operator.ge),
BinaryBuiltinWrapper(operator.gt), BinaryMathWrapper(operator.gt),
BinaryBuiltinWrapper(operator.le), BinaryMathWrapper(operator.le),
BinaryBuiltinWrapper(operator.lt), BinaryMathWrapper(operator.lt),
BinaryBuiltinWrapper(operator.ne), BinaryMathWrapper(operator.ne),
BinaryBuiltinWrapper(operator.xor), BinaryMathWrapper(operator.xor),
BinaryBuiltinWrapper(operator.lshift), BinaryMathWrapper(operator.lshift),
BinaryBuiltinWrapper(operator.rshift), BinaryMathWrapper(operator.rshift),
BinaryBuiltinWrapper(operator.and_), BinaryLogicWrapper(operator.and_),
BinaryBuiltinWrapper(operator.or_), BinaryLogicWrapper(operator.or_),
BinaryBuiltinWrapper(operator.add), BinaryMathWrapper(operator.add),
BinaryBuiltinWrapper(operator.floordiv), BinaryMathWrapper(operator.floordiv),
BinaryBuiltinWrapper(operator.mod), BinaryMathWrapper(operator.mod),
BinaryBuiltinWrapper(operator.mul), BinaryMathWrapper(operator.mul),
BinaryBuiltinWrapper(operator.pow), BinaryMathWrapper(operator.pow),
BinaryBuiltinWrapper(operator.sub), BinaryMathWrapper(operator.sub),
## BinaryBuiltinWrapper(operator.truediv), ## BinaryMathWrapper(operator.truediv),
UnaryBuiltinWrapper(bool), UnaryBuiltinWrapper(bool),
UnaryBuiltinWrapper(operator.not_), UnaryBuiltinWrapper(operator.not_),

View File

@ -179,10 +179,10 @@ def concat(quote, expression):
# In-lining is slightly faster (and won't break the # In-lining is slightly faster (and won't break the
# recursion limit on long quotes.) # recursion limit on long quotes.)
if not isinstance(quote, tuple):
raise NotAListError('Not a list.')
temp = [] temp = []
while quote: while quote:
if not isinstance(quote, tuple):
raise NotAListError(repr(quote))
item, quote = quote item, quote = quote
temp.append(item) temp.append(item)
for item in reversed(temp): for item in reversed(temp):