From 2fb27971f1cf942a43c3b1695e2a6089af85e2c6 Mon Sep 17 00:00:00 2001 From: Simon Forman Date: Tue, 5 Apr 2022 10:02:01 -0700 Subject: [PATCH] Two wrappers One for math ops, the other for Boolean. Fixes: https://todo.sr.ht/~sforman/thun-der/13 --- implementations/Python/joy/joy.py | 2 +- implementations/Python/joy/library.py | 78 +++++++++++++++++++------------ implementations/Python/joy/utils/stack.py | 4 +- 3 files changed, 52 insertions(+), 32 deletions(-) diff --git a/implementations/Python/joy/joy.py b/implementations/Python/joy/joy.py index 3b271b3..eb2674c 100644 --- a/implementations/Python/joy/joy.py +++ b/implementations/Python/joy/joy.py @@ -140,7 +140,7 @@ def interp(stack=(), dictionary=None): except NotAnIntError: print('Not an integer.') except NotAListError as e: - print(e) # 'Not a list.' + print(e) except: print_exc() print(stack_to_string(stack)) diff --git a/implementations/Python/joy/library.py b/implementations/Python/joy/library.py index 5dc02bb..f556f73 100644 --- a/implementations/Python/joy/library.py +++ b/implementations/Python/joy/library.py @@ -141,9 +141,9 @@ def SimpleFunctionWrapper(f): 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 @wraps(f) @@ -152,13 +152,33 @@ def BinaryBuiltinWrapper(f): (a, (b, stack)) = stack except ValueError: raise StackUnderflowError('Not enough values on stack.') - # Boolean predicates like "or" fail here. :( -## if ( not isinstance(a, int) -## or not isinstance(b, int) -## or isinstance(a, bool) # Because bools are ints in Python. -## or isinstance(b, bool) + if ( not isinstance(a, int) + or not isinstance(b, int) + # bool is int in Python. + or isinstance(a, 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) return (result, stack), expression, dictionary return inner @@ -1331,27 +1351,27 @@ for F in ( #divmod_ = pm = __(n2, n1), __(n4, n3) - BinaryBuiltinWrapper(operator.eq), - BinaryBuiltinWrapper(operator.ge), - BinaryBuiltinWrapper(operator.gt), - BinaryBuiltinWrapper(operator.le), - BinaryBuiltinWrapper(operator.lt), - BinaryBuiltinWrapper(operator.ne), - - BinaryBuiltinWrapper(operator.xor), - BinaryBuiltinWrapper(operator.lshift), - BinaryBuiltinWrapper(operator.rshift), - - BinaryBuiltinWrapper(operator.and_), - BinaryBuiltinWrapper(operator.or_), - - BinaryBuiltinWrapper(operator.add), - BinaryBuiltinWrapper(operator.floordiv), - BinaryBuiltinWrapper(operator.mod), - BinaryBuiltinWrapper(operator.mul), - BinaryBuiltinWrapper(operator.pow), - BinaryBuiltinWrapper(operator.sub), -## BinaryBuiltinWrapper(operator.truediv), + BinaryMathWrapper(operator.eq), + BinaryMathWrapper(operator.ge), + BinaryMathWrapper(operator.gt), + BinaryMathWrapper(operator.le), + BinaryMathWrapper(operator.lt), + BinaryMathWrapper(operator.ne), + + BinaryMathWrapper(operator.xor), + BinaryMathWrapper(operator.lshift), + BinaryMathWrapper(operator.rshift), + + BinaryLogicWrapper(operator.and_), + BinaryLogicWrapper(operator.or_), + + BinaryMathWrapper(operator.add), + BinaryMathWrapper(operator.floordiv), + BinaryMathWrapper(operator.mod), + BinaryMathWrapper(operator.mul), + BinaryMathWrapper(operator.pow), + BinaryMathWrapper(operator.sub), +## BinaryMathWrapper(operator.truediv), UnaryBuiltinWrapper(bool), UnaryBuiltinWrapper(operator.not_), diff --git a/implementations/Python/joy/utils/stack.py b/implementations/Python/joy/utils/stack.py index f0063a8..90f75fd 100644 --- a/implementations/Python/joy/utils/stack.py +++ b/implementations/Python/joy/utils/stack.py @@ -179,10 +179,10 @@ def concat(quote, expression): # In-lining is slightly faster (and won't break the # recursion limit on long quotes.) + if not isinstance(quote, tuple): + raise NotAListError('Not a list.') temp = [] while quote: - if not isinstance(quote, tuple): - raise NotAListError(repr(quote)) item, quote = quote temp.append(item) for item in reversed(temp): -- 2.11.0