1
1
from __future__ import unicode_literals
2
2
3
+ from functools import update_wrapper
3
4
import itertools
4
5
import json
5
6
import math
23
24
)
24
25
25
26
27
+ def wraps_op (op ):
28
+
29
+ def update_and_rename_wrapper (w ):
30
+ f = update_wrapper (w , op )
31
+ # fn names are str in both Py 2/3
32
+ f .__name__ = str ('JS_' ) + f .__name__
33
+ return f
34
+
35
+ return update_and_rename_wrapper
36
+
37
+
26
38
def _js_bit_op (op ):
27
39
28
40
def zeroise (x ):
29
41
return 0 if x in (None , JS_Undefined ) else x
30
42
43
+ @wraps_op (op )
31
44
def wrapped (a , b ):
32
45
return op (zeroise (a ), zeroise (b )) & 0xffffffff
33
46
@@ -36,6 +49,7 @@ def wrapped(a, b):
36
49
37
50
def _js_arith_op (op ):
38
51
52
+ @wraps_op (op )
39
53
def wrapped (a , b ):
40
54
if JS_Undefined in (a , b ):
41
55
return float ('nan' )
@@ -66,6 +80,7 @@ def _js_exp(a, b):
66
80
67
81
def _js_eq_op (op ):
68
82
83
+ @wraps_op (op )
69
84
def wrapped (a , b ):
70
85
if set ((a , b )) <= set ((None , JS_Undefined )):
71
86
return op (a , a )
@@ -76,6 +91,7 @@ def wrapped(a, b):
76
91
77
92
def _js_comp_op (op ):
78
93
94
+ @wraps_op (op )
79
95
def wrapped (a , b ):
80
96
if JS_Undefined in (a , b ):
81
97
return False
@@ -356,6 +372,7 @@ def _operator(self, op, left_val, right_expr, expr, local_vars, allow_recursion)
356
372
return right_val
357
373
358
374
try :
375
+ # print('Eval:', opfunc.__name__, left_val, right_val)
359
376
return opfunc (left_val , right_val )
360
377
except Exception as e :
361
378
raise self .Exception ('Failed to evaluate {left_val!r:.50} {op} {right_val!r:.50}' .format (** locals ()), expr , cause = e )
@@ -395,6 +412,7 @@ def interpret_statement(self, stmt, local_vars, allow_recursion=100):
395
412
raise self .Exception ('Recursion limit reached' )
396
413
allow_recursion -= 1
397
414
415
+ # print('At: ' + stmt[:60])
398
416
should_return = False
399
417
# fails on (eg) if (...) stmt1; else stmt2;
400
418
sub_statements = list (self ._separate (stmt , ';' )) or ['' ]
@@ -702,9 +720,24 @@ def interpret_statement(self, stmt, local_vars, allow_recursion=100):
702
720
continue
703
721
704
722
right_expr = separated .pop ()
705
- while op == '-' and len (separated ) > 1 and not separated [- 1 ].strip ():
706
- right_expr = '-' + right_expr
707
- separated .pop ()
723
+ # handle operators that are both unary and binary, minimal BODMAS
724
+ if op in ('+' , '-' ):
725
+ undone = 0
726
+ while len (separated ) > 1 and not separated [- 1 ].strip ():
727
+ undone += 1
728
+ separated .pop ()
729
+ if op == '-' and undone % 2 != 0 :
730
+ right_expr = op + right_expr
731
+ left_val = separated [- 1 ]
732
+ for dm_op in ('*' , '%' , '/' , '**' ):
733
+ bodmas = tuple (self ._separate (left_val , dm_op , skip_delims = skip_delim ))
734
+ if len (bodmas ) > 1 and not bodmas [- 1 ].strip ():
735
+ expr = op .join (separated ) + op + right_expr
736
+ right_expr = None
737
+ break
738
+ if right_expr is None :
739
+ continue
740
+
708
741
left_val = self .interpret_expression (op .join (separated ), local_vars , allow_recursion )
709
742
return self ._operator (op , left_val , right_expr , expr , local_vars , allow_recursion ), should_return
710
743
@@ -955,6 +988,7 @@ def valid_arg(y):
955
988
def build_function (self , argnames , code , * global_stack ):
956
989
global_stack = list (global_stack ) or [{}]
957
990
argnames = tuple (argnames )
991
+ # import pdb; pdb.set_trace()
958
992
959
993
def resf (args , kwargs = {}, allow_recursion = 100 ):
960
994
global_stack [0 ].update (
0 commit comments