[jsinterp] Handle default in switch better
This commit is contained in:
parent
c588b602d3
commit
a1fc7ca074
3 changed files with 33 additions and 10 deletions
|
@ -132,6 +132,21 @@ class TestJSInterpreter(unittest.TestCase):
|
||||||
self.assertEqual(jsi.call_function('x', 3), 6)
|
self.assertEqual(jsi.call_function('x', 3), 6)
|
||||||
self.assertEqual(jsi.call_function('x', 5), 0)
|
self.assertEqual(jsi.call_function('x', 5), 0)
|
||||||
|
|
||||||
|
def test_switch_default(self):
|
||||||
|
jsi = JSInterpreter('''
|
||||||
|
function x(f) { switch(f){
|
||||||
|
case 2: f+=2;
|
||||||
|
default: f-=1;
|
||||||
|
case 5:
|
||||||
|
case 6: f+=6;
|
||||||
|
case 0: break;
|
||||||
|
case 1: f+=1;
|
||||||
|
} return f }
|
||||||
|
''')
|
||||||
|
self.assertEqual(jsi.call_function('x', 1), 2)
|
||||||
|
self.assertEqual(jsi.call_function('x', 5), 11)
|
||||||
|
self.assertEqual(jsi.call_function('x', 9), 14)
|
||||||
|
|
||||||
def test_try(self):
|
def test_try(self):
|
||||||
jsi = JSInterpreter('''
|
jsi = JSInterpreter('''
|
||||||
function x() { try{return 10} catch(e){return 5} }
|
function x() { try{return 10} catch(e){return 5} }
|
||||||
|
|
|
@ -69,7 +69,11 @@ _NSIG_TESTS = [
|
||||||
(
|
(
|
||||||
'https://www.youtube.com/s/player/9216d1f7/player_ias.vflset/en_US/base.js',
|
'https://www.youtube.com/s/player/9216d1f7/player_ias.vflset/en_US/base.js',
|
||||||
'SLp9F5bwjAdhE9F-', 'gWnb9IK2DJ8Q1w',
|
'SLp9F5bwjAdhE9F-', 'gWnb9IK2DJ8Q1w',
|
||||||
), # TODO: Add more tests
|
),
|
||||||
|
(
|
||||||
|
'https://www.youtube.com/s/player/f8cb7a3b/player_ias.vflset/en_US/base.js',
|
||||||
|
'oBo2h5euWy6osrUt', 'ivXHpm7qJjJN',
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -228,21 +228,25 @@ class JSInterpreter(object):
|
||||||
switch_val, remaining = self._seperate_at_paren(expr[m.end() - 1:], ')')
|
switch_val, remaining = self._seperate_at_paren(expr[m.end() - 1:], ')')
|
||||||
switch_val = self.interpret_expression(switch_val, local_vars, allow_recursion)
|
switch_val = self.interpret_expression(switch_val, local_vars, allow_recursion)
|
||||||
body, expr = self._seperate_at_paren(remaining, '}')
|
body, expr = self._seperate_at_paren(remaining, '}')
|
||||||
body, default = body.split('default:') if 'default:' in body else (body, None)
|
items = body.replace('default:', 'case default:').split('case ')[1:]
|
||||||
items = body.split('case ')[1:]
|
for default in (False, True):
|
||||||
if default:
|
|
||||||
items.append(f'default:{default}')
|
|
||||||
matched = False
|
matched = False
|
||||||
for item in items:
|
for item in items:
|
||||||
case, stmt = [i.strip() for i in self._seperate(item, ':', 1)]
|
case, stmt = [i.strip() for i in self._seperate(item, ':', 1)]
|
||||||
matched = matched or case == 'default' or switch_val == self.interpret_expression(case, local_vars, allow_recursion)
|
if default:
|
||||||
if matched:
|
matched = matched or case == 'default'
|
||||||
|
elif not matched:
|
||||||
|
matched = case != 'default' and switch_val == self.interpret_expression(case, local_vars, allow_recursion)
|
||||||
|
if not matched:
|
||||||
|
continue
|
||||||
try:
|
try:
|
||||||
ret, should_abort = self.interpret_statement(stmt, local_vars, allow_recursion - 1)
|
ret, should_abort = self.interpret_statement(stmt, local_vars, allow_recursion - 1)
|
||||||
if should_abort:
|
if should_abort:
|
||||||
return ret
|
return ret
|
||||||
except JS_Break:
|
except JS_Break:
|
||||||
break
|
break
|
||||||
|
if matched:
|
||||||
|
break
|
||||||
return self.interpret_statement(expr, local_vars, allow_recursion - 1)[0]
|
return self.interpret_statement(expr, local_vars, allow_recursion - 1)[0]
|
||||||
|
|
||||||
# Comma seperated statements
|
# Comma seperated statements
|
||||||
|
|
Loading…
Reference in a new issue