|
|
|
@ -590,6 +590,29 @@ class JSInterpreter:
|
|
|
|
|
return ret, True
|
|
|
|
|
return ret, False
|
|
|
|
|
|
|
|
|
|
m = re.match(fr'''(?x)
|
|
|
|
|
(?P<out>{_NAME_RE})(?:\[(?P<index>{_NESTED_BRACKETS})\])?\s*
|
|
|
|
|
(?P<op>{"|".join(map(re.escape, set(_OPERATORS) - _COMP_OPERATORS))})?
|
|
|
|
|
=(?!=)(?P<expr>.*)$
|
|
|
|
|
''', expr)
|
|
|
|
|
if m: # We are assigning a value to a variable
|
|
|
|
|
left_val = local_vars.get(m.group('out'))
|
|
|
|
|
|
|
|
|
|
if not m.group('index'):
|
|
|
|
|
local_vars[m.group('out')] = self._operator(
|
|
|
|
|
m.group('op'), left_val, m.group('expr'), expr, local_vars, allow_recursion)
|
|
|
|
|
return local_vars[m.group('out')], should_return
|
|
|
|
|
elif left_val in (None, JS_Undefined):
|
|
|
|
|
raise self.Exception(f'Cannot index undefined variable {m.group("out")}', expr)
|
|
|
|
|
|
|
|
|
|
idx = self.interpret_expression(m.group('index'), local_vars, allow_recursion)
|
|
|
|
|
if not isinstance(idx, (int, float)):
|
|
|
|
|
raise self.Exception(f'List index {idx} must be integer', expr)
|
|
|
|
|
idx = int(idx)
|
|
|
|
|
left_val[idx] = self._operator(
|
|
|
|
|
m.group('op'), self._index(left_val, idx), m.group('expr'), expr, local_vars, allow_recursion)
|
|
|
|
|
return left_val[idx], should_return
|
|
|
|
|
|
|
|
|
|
for m in re.finditer(rf'''(?x)
|
|
|
|
|
(?P<pre_sign>\+\+|--)(?P<var1>{_NAME_RE})|
|
|
|
|
|
(?P<var2>{_NAME_RE})(?P<post_sign>\+\+|--)''', expr):
|
|
|
|
@ -606,11 +629,7 @@ class JSInterpreter:
|
|
|
|
|
return None, should_return
|
|
|
|
|
|
|
|
|
|
m = re.match(fr'''(?x)
|
|
|
|
|
(?P<assign>
|
|
|
|
|
(?P<out>{_NAME_RE})(?:\[(?P<index>{_NESTED_BRACKETS})\])?\s*
|
|
|
|
|
(?P<op>{"|".join(map(re.escape, set(_OPERATORS) - _COMP_OPERATORS))})?
|
|
|
|
|
=(?!=)(?P<expr>.*)$
|
|
|
|
|
)|(?P<return>
|
|
|
|
|
(?P<return>
|
|
|
|
|
(?!if|return|true|false|null|undefined|NaN)(?P<name>{_NAME_RE})$
|
|
|
|
|
)|(?P<attribute>
|
|
|
|
|
(?P<var>{_NAME_RE})(?:
|
|
|
|
@ -622,25 +641,7 @@ class JSInterpreter:
|
|
|
|
|
)|(?P<function>
|
|
|
|
|
(?P<fname>{_NAME_RE})\((?P<args>.*)\)$
|
|
|
|
|
)''', expr)
|
|
|
|
|
if m and m.group('assign'):
|
|
|
|
|
left_val = local_vars.get(m.group('out'))
|
|
|
|
|
|
|
|
|
|
if not m.group('index'):
|
|
|
|
|
local_vars[m.group('out')] = self._operator(
|
|
|
|
|
m.group('op'), left_val, m.group('expr'), expr, local_vars, allow_recursion)
|
|
|
|
|
return local_vars[m.group('out')], should_return
|
|
|
|
|
elif left_val in (None, JS_Undefined):
|
|
|
|
|
raise self.Exception(f'Cannot index undefined variable {m.group("out")}', expr)
|
|
|
|
|
|
|
|
|
|
idx = self.interpret_expression(m.group('index'), local_vars, allow_recursion)
|
|
|
|
|
if not isinstance(idx, (int, float)):
|
|
|
|
|
raise self.Exception(f'List index {idx} must be integer', expr)
|
|
|
|
|
idx = int(idx)
|
|
|
|
|
left_val[idx] = self._operator(
|
|
|
|
|
m.group('op'), self._index(left_val, idx), m.group('expr'), expr, local_vars, allow_recursion)
|
|
|
|
|
return left_val[idx], should_return
|
|
|
|
|
|
|
|
|
|
elif expr.isdigit():
|
|
|
|
|
if expr.isdigit():
|
|
|
|
|
return int(expr), should_return
|
|
|
|
|
|
|
|
|
|
elif expr == 'break':
|
|
|
|
|