def _class(obj): name = obj.name # String bases = obj.bases # List of names assert not obj.decorator_list, "Decorators on classes are not supported" t = InstanceMethodTransformer() t.visit(obj) body = map(convert, obj.body) v = AssignTransformer() v.visit(body) f = InitFinder() f.visit(body) if f.found_init: body.append( js_ast.Call(js_ast.Name('this.__init__'), [js_ast.Name('args'), js_ast.Name('kwargs')])) aux_assign = js_ast.Assign( js_ast.Name('_' + name), js_ast.Function( [js_ast.Name('args'), js_ast.Name('kwargs')], body)) main_assign = js_ast.Assign( js_ast.Name(name), js_ast.Function( [js_ast.Name('args'), js_ast.Name('kwargs')], [js_ast.RawStatement("return new _" + name + "(args, kwargs)")])) return js_ast.RawStatement(str(aux_assign) + '\n' + str(main_assign))
def aug_assign(obj): target = convert(obj.target) op = convert(obj.op) value = convert(obj.value) if str(target).startswith('js.'): target = js_ast.Name(str(target)[3:]) return js_ast.AugAssign(target, op, value)
def assign(obj): assert len(obj.targets) == 1, "Multi-assignment not supported" assert type(obj.targets) != ast.Tuple, "Tuple assignment not supported" target = convert(obj.targets[0]) if str(target).startswith('js.'): target = js_ast.Name(str(target)[3:]) return js_ast.Assign(target, convert(obj.value))
def _for(obj): target = convert(obj.target) target_idx = js_ast.Name(str(target) + "_idx") target_value = js_ast.Name(str(target) + "_val") _iter = convert(obj.iter) body = map(convert, obj.body) if type(_iter) != js_ast.Name and type(_iter) != js_ast.Attribute: a = js_ast.Assign(target_value, _iter) body.insert( 0, js_ast.Assign(target, js_ast.Subscript(target_value, target_idx))) real_for = js_ast.RawExpression( str(a) + "\n" + str(js_ast.For(target_idx, target_value, body))) return real_for else: body.insert(0, js_ast.Assign(target, js_ast.Subscript(_iter, target_idx))) return js_ast.For(target_idx, _iter, body)
def name(obj): n = obj.id if n == 'True': n = 'true' elif n == 'False': n = 'false' elif n == 'None': n = 'null' return js_ast.Name(n)
def call(obj): func_name = "" temp = obj.func while type(temp) == ast.Attribute: func_name = str(temp.attr) + "." + func_name temp = temp.value func_name = str(temp.id) + "." + func_name func = js_ast.Name(func_name[:-1]) if str(func) == 'js': assert len( obj.args ) == 1, "Cannot call 'js' built-in with more than one argument" s = obj.args[0] assert type( s) == ast.Str, "Cannot call 'js' built-in with non-string argument" return js_ast.RawExpression(s.s) args = map(convert, obj.args) if func_name[:3] == "js.": assert (not obj.starargs) and (not obj.keywords) and ( not obj.kwargs), "JS built-ins only take positional arguments" return js_ast.Call(js_ast.Name(func_name[3:-1]), args) starargs = convert(obj.starargs) if args and starargs: assert False, "Both args and starargs not permitted" + str( args) + " " + str(starargs) elif args: args = js_ast.List(args) elif starargs: args = starargs kwargs_explicit = {kw.arg: convert(kw.value) for kw in obj.keywords} kwargs_dict = obj.kwargs if kwargs_explicit and kwargs_dict: raise NotImplementedError, "Both explicit keyword args and kwargs dict are not permitted" elif kwargs_dict: kwargs = convert(kwargs_dict) else: kwargs = js_ast.Dict(kwargs_explicit.keys(), kwargs_explicit.values()) return js_ast.Call(func, [args, kwargs])
def _def(obj): name = js_ast.Name(obj.name) args = map(convert, obj.args.args) str_args = [js_ast.Str(o.id) for o in obj.args.args] kwarg = obj.args.kwarg # arg kwargs go in vararg = obj.args.vararg # arg varargs go in if vararg: args.append(js_ast.Name(vararg)) if kwarg: args.append(js_ast.Name(kwarg)) defaults = dict( reversed( zip(reversed(str_args), map(convert, reversed(obj.args.defaults))))) #print 'Defaults', defaults local_vars = find_locals(obj.body) body = map(convert, obj.body) body.insert(0, js_ast.Vars(local_vars)) passed_args = [] if kwarg: passed_args.append(js_ast.Name('py.kwargs')) if vararg: passed_args.append(js_ast.Name('py.args')) passed_args.append(js_ast.Dict(defaults.keys(), defaults.values())) #print "Passed Args", passed_args the_fn = js_ast.Function(args, body) passed_args.append(the_fn) the_def = js_ast.Call(js_ast.Name("py.def"), passed_args) for decorator in reversed(obj.decorator_list): the_def = js_ast.Call(convert(decorator), [js_ast.List([the_def]), js_ast.Dict([], [])]) return js_ast.Assign(name, the_def)
def _tuple(obj): return js_ast.Call(js_ast.Name('tuple'), [ js_ast.List([js_ast.List(map(convert, obj.elts))]), js_ast.Dict([], []) ])
def _print(obj): values = obj.values newline = obj.nl # TODO: actually handle this dest = obj.dest assert dest is None, "Only printing to stdout is supported" return js_ast.Call(js_ast.Name('console.log'), map(convert, values))