SickGear/lib/js2py/legecy_translators/exps.py

86 lines
3.1 KiB
Python
Raw Permalink Normal View History

"""
exp_translate routine:
It takes a single line of JS code and returns a SINGLE line of Python code.
Note var is not present here because it was removed in previous stages. Also remove this useless void keyword
If case of parsing errors it must return a pos of error.
1. Convert all assignment operations to put operations, this may be hard :( DONE, wasn't that bad
2. Convert all gets and calls to get and callprop.
3. Convert unary operators like typeof, new, !, delete, ++, --
Delete can be handled by replacing last get method with delete.
4. Convert remaining operators that are not handled by python:
&&, || <= these should be easy simply replace && by and and || by or
=== and !==
comma operator , in, instanceof and finally :?
NOTES:
Strings and other literals are not present so each = means assignment
"""
from __future__ import print_function
from utils import *
from jsparser import *
def exps_translator(js):
#Check () {} and [] nums
ass = assignment_translator(js)
# Step 1
def assignment_translator(js):
sep = js.split(',')
res = sep[:]
for i, e in enumerate(sep):
if '=' not in e: # no need to convert
continue
res[i] = bass_translator(e)
return ','.join(res)
def bass_translator(s):
# I hope that I will not have to fix any bugs here because it will be terrible
if '(' in s or '[' in s:
converted = ''
for e in bracket_split(s, ['()', '[]'], strip=False):
if e[0] == '(':
converted += '(' + bass_translator(e[1:-1]) + ')'
elif e[0] == '[':
converted += '[' + bass_translator(e[1:-1]) + ']'
else:
converted += e
s = converted
if '=' not in s:
return s
ass = reversed(s.split('='))
last = ass.next()
res = last
for e in ass:
op = ''
if e[-1] in OP_METHODS: #increment assign like +=
op = ', "' + e[-1] + '"'
e = e[:-1]
cand = e.strip(
'() ') # (a) = 40 is valid so we need to transform '(a) ' to 'a'
if not is_property_accessor(cand): # it is not a property assignment
if not is_lval(cand) or is_internal(cand):
raise SyntaxError('Invalid left-hand side in assignment')
res = 'var.put(%s, %s%s)' % (cand.__repr__(), res, op)
elif cand[-1] == ']': # property assignment via []
c = list(bracket_split(cand, ['[]'], strip=False))
meth, prop = ''.join(c[:-1]).strip(), c[-1][1:-1].strip(
) #this does not have to be a string so dont remove
#() because it can be a call
res = '%s.put(%s, %s%s)' % (meth, prop, res, op)
else: # Prop set via '.'
c = cand.rfind('.')
meth, prop = cand[:c].strip(), cand[c + 1:].strip('() ')
if not is_lval(prop):
raise SyntaxError('Invalid left-hand side in assignment')
res = '%s.put(%s, %s%s)' % (meth, prop.__repr__(), res, op)
return res
if __name__ == '__main__':
print(bass_translator('3.ddsd = 40'))