""" 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 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')