[jsinterp] Adding interpreter support to get field
This commit is contained in:
parent
5238ed11ac
commit
171680120d
@ -1,7 +1,5 @@
|
|||||||
from youtube_dl.jsinterp.jsgrammar import Token
|
from youtube_dl.jsinterp.jsgrammar import Token
|
||||||
|
|
||||||
skip = {'i': 'Interpreting get field not yet implemented'}
|
|
||||||
|
|
||||||
tests = [
|
tests = [
|
||||||
{
|
{
|
||||||
'code': 'return a.var;',
|
'code': 'return a.var;',
|
||||||
|
@ -53,7 +53,7 @@ class JSInterpreter(object):
|
|||||||
if variables is not None:
|
if variables is not None:
|
||||||
for k, v in dict(variables).items():
|
for k, v in dict(variables).items():
|
||||||
# XXX validate identifiers
|
# XXX validate identifiers
|
||||||
self.global_vars[k] = Reference(v, (self.global_vars, k))
|
self.global_vars[k] = self.create_reference(v, (self.global_vars, k))
|
||||||
self._context = Context()
|
self._context = Context()
|
||||||
self._context_stack = []
|
self._context_stack = []
|
||||||
|
|
||||||
@ -65,6 +65,20 @@ class JSInterpreter(object):
|
|||||||
yield self._statement(ts, stack_size)
|
yield self._statement(ts, stack_size)
|
||||||
raise StopIteration
|
raise StopIteration
|
||||||
|
|
||||||
|
def create_reference(self, value, parent_key):
|
||||||
|
if isinstance(value, dict):
|
||||||
|
o = {}
|
||||||
|
for k, v in value.items():
|
||||||
|
o[k] = self.create_reference(v, (o, k))
|
||||||
|
elif isinstance(value, list):
|
||||||
|
o = []
|
||||||
|
for k, v in enumerate(value):
|
||||||
|
o[k] = self.create_reference(v, (o, k))
|
||||||
|
else:
|
||||||
|
o = value
|
||||||
|
|
||||||
|
return Reference(o, parent_key)
|
||||||
|
|
||||||
def _statement(self, token_stream, stack_top):
|
def _statement(self, token_stream, stack_top):
|
||||||
if stack_top < 0:
|
if stack_top < 0:
|
||||||
raise ExtractorError('Recursion limit reached')
|
raise ExtractorError('Recursion limit reached')
|
||||||
@ -923,10 +937,9 @@ class JSInterpreter(object):
|
|||||||
while tail is not None:
|
while tail is not None:
|
||||||
tail_name, tail_value, tail = tail
|
tail_name, tail_value, tail = tail
|
||||||
if tail_name is Token.FIELD:
|
if tail_name is Token.FIELD:
|
||||||
# TODO interpret field
|
target = target.getvalue()[tail_value]
|
||||||
raise ExtractorError('''Can't interpret expression called %s''' % tail_name)
|
|
||||||
elif tail_name is Token.ELEM:
|
elif tail_name is Token.ELEM:
|
||||||
index = self.interpret_statement(tail_value).getvalue()
|
index = self.interpret_expression(tail_value).getvalue()
|
||||||
target = target.getvalue()[index]
|
target = target.getvalue()[index]
|
||||||
elif tail_name is Token.CALL:
|
elif tail_name is Token.CALL:
|
||||||
# TODO interpret call
|
# TODO interpret call
|
||||||
@ -945,9 +958,8 @@ class JSInterpreter(object):
|
|||||||
elif name is Token.ARRAY:
|
elif name is Token.ARRAY:
|
||||||
array = []
|
array = []
|
||||||
for key, elem in enumerate(expr[1]):
|
for key, elem in enumerate(expr[1]):
|
||||||
value = self.interpret_expression(elem)
|
value = self.interpret_expression(elem).getvalue()
|
||||||
value._parent = array, key
|
array.append(Reference(value, (array, key)))
|
||||||
array.append(value)
|
|
||||||
ref = Reference(array)
|
ref = Reference(array)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user