py_ext/modules/svgui/pyjs/pyjs.py
changeset 728 e0424e96e3fd
parent 727 3edd2f19bce2
child 729 25054c592dc4
--- a/py_ext/modules/svgui/pyjs/pyjs.py	Wed May 09 00:39:54 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1777 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2006 James Tauber and contributors
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-import sys
-from types import StringType
-import compiler
-from compiler import ast
-import os
-import copy
-
-# the standard location for builtins (e.g. pyjslib) can be
-# over-ridden by changing this.  it defaults to sys.prefix
-# so that on a system-wide install of pyjamas the builtins
-# can be found in e.g. {sys.prefix}/share/pyjamas
-#
-# over-rides can be done by either explicitly modifying
-# pyjs.prefix or by setting an environment variable, PYJSPREFIX.
-
-prefix = sys.prefix
-
-if os.environ.has_key('PYJSPREFIX'):
-    prefix = os.environ['PYJSPREFIX']
-
-# pyjs.path is the list of paths, just like sys.path, from which
-# library modules will be searched for, for compile purposes.
-# obviously we don't want to use sys.path because that would result
-# in compiling standard python modules into javascript!
-
-path = [os.path.abspath('')]
-
-if os.environ.has_key('PYJSPATH'):
-    for p in os.environ['PYJSPATH'].split(os.pathsep):
-        p = os.path.abspath(p)
-        if os.path.isdir(p):
-            path.append(p)
-
-# this is the python function used to wrap native javascript
-NATIVE_JS_FUNC_NAME = "JS"
-
-UU = ""
-
-PYJSLIB_BUILTIN_FUNCTIONS=("cmp",
-                           "map",
-                           "filter",
-                           "dir",
-                           "getattr",
-                           "setattr",
-                           "hasattr",
-                           "int",
-                           "float",
-                           "str",
-                           "repr",
-                           "range",
-                           "len",
-                           "hash",
-                           "abs",
-                           "ord",
-                           "chr",
-                           "enumerate",
-                           "min",
-                           "max",
-                           "bool",
-                           "type",
-                           "isinstance")
-
-PYJSLIB_BUILTIN_CLASSES=("BaseException",
-                         "Exception",
-                         "StandardError",
-                         "StopIteration",
-                         "AttributeError",
-                         "TypeError",
-                         "KeyError",
-                         "LookupError",
-                         "list",
-                         "dict",
-                         "object",
-                         "tuple",
-                        )
-
-def pyjs_builtin_remap(name):
-    # XXX HACK!
-    if name == 'list':
-        name = 'List'
-    if name == 'object':
-        name = '__Object'
-    if name == 'dict':
-        name = 'Dict'
-    if name == 'tuple':
-        name = 'Tuple'
-    return name
-
-# XXX: this is a hack: these should be dealt with another way
-# however, console is currently the only global name which is causing
-# problems.
-PYJS_GLOBAL_VARS=("console")
-
-# This is taken from the django project.
-# Escape every ASCII character with a value less than 32.
-JS_ESCAPES = (
-    ('\\', r'\x5C'),
-    ('\'', r'\x27'),
-    ('"', r'\x22'),
-    ('>', r'\x3E'),
-    ('<', r'\x3C'),
-    ('&', r'\x26'),
-    (';', r'\x3B')
-    ) + tuple([('%c' % z, '\\x%02X' % z) for z in range(32)])
-
-def escapejs(value):
-    """Hex encodes characters for use in JavaScript strings."""
-    for bad, good in JS_ESCAPES:
-        value = value.replace(bad, good)
-    return value
-
-def uuprefix(name, leave_alone=0):
-    name = name.split(".")
-    name = name[:leave_alone] + map(lambda x: "__%s" % x, name[leave_alone:])
-    return '.'.join(name)
-
-class Klass:
-
-    klasses = {}
-
-    def __init__(self, name, name_):
-        self.name = name
-        self.name_ = name_
-        self.klasses[name] = self
-        self.functions = set()
-
-    def set_base(self, base_name):
-        self.base = self.klasses.get(base_name)
-
-    def add_function(self, function_name):
-        self.functions.add(function_name)
-
-
-class TranslationError(Exception):
-    def __init__(self, message, node):
-        self.message = "line %s:\n%s\n%s" % (node.lineno, message, node)
-
-    def __str__(self):
-        return self.message
-
-def strip_py(name):
-    return name
-
-def mod_var_name_decl(raw_module_name):
-    """ function to get the last component of the module e.g.
-        pyjamas.ui.DOM into the "namespace".  i.e. doing
-        "import pyjamas.ui.DOM" actually ends up with _two_
-        variables - one pyjamas.ui.DOM, the other just "DOM".
-        but "DOM" is actually local, hence the "var" prefix.
-
-        for PyV8, this might end up causing problems - we'll have
-        to see: gen_mod_import and mod_var_name_decl might have
-        to end up in a library-specific module, somewhere.
-    """
-    name = raw_module_name.split(".")
-    if len(name) == 1:
-        return ''
-    child_name = name[-1]
-    return "var %s = %s;\n" % (child_name, raw_module_name)
-
-def gen_mod_import(parentName, importName, dynamic=1):
-    #pyjs_ajax_eval("%(n)s.cache.js", null, true);
-    return """
-    pyjslib.import_module(sys.loadpath, '%(p)s', '%(n)s', %(d)d, false);
-    """ % ({'p': parentName, 'd': dynamic, 'n': importName}) + \
-    mod_var_name_decl(importName)
-
-class Translator:
-
-    def __init__(self, mn, module_name, raw_module_name, src, debug, mod, output,
-                 dynamic=0, optimize=False,
-                 findFile=None):
-
-        if module_name:
-            self.module_prefix = module_name + "."
-        else:
-            self.module_prefix = ""
-        self.raw_module_name = raw_module_name
-        src = src.replace("\r\n", "\n")
-        src = src.replace("\n\r", "\n")
-        src = src.replace("\r",   "\n")
-        self.src = src.split("\n")
-        self.debug = debug
-        self.imported_modules = []
-        self.imported_modules_as = []
-        self.imported_js = set()
-        self.top_level_functions = set()
-        self.top_level_classes = set()
-        self.top_level_vars = set()
-        self.local_arg_stack = [[]]
-        self.output = output
-        self.imported_classes = {}
-        self.method_imported_globals = set()
-        self.method_self = None
-        self.nextTupleAssignID = 1
-        self.dynamic = dynamic
-        self.optimize = optimize
-        self.findFile = findFile
-
-        if module_name.find(".") >= 0:
-            vdec = ''
-        else:
-            vdec = 'var '
-        print >>self.output, UU+"%s%s = function (__mod_name__) {" % (vdec, module_name)
-
-        print >>self.output, "    if("+module_name+".__was_initialized__) return;"
-        print >>self.output, "    "+UU+module_name+".__was_initialized__ = true;"
-        print >>self.output, UU+"if (__mod_name__ == null) __mod_name__ = '%s';" % (mn)
-        print >>self.output, UU+"%s.__name__ = __mod_name__;" % (raw_module_name)
-
-        decl = mod_var_name_decl(raw_module_name)
-        if decl:
-            print >>self.output, decl
-
-
-        if self.debug:
-            haltException = self.module_prefix + "HaltException"
-            print >>self.output, haltException + ' = function () {'
-            print >>self.output, '  this.message = "Program Halted";'
-            print >>self.output, '  this.name = "' + haltException + '";'
-            print >>self.output, '}'
-            print >>self.output, ''
-            print >>self.output, haltException + ".prototype.__str__ = function()"
-            print >>self.output, '{'
-            print >>self.output, 'return this.message ;'
-            print >>self.output, '}'
-
-            print >>self.output, haltException + ".prototype.toString = function()"
-            print >>self.output, '{'
-            print >>self.output, 'return this.name + ": \\"" + this.message + "\\"";'
-            print >>self.output, '}'
-
-            isHaltFunction = self.module_prefix + "IsHaltException"
-            print >>self.output, """
-    %s = function (s) {
-      var suffix="HaltException";
-      if (s.length < suffix.length) {
-        //alert(s + " " + suffix);
-        return false;
-      } else {
-        var ss = s.substring(s.length, (s.length - suffix.length));
-        //alert(s + " " + suffix + " " + ss);
-        return ss == suffix;
-      }
-    }
-                """ % isHaltFunction
-        for child in mod.node:
-            if isinstance(child, ast.Function):
-                self.top_level_functions.add(child.name)
-            elif isinstance(child, ast.Class):
-                self.top_level_classes.add(child.name)
-
-        for child in mod.node:
-            if isinstance(child, ast.Function):
-                self._function(child, False)
-            elif isinstance(child, ast.Class):
-                self._class(child)
-            elif isinstance(child, ast.Import):
-                importName = child.names[0][0]
-                if importName == '__pyjamas__': # special module to help make pyjamas modules loadable in the python interpreter
-                    pass
-                elif importName.endswith('.js'):
-                   self.imported_js.add(importName)
-                else:
-                   self.add_imported_module(strip_py(importName))
-            elif isinstance(child, ast.From):
-                if child.modname == '__pyjamas__': # special module to help make pyjamas modules loadable in the python interpreter
-                    pass
-                else:
-                    self.add_imported_module(child.modname)
-                    self._from(child)
-            elif isinstance(child, ast.Discard):
-                self._discard(child, None)
-            elif isinstance(child, ast.Assign):
-                self._assign(child, None, True)
-            elif isinstance(child, ast.AugAssign):
-                self._augassign(child, None)
-            elif isinstance(child, ast.If):
-                self._if(child, None)
-            elif isinstance(child, ast.For):
-                self._for(child, None)
-            elif isinstance(child, ast.While):
-                self._while(child, None)
-            elif isinstance(child, ast.Subscript):
-                self._subscript_stmt(child, None)
-            elif isinstance(child, ast.Global):
-                self._global(child, None)
-            elif isinstance(child, ast.Printnl):
-               self._print(child, None)
-            elif isinstance(child, ast.Print):
-               self._print(child, None)
-            elif isinstance(child, ast.TryExcept):
-                self._tryExcept(child, None)
-            elif isinstance(child, ast.Raise):
-                self._raise(child, None)
-            elif isinstance(child, ast.Stmt):
-                self._stmt(child, None)
-            else:
-                raise TranslationError("unsupported type (in __init__)", child)
-
-        # Initialize all classes for this module
-        #print >> self.output, "__"+self.modpfx()+\
-        #          "classes_initialize = function() {\n"
-        #for className in self.top_level_classes:
-        #    print >> self.output, "\t"+UU+self.modpfx()+"__"+className+"_initialize();"
-        #print >> self.output, "};\n"
-
-        print >> self.output, "return this;\n"
-        print >> self.output, "}; /* end %s */ \n"  % module_name
-
-    def module_imports(self):
-        return self.imported_modules + self.imported_modules_as
-
-    def add_local_arg(self, varname):
-        local_vars = self.local_arg_stack[-1]
-        if varname not in local_vars:
-            local_vars.append(varname)
-
-    def add_imported_module(self, importName):
-
-        if importName in self.imported_modules:
-            return
-        self.imported_modules.append(importName)
-        name = importName.split(".")
-        if len(name) != 1:
-            # add the name of the module to the namespace,
-            # but don't add the short name to imported_modules
-            # because then the short name would be attempted to be
-            # added to the dependencies, and it's half way up the
-            # module import directory structure!
-            child_name = name[-1]
-            self.imported_modules_as.append(child_name) 
-        print >> self.output, gen_mod_import(self.raw_module_name,
-                                             strip_py(importName),
-                                             self.dynamic)
-
-    def _default_args_handler(self, node, arg_names, current_klass,
-                              output=None):
-        if len(node.defaults):
-            output = output or self.output
-            default_pos = len(arg_names) - len(node.defaults)
-            if arg_names and arg_names[0] == self.method_self:
-                default_pos -= 1
-            for default_node in node.defaults:
-                if isinstance(default_node, ast.Const):
-                    default_value = self._const(default_node)
-                elif isinstance(default_node, ast.Name):
-                    default_value = self._name(default_node, current_klass)
-                elif isinstance(default_node, ast.UnarySub):
-                    default_value = self._unarysub(default_node, current_klass)
-                else:
-                    raise TranslationError("unsupported type (in _method)", default_node)
-
-                default_name = arg_names[default_pos]
-                default_pos += 1
-                print >> output, "    if (typeof %s == 'undefined') %s=%s;" % (default_name, default_name, default_value)
-
-    def _varargs_handler(self, node, varargname, arg_names, current_klass):
-        print >>self.output, "    var", varargname, '= new pyjslib.Tuple();'
-        print >>self.output, "    for(var __va_arg="+str(len(arg_names))+"; __va_arg < arguments.length; __va_arg++) {"
-        print >>self.output, "        var __arg = arguments[__va_arg];"
-        print >>self.output, "        "+varargname+".append(__arg);"
-        print >>self.output, "    }"
-
-    def _kwargs_parser(self, node, function_name, arg_names, current_klass):
-        if len(node.defaults) or node.kwargs:
-            default_pos = len(arg_names) - len(node.defaults)
-            if arg_names and arg_names[0] == self.method_self:
-                default_pos -= 1
-            print >>self.output, function_name+'.parse_kwargs = function (', ", ".join(["__kwargs"]+arg_names), ") {"
-            for default_node in node.defaults:
-                default_value = self.expr(default_node, current_klass)
-#                if isinstance(default_node, ast.Const):
-#                    default_value = self._const(default_node)
-#                elif isinstance(default_node, ast.Name):
-#                    default_value = self._name(default_node)
-#                elif isinstance(default_node, ast.UnarySub):
-#                    default_value = self._unarysub(default_node, current_klass)
-#                else:
-#                    raise TranslationError("unsupported type (in _method)", default_node)
-
-                default_name = arg_names[default_pos]
-                print >>self.output, "    if (typeof %s == 'undefined')"%(default_name)
-                print >>self.output, "        %s=__kwargs.%s;"% (default_name, default_name)
-                default_pos += 1
-
-            #self._default_args_handler(node, arg_names, current_klass)
-            if node.kwargs: arg_names += ["pyjslib.Dict(__kwargs)"]
-            print >>self.output, "    var __r = "+"".join(["[", ", ".join(arg_names), "]"])+";"
-            if node.varargs:
-                self._varargs_handler(node, "__args", arg_names, current_klass)
-                print >>self.output, "    __r.push.apply(__r, __args.getArray())"
-            print >>self.output, "    return __r;"
-            print >>self.output, "};"
-
-    def _function(self, node, local=False):
-        if local:
-            function_name = node.name
-            self.add_local_arg(function_name)
-        else:
-            function_name = UU + self.modpfx() + node.name
-
-        arg_names = list(node.argnames)
-        normal_arg_names = list(arg_names)
-        if node.kwargs: kwargname = normal_arg_names.pop()
-        if node.varargs: varargname = normal_arg_names.pop()
-        declared_arg_names = list(normal_arg_names)
-        if node.kwargs: declared_arg_names.append(kwargname)
-
-        function_args = "(" + ", ".join(declared_arg_names) + ")"
-        print >>self.output, "%s = function%s {" % (function_name, function_args)
-        self._default_args_handler(node, normal_arg_names, None)
-
-        local_arg_names = normal_arg_names + declared_arg_names 
-
-        if node.varargs:
-            self._varargs_handler(node, varargname, declared_arg_names, None)
-            local_arg_names.append(varargname)
-
-        # stack of local variable names for this function call
-        self.local_arg_stack.append(local_arg_names)
-
-        for child in node.code:
-            self._stmt(child, None)
-
-        # remove the top local arg names
-        self.local_arg_stack.pop()
-
-        # we need to return null always, so it is not undefined
-        lastStmt = [p for p in node.code][-1]
-        if not isinstance(lastStmt, ast.Return):
-            if not self._isNativeFunc(lastStmt):
-                print >>self.output, "    return null;"
-
-        print >>self.output, "};"
-        print >>self.output, "%s.__name__ = '%s';\n" % (function_name, node.name)
-
-
-        self._kwargs_parser(node, function_name, normal_arg_names, None)
-
-
-    def _return(self, node, current_klass):
-        expr = self.expr(node.value, current_klass)
-        # in python a function call always returns None, so we do it
-        # here too
-        print >>self.output, "    return " + expr + ";"
-
-
-    def _break(self, node, current_klass):
-        print >>self.output, "    break;"
-
-
-    def _continue(self, node, current_klass):
-        print >>self.output, "    continue;"
-
-
-    def _callfunc(self, v, current_klass):
-
-        if isinstance(v.node, ast.Name):
-            if v.node.name in self.top_level_functions:
-                call_name = self.modpfx() + v.node.name
-            elif v.node.name in self.top_level_classes:
-                call_name = self.modpfx() + v.node.name
-            elif self.imported_classes.has_key(v.node.name):
-                call_name = self.imported_classes[v.node.name] + '.' + v.node.name
-            elif v.node.name in PYJSLIB_BUILTIN_FUNCTIONS:
-                call_name = 'pyjslib.' + v.node.name
-            elif v.node.name in PYJSLIB_BUILTIN_CLASSES:
-                name = pyjs_builtin_remap(v.node.name)
-                call_name = 'pyjslib.' + name
-            elif v.node.name == "callable":
-                call_name = "pyjslib.isFunction"
-            else:
-                call_name = v.node.name
-            call_args = []
-        elif isinstance(v.node, ast.Getattr):
-            attr_name = v.node.attrname
-
-            if isinstance(v.node.expr, ast.Name):
-                call_name = self._name2(v.node.expr, current_klass, attr_name)
-                call_args = []
-            elif isinstance(v.node.expr, ast.Getattr):
-                call_name = self._getattr2(v.node.expr, current_klass, attr_name)
-                call_args = []
-            elif isinstance(v.node.expr, ast.CallFunc):
-                call_name = self._callfunc(v.node.expr, current_klass) + "." + v.node.attrname
-                call_args = []
-            elif isinstance(v.node.expr, ast.Subscript):
-                call_name = self._subscript(v.node.expr, current_klass) + "." + v.node.attrname
-                call_args = []
-            elif isinstance(v.node.expr, ast.Const):
-                call_name = self.expr(v.node.expr, current_klass) + "." + v.node.attrname
-                call_args = []
-            else:
-                raise TranslationError("unsupported type (in _callfunc)", v.node.expr)
-        else:
-            raise TranslationError("unsupported type (in _callfunc)", v.node)
-
-        call_name = strip_py(call_name)
-
-        kwargs = []
-        star_arg_name = None
-        if v.star_args:
-            star_arg_name = self.expr(v.star_args, current_klass)
-
-        for ch4 in v.args:
-            if isinstance(ch4, ast.Keyword):
-                kwarg = ch4.name + ":" + self.expr(ch4.expr, current_klass)
-                kwargs.append(kwarg)
-            else:
-                arg = self.expr(ch4, current_klass)
-                call_args.append(arg)
-
-        if kwargs:
-            fn_args = ", ".join(['{' + ', '.join(kwargs) + '}']+call_args)
-        else:
-            fn_args = ", ".join(call_args)
-
-        if kwargs or star_arg_name:
-            if not star_arg_name:
-                star_arg_name = 'null'
-            try: call_this, method_name = call_name.rsplit(".", 1)
-            except ValueError:
-                # Must be a function call ...
-                return ("pyjs_kwargs_function_call("+call_name+", "
-                                  + star_arg_name 
-                                  + ", ["+fn_args+"]"
-                                  + ")" )
-            else:
-                return ("pyjs_kwargs_method_call("+call_this+", '"+method_name+"', "
-                                  + star_arg_name 
-                                  + ", ["+fn_args+"]"
-                                  + ")")
-        else:
-            return call_name + "(" + ", ".join(call_args) + ")"
-
-    def _print(self, node, current_klass):
-        if self.optimize:
-            return
-        call_args = []
-        for ch4 in node.nodes:
-            arg = self.expr(ch4, current_klass)
-            call_args.append(arg)
-
-        print >>self.output, "pyjslib.printFunc([", ', '.join(call_args), "],", int(isinstance(node, ast.Printnl)), ");"
-
-    def _tryExcept(self, node, current_klass):
-        if len(node.handlers) != 1:
-            raise TranslationError("except statements in this form are" +
-                                   " not supported", node)
-
-        expr = node.handlers[0][0]
-        as_ = node.handlers[0][1]
-        if as_:
-            errName = as_.name
-        else:
-            errName = 'err'
-
-        # XXX TODO: check that this should instead be added as a _separate_
-        # local scope, temporary to the function.  oh dearie me.
-        self.add_local_arg(errName)
-
-        print >>self.output, "    try {"
-        for stmt in node.body.nodes:
-            self._stmt(stmt, current_klass)
-        print >> self.output, "    } catch(%s) {" % errName
-        if expr:
-            l = []
-            if isinstance(expr, ast.Tuple):
-                for x in expr.nodes:
-                    l.append("(%(err)s.__name__ == %(expr)s.__name__)" % dict (err=errName, expr=self.expr(x, current_klass)))
-            else:
-                l = [ " (%(err)s.__name__ == %(expr)s.__name__) " % dict (err=errName, expr=self.expr(expr, current_klass)) ]
-            print >> self.output, "   if(%s) {" % '||\n\t\t'.join(l)
-        for stmt in node.handlers[0][2]:
-            self._stmt(stmt, current_klass)
-        if expr:
-            #print >> self.output, "} else { throw(%s); } " % errName
-            print >> self.output, "}"
-        if node.else_ != None:
-            print >>self.output, "    } finally {"
-            for stmt in node.else_:
-                self._stmt(stmt, current_klass)
-        print >>self.output, "    }"
-
-    # XXX: change use_getattr to True to enable "strict" compilation
-    # but incurring a 100% performance penalty. oops.
-    def _getattr(self, v, current_klass, use_getattr=False):
-        attr_name = v.attrname
-        if isinstance(v.expr, ast.Name):
-            obj = self._name(v.expr, current_klass, return_none_for_module=True)
-            if obj == None and v.expr.name in self.module_imports():
-                # XXX TODO: distinguish between module import classes
-                # and variables.  right now, this is a hack to get
-                # the sys module working.
-                #if v.expr.name == 'sys':
-                return v.expr.name+'.'+attr_name
-                #return v.expr.name+'.__'+attr_name+'.prototype.__class__'
-            if not use_getattr or attr_name == '__class__' or \
-                    attr_name == '__name__':
-                return obj + "." + attr_name
-            return "pyjslib.getattr(%s, '%s')" % (obj, attr_name)
-        elif isinstance(v.expr, ast.Getattr):
-            return self._getattr(v.expr, current_klass) + "." + attr_name
-        elif isinstance(v.expr, ast.Subscript):
-            return self._subscript(v.expr, self.modpfx()) + "." + attr_name
-        elif isinstance(v.expr, ast.CallFunc):
-            return self._callfunc(v.expr, self.modpfx()) + "." + attr_name
-        else:
-            raise TranslationError("unsupported type (in _getattr)", v.expr)
-
-
-    def modpfx(self):
-        return strip_py(self.module_prefix)
-        
-    def _name(self, v, current_klass, top_level=False,
-                                      return_none_for_module=False):
-
-        if v.name == 'ilikesillynamesfornicedebugcode':
-            print top_level, current_klass, repr(v)
-            print self.top_level_vars
-            print self.top_level_functions
-            print self.local_arg_stack
-            print "error..."
-
-        local_var_names = None
-        las = len(self.local_arg_stack)
-        if las > 0:
-            local_var_names = self.local_arg_stack[-1]
-
-        if v.name == "True":
-            return "true"
-        elif v.name == "False":
-            return "false"
-        elif v.name == "None":
-            return "null"
-        elif v.name == '__name__' and current_klass is None:
-            return self.modpfx() + v.name
-        elif v.name == self.method_self:
-            return "this"
-        elif v.name in self.top_level_functions:
-            return UU+self.modpfx() + v.name
-        elif v.name in self.method_imported_globals:
-            return UU+self.modpfx() + v.name
-        elif not current_klass and las == 1 and v.name in self.top_level_vars:
-            return UU+self.modpfx() + v.name
-        elif v.name in local_var_names:
-            return v.name
-        elif self.imported_classes.has_key(v.name):
-            return UU+self.imported_classes[v.name] + '.__' + v.name + ".prototype.__class__"
-        elif v.name in self.top_level_classes:
-            return UU+self.modpfx() + "__" + v.name + ".prototype.__class__"
-        elif v.name in self.module_imports() and return_none_for_module:
-            return None
-        elif v.name in PYJSLIB_BUILTIN_CLASSES:
-            return "pyjslib." + pyjs_builtin_remap( v.name )
-        elif current_klass:
-            if v.name not in local_var_names and \
-               v.name not in self.top_level_vars and \
-               v.name not in PYJS_GLOBAL_VARS and \
-               v.name not in self.top_level_functions:
-
-                cls_name = current_klass
-                if hasattr(cls_name, "name"):
-                    cls_name_ = cls_name.name_
-                    cls_name = cls_name.name
-                else:
-                    cls_name_ = current_klass + "_" # XXX ???
-                name = UU+cls_name_ + ".prototype.__class__." \
-                                   + v.name
-                if v.name == 'listener':
-                    name = 'listener+' + name
-                return name
-
-        return v.name
-
-    def _name2(self, v, current_klass, attr_name):
-        obj = v.name
-
-        if obj in self.method_imported_globals:
-            call_name = UU+self.modpfx() + obj + "." + attr_name
-        elif self.imported_classes.has_key(obj):
-            #attr_str = ""
-            #if attr_name != "__init__":
-            attr_str = ".prototype.__class__." + attr_name
-            call_name = UU+self.imported_classes[obj] + '.__' + obj + attr_str
-        elif obj in self.module_imports():
-            call_name = obj + "." + attr_name
-        elif obj[0] == obj[0].upper(): # XXX HACK ALERT
-            call_name = UU + self.modpfx() + "__" + obj + ".prototype.__class__." + attr_name
-        else:
-            call_name = UU+self._name(v, current_klass) + "." + attr_name
-
-        return call_name
-
-
-    def _getattr2(self, v, current_klass, attr_name):
-        if isinstance(v.expr, ast.Getattr):
-            call_name = self._getattr2(v.expr, current_klass, v.attrname + "." + attr_name)
-        elif isinstance(v.expr, ast.Name) and v.expr.name in self.module_imports():
-            call_name = UU+v.expr.name + '.__' +v.attrname+".prototype.__class__."+attr_name
-        else:
-            obj = self.expr(v.expr, current_klass)
-            call_name = obj + "." + v.attrname + "." + attr_name
-
-        return call_name
-
-
-    def _class(self, node):
-        """
-        Handle a class definition.
-
-        In order to translate python semantics reasonably well, the following
-        structure is used:
-
-        A special object is created for the class, which inherits attributes
-        from the superclass, or Object if there's no superclass.  This is the
-        class object; the object which you refer to when specifying the
-        class by name.  Static, class, and unbound methods are copied
-        from the superclass object.
-
-        A special constructor function is created with the same name as the
-        class, which is used to create instances of that class.
-
-        A javascript class (e.g. a function with a prototype attribute) is
-        created which is the javascript class of created instances, and
-        which inherits attributes from the class object. Bound methods are
-        copied from the superclass into this class rather than inherited,
-        because the class object contains unbound, class, and static methods
-        that we don't necessarily want to inherit.
-
-        The type of a method can now be determined by inspecting its
-        static_method, unbound_method, class_method, or instance_method
-        attribute; only one of these should be true.
-
-        Much of this work is done in pyjs_extend, is pyjslib.py
-        """
-        class_name = self.modpfx() + uuprefix(node.name, 1)
-        class_name_ = self.modpfx() + uuprefix(node.name)
-        current_klass = Klass(class_name, class_name_)
-        init_method = None
-        for child in node.code:
-            if isinstance(child, ast.Function):
-                current_klass.add_function(child.name)
-                if child.name == "__init__":
-                    init_method = child
-
-
-        if len(node.bases) == 0:
-            base_class = "pyjslib.__Object"
-        elif len(node.bases) == 1:
-            if isinstance(node.bases[0], ast.Name):
-                if self.imported_classes.has_key(node.bases[0].name):
-                    base_class_ = self.imported_classes[node.bases[0].name] + '.__' + node.bases[0].name
-                    base_class = self.imported_classes[node.bases[0].name] + '.' + node.bases[0].name
-                else:
-                    base_class_ = self.modpfx() + "__" + node.bases[0].name
-                    base_class = self.modpfx() + node.bases[0].name
-            elif isinstance(node.bases[0], ast.Getattr):
-                # the bases are not in scope of the class so do not
-                # pass our class to self._name
-                base_class_ = self._name(node.bases[0].expr, None) + \
-                             ".__" + node.bases[0].attrname
-                base_class = self._name(node.bases[0].expr, None) + \
-                             "." + node.bases[0].attrname
-            else:
-                raise TranslationError("unsupported type (in _class)", node.bases[0])
-
-            current_klass.set_base(base_class)
-        else:
-            raise TranslationError("more than one base (in _class)", node)
-
-        print >>self.output, UU+class_name_ + " = function () {"
-        # call superconstructor
-        #if base_class:
-        #    print >>self.output, "    __" + base_class + ".call(this);"
-        print >>self.output, "}"
-
-        if not init_method:
-            init_method = ast.Function([], "__init__", ["self"], [], 0, None, [])
-            #self._method(init_method, current_klass, class_name)
-
-        # Generate a function which constructs the object
-        clsfunc = ast.Function([],
-           node.name,
-           init_method.argnames[1:],
-           init_method.defaults,
-           init_method.flags,
-           None,
-           [ast.Discard(ast.CallFunc(ast.Name("JS"), [ast.Const(
-#            I attempted lazy initialization, but then you can't access static class members
-#            "    if(!__"+base_class+".__was_initialized__)"+
-#            "        __" + class_name + "_initialize();\n" +
-            "    var instance = new " + UU + class_name_ + "();\n" +
-            "    if(instance.__init__) instance.__init__.apply(instance, arguments);\n" +
-            "    return instance;"
-            )]))])
-
-        self._function(clsfunc, False)
-        print >>self.output, UU+class_name_ + ".__initialize__ = function () {"
-        print >>self.output, "    if("+UU+class_name_+".__was_initialized__) return;"
-        print >>self.output, "    "+UU+class_name_+".__was_initialized__ = true;"
-        cls_obj = UU+class_name_ + '.prototype.__class__'
-
-        if class_name == "pyjslib.__Object":
-            print >>self.output, "    "+cls_obj+" = {};"
-        else:
-            if base_class and base_class not in ("object", "pyjslib.__Object"):
-                print >>self.output, "    if(!"+UU+base_class_+".__was_initialized__)"
-                print >>self.output, "        "+UU+base_class_+".__initialize__();"
-                print >>self.output, "    pyjs_extend(" + UU+class_name_ + ", "+UU+base_class_+");"
-            else:
-                print >>self.output, "    pyjs_extend(" + UU+class_name_ + ", "+UU+"pyjslib.__Object);"
-
-        print >>self.output, "    "+cls_obj+".__new__ = "+UU+class_name+";"
-        print >>self.output, "    "+cls_obj+".__name__ = '"+UU+node.name+"';"
-
-        for child in node.code:
-            if isinstance(child, ast.Pass):
-                pass
-            elif isinstance(child, ast.Function):
-                self._method(child, current_klass, class_name, class_name_)
-            elif isinstance(child, ast.Assign):
-                self.classattr(child, current_klass)
-            elif isinstance(child, ast.Discard) and isinstance(child.expr, ast.Const):
-                # Probably a docstring, turf it
-                pass
-            else:
-                raise TranslationError("unsupported type (in _class)", child)
-        print >>self.output, "}"
-
-        print >> self.output, class_name_+".__initialize__();"
-
-
-    def classattr(self, node, current_klass):
-        self._assign(node, current_klass, True)
-
-    def _raise(self, node, current_klass):
-        if node.expr2:
-            raise TranslationError("More than one expression unsupported",
-                                   node)
-        print >> self.output, "throw (%s);" % self.expr(
-            node.expr1, current_klass)
-
-    def _method(self, node, current_klass, class_name, class_name_):
-        # reset global var scope
-        self.method_imported_globals = set()
-
-        arg_names = list(node.argnames)
-
-        classmethod = False
-        staticmethod = False
-        if node.decorators:
-            for d in node.decorators:
-                if d.name == "classmethod":
-                    classmethod = True
-                elif d.name == "staticmethod":
-                    staticmethod = True
-
-        if staticmethod:
-            staticfunc = ast.Function([], class_name_+"."+node.name, node.argnames, node.defaults, node.flags, node.doc, node.code, node.lineno)
-            self._function(staticfunc, True)
-            print >>self.output, "    " + UU+class_name_ + ".prototype.__class__." + node.name + " = " + class_name_+"."+node.name+";";
-            print >>self.output, "    " + UU+class_name_ + ".prototype.__class__." + node.name + ".static_method = true;";
-            return
-        else:
-            if len(arg_names) == 0:
-                raise TranslationError("methods must take an argument 'self' (in _method)", node)
-            self.method_self = arg_names[0]
-
-            #if not classmethod and arg_names[0] != "self":
-            #    raise TranslationError("first arg not 'self' (in _method)", node)
-
-        normal_arg_names = arg_names[1:]
-        if node.kwargs: kwargname = normal_arg_names.pop()
-        if node.varargs: varargname = normal_arg_names.pop()
-        declared_arg_names = list(normal_arg_names)
-        if node.kwargs: declared_arg_names.append(kwargname)
-
-        function_args = "(" + ", ".join(declared_arg_names) + ")"
-
-        if classmethod:
-            fexpr = UU + class_name_ + ".prototype.__class__." + node.name
-        else:
-            fexpr = UU + class_name_ + ".prototype." + node.name
-        print >>self.output, "    "+fexpr + " = function" + function_args + " {"
-
-        # default arguments
-        self._default_args_handler(node, normal_arg_names, current_klass)
-
-        local_arg_names = normal_arg_names + declared_arg_names 
-
-        if node.varargs:
-            self._varargs_handler(node, varargname, declared_arg_names, current_klass)
-            local_arg_names.append(varargname)
-
-
-        # stack of local variable names for this function call
-        self.local_arg_stack.append(local_arg_names)
-
-        for child in node.code:
-            self._stmt(child, current_klass)
-
-        # remove the top local arg names
-        self.local_arg_stack.pop()
-
-        print >>self.output, "    };"
-
-        self._kwargs_parser(node, fexpr, normal_arg_names, current_klass)
-
-        if classmethod:
-            # Have to create a version on the instances which automatically passes the
-            # class as "self"
-            altexpr = UU + class_name_ + ".prototype." + node.name
-            print >>self.output, "    "+altexpr + " = function() {"
-            print >>self.output, "        return " + fexpr + ".apply(this.__class__, arguments);"
-            print >>self.output, "    };"
-            print >>self.output, "    "+fexpr+".class_method = true;"
-            print >>self.output, "    "+altexpr+".instance_method = true;"
-        else:
-            # For instance methods, we need an unbound version in the class object
-            altexpr = UU + class_name_ + ".prototype.__class__." + node.name
-            print >>self.output, "    "+altexpr + " = function() {"
-            print >>self.output, "        return " + fexpr + ".call.apply("+fexpr+", arguments);"
-            print >>self.output, "    };"
-            print >>self.output, "    "+altexpr+".unbound_method = true;"
-            print >>self.output, "    "+fexpr+".instance_method = true;"
-            print >>self.output, "    "+altexpr+".__name__ = '%s';" % node.name
-
-        print >>self.output, UU + class_name_ + ".prototype.%s.__name__ = '%s';" % \
-                (node.name, node.name)
-
-        if node.kwargs or len(node.defaults):
-            print >>self.output, "    "+altexpr + ".parse_kwargs = " + fexpr + ".parse_kwargs;"
-
-        self.method_self = None
-        self.method_imported_globals = set()
-
-    def _isNativeFunc(self, node):
-        if isinstance(node, ast.Discard):
-            if isinstance(node.expr, ast.CallFunc):
-                if isinstance(node.expr.node, ast.Name) and \
-                       node.expr.node.name == NATIVE_JS_FUNC_NAME:
-                    return True
-        return False
-
-    def _stmt(self, node, current_klass):
-        debugStmt = self.debug and not self._isNativeFunc(node)
-        if debugStmt:
-            print >>self.output, '  try {'
-
-        if isinstance(node, ast.Return):
-            self._return(node, current_klass)
-        elif isinstance(node, ast.Break):
-            self._break(node, current_klass)
-        elif isinstance(node, ast.Continue):
-            self._continue(node, current_klass)
-        elif isinstance(node, ast.Assign):
-            self._assign(node, current_klass)
-        elif isinstance(node, ast.AugAssign):
-            self._augassign(node, current_klass)
-        elif isinstance(node, ast.Discard):
-            self._discard(node, current_klass)
-        elif isinstance(node, ast.If):
-            self._if(node, current_klass)
-        elif isinstance(node, ast.For):
-            self._for(node, current_klass)
-        elif isinstance(node, ast.While):
-            self._while(node, current_klass)
-        elif isinstance(node, ast.Subscript):
-            self._subscript_stmt(node, current_klass)
-        elif isinstance(node, ast.Global):
-            self._global(node, current_klass)
-        elif isinstance(node, ast.Pass):
-            pass
-        elif isinstance(node, ast.Function):
-            self._function(node, True)
-        elif isinstance(node, ast.Printnl):
-           self._print(node, current_klass)
-        elif isinstance(node, ast.Print):
-           self._print(node, current_klass)
-        elif isinstance(node, ast.TryExcept):
-            self._tryExcept(node, current_klass)
-        elif isinstance(node, ast.Raise):
-            self._raise(node, current_klass)
-        else:
-            raise TranslationError("unsupported type (in _stmt)", node)
-
-        if debugStmt:
-
-            lt = self.get_line_trace(node)
-
-            haltException = self.module_prefix + "HaltException"
-            isHaltFunction = self.module_prefix + "IsHaltException"
-
-            print >>self.output, '  } catch (__err) {'
-            print >>self.output, '      if (' + isHaltFunction + '(__err.name)) {'
-            print >>self.output, '          throw __err;'
-            print >>self.output, '      } else {'
-            print >>self.output, "          st = sys.printstack() + "\
-                                                + '"%s"' % lt + "+ '\\n' ;"
-            print >>self.output, '          alert("' + "Error in " \
-                                                + lt + '"' \
-                                                + '+"\\n"+__err.name+": "+__err.message'\
-                                                + '+"\\n\\nStack trace:\\n"' \
-                                                + '+st' \
-                                                + ');'
-            print >>self.output, '          debugger;'
-
-            print >>self.output, '          throw new ' + self.module_prefix + "HaltException();"
-            print >>self.output, '      }'
-            print >>self.output, '  }'
-
-
-    def get_line_trace(self, node):
-        lineNum = "Unknown"
-        srcLine = ""
-        if hasattr(node, "lineno"):
-            if node.lineno != None:
-                lineNum = node.lineno
-                srcLine = self.src[min(lineNum, len(self.src))-1]
-                srcLine = srcLine.replace('\\', '\\\\')
-                srcLine = srcLine.replace('"', '\\"')
-                srcLine = srcLine.replace("'", "\\'")
-
-        return self.raw_module_name + ".py, line " \
-               + str(lineNum) + ":"\
-               + "\\n" \
-               + "    " + srcLine
-
-    def _augassign(self, node, current_klass):
-        v = node.node
-        if isinstance(v, ast.Getattr):
-            # XXX HACK!  don't allow += on return result of getattr.
-            # TODO: create a temporary variable or something.
-            lhs = self._getattr(v, current_klass, False)
-        else:
-            lhs = self._name(node.node, current_klass)
-        op = node.op
-        rhs = self.expr(node.expr, current_klass)
-        print >>self.output, "    " + lhs + " " + op + " " + rhs + ";"
-
-
-    def _assign(self, node, current_klass, top_level = False):
-        if len(node.nodes) != 1:
-            tempvar = '__temp'+str(node.lineno)
-            tnode = ast.Assign([ast.AssName(tempvar, "OP_ASSIGN", node.lineno)], node.expr, node.lineno)
-            self._assign(tnode, current_klass, top_level)
-            for v in node.nodes:
-               tnode2 = ast.Assign([v], ast.Name(tempvar, node.lineno), node.lineno)
-               self._assign(tnode2, current_klass, top_level)
-            return
-
-        local_var_names = None
-        if len(self.local_arg_stack) > 0:
-            local_var_names = self.local_arg_stack[-1]
-
-        def _lhsFromAttr(v, current_klass):
-            attr_name = v.attrname
-            if isinstance(v.expr, ast.Name):
-                obj = v.expr.name
-                lhs = self._name(v.expr, current_klass) + "." + attr_name
-            elif isinstance(v.expr, ast.Getattr):
-                lhs = self._getattr(v, current_klass)
-            elif isinstance(v.expr, ast.Subscript):
-                lhs = self._subscript(v.expr, current_klass) + "." + attr_name
-            else:
-                raise TranslationError("unsupported type (in _assign)", v.expr)
-            return lhs
-
-        def _lhsFromName(v, top_level, current_klass):
-            if top_level:
-                if current_klass:
-                    lhs = UU+current_klass.name_ + ".prototype.__class__." \
-                               + v.name
-                else:
-                    self.top_level_vars.add(v.name)
-                    vname = self.modpfx() + v.name
-                    if not self.modpfx() and v.name not in\
-                           self.method_imported_globals:
-                        lhs = "var " + vname
-                    else:
-                        lhs = UU + vname
-                    self.add_local_arg(v.name)
-            else:
-                if v.name in local_var_names:
-                    lhs = v.name
-                elif v.name in self.method_imported_globals:
-                    lhs = self.modpfx() + v.name
-                else:
-                    lhs = "var " + v.name
-                    self.add_local_arg(v.name)
-            return lhs
-
-        dbg = 0
-        v = node.nodes[0]
-        if isinstance(v, ast.AssAttr):
-            lhs = _lhsFromAttr(v, current_klass)
-            if v.flags == "OP_ASSIGN":
-                op = "="
-            else:
-                raise TranslationError("unsupported flag (in _assign)", v)
-
-        elif isinstance(v, ast.AssName):
-            lhs = _lhsFromName(v, top_level, current_klass)
-            if v.flags == "OP_ASSIGN":
-                op = "="
-            else:
-                raise TranslationError("unsupported flag (in _assign)", v)
-        elif isinstance(v, ast.Subscript):
-            if v.flags == "OP_ASSIGN":
-                obj = self.expr(v.expr, current_klass)
-                if len(v.subs) != 1:
-                    raise TranslationError("must have one sub (in _assign)", v)
-                idx = self.expr(v.subs[0], current_klass)
-                value = self.expr(node.expr, current_klass)
-                print >>self.output, "    " + obj + ".__setitem__(" + idx + ", " + value + ");"
-                return
-            else:
-                raise TranslationError("unsupported flag (in _assign)", v)
-        elif isinstance(v, (ast.AssList, ast.AssTuple)):
-            uniqueID = self.nextTupleAssignID
-            self.nextTupleAssignID += 1
-            tempName = "__tupleassign" + str(uniqueID) + "__"
-            print >>self.output, "    var " + tempName + " = " + \
-                                 self.expr(node.expr, current_klass) + ";"
-            for index,child in enumerate(v.getChildNodes()):
-                rhs = tempName + ".__getitem__(" + str(index) + ")"
-
-                if isinstance(child, ast.AssAttr):
-                    lhs = _lhsFromAttr(child, current_klass)
-                elif isinstance(child, ast.AssName):
-                    lhs = _lhsFromName(child, top_level, current_klass)
-                elif isinstance(child, ast.Subscript):
-                    if child.flags == "OP_ASSIGN":
-                        obj = self.expr(child.expr, current_klass)
-                        if len(child.subs) != 1:
-                            raise TranslationError("must have one sub " +
-                                                   "(in _assign)", child)
-                        idx = self.expr(child.subs[0], current_klass)
-                        value = self.expr(node.expr, current_klass)
-                        print >>self.output, "    " + obj + ".__setitem__(" \
-                                           + idx + ", " + rhs + ");"
-                        continue
-                print >>self.output, "    " + lhs + " = " + rhs + ";"
-            return
-        else:
-            raise TranslationError("unsupported type (in _assign)", v)
-
-        rhs = self.expr(node.expr, current_klass)
-        if dbg:
-            print "b", repr(node.expr), rhs
-        print >>self.output, "    " + lhs + " " + op + " " + rhs + ";"
-
-
-    def _discard(self, node, current_klass):
-        
-        if isinstance(node.expr, ast.CallFunc):
-            debugStmt = self.debug and not self._isNativeFunc(node)
-            if debugStmt and isinstance(node.expr.node, ast.Name) and \
-               node.expr.node.name == 'import_wait':
-               debugStmt = False
-            if debugStmt:
-                st = self.get_line_trace(node)
-                print >>self.output, "sys.addstack('%s');\n" % st
-            if isinstance(node.expr.node, ast.Name) and node.expr.node.name == NATIVE_JS_FUNC_NAME:
-                if len(node.expr.args) != 1:
-                    raise TranslationError("native javascript function %s must have one arg" % NATIVE_JS_FUNC_NAME, node.expr)
-                if not isinstance(node.expr.args[0], ast.Const):
-                    raise TranslationError("native javascript function %s must have constant arg" % NATIVE_JS_FUNC_NAME, node.expr)
-                raw_js = node.expr.args[0].value
-                print >>self.output, raw_js
-            else:
-                expr = self._callfunc(node.expr, current_klass)
-                print >>self.output, "    " + expr + ";"
-
-            if debugStmt:
-                print >>self.output, "sys.popstack();\n"
-
-        elif isinstance(node.expr, ast.Const):
-            if node.expr.value is not None: # Empty statements generate ignore None
-                print >>self.output, self._const(node.expr)
-        else:
-            raise TranslationError("unsupported type (in _discard)", node.expr)
-
-
-    def _if(self, node, current_klass):
-        for i in range(len(node.tests)):
-            test, consequence = node.tests[i]
-            if i == 0:
-                keyword = "if"
-            else:
-                keyword = "else if"
-
-            self._if_test(keyword, test, consequence, current_klass)
-
-        if node.else_:
-            keyword = "else"
-            test = None
-            consequence = node.else_
-
-            self._if_test(keyword, test, consequence, current_klass)
-
-
-    def _if_test(self, keyword, test, consequence, current_klass):
-        if test:
-            expr = self.expr(test, current_klass)
-
-            print >>self.output, "    " + keyword + " (pyjslib.bool(" + expr + ")) {"
-        else:
-            print >>self.output, "    " + keyword + " {"
-
-        if isinstance(consequence, ast.Stmt):
-            for child in consequence.nodes:
-                self._stmt(child, current_klass)
-        else:
-            raise TranslationError("unsupported type (in _if_test)", consequence)
-
-        print >>self.output, "    }"
-
-
-    def _from(self, node):
-        for name in node.names:
-            # look up "hack" in AppTranslator as to how findFile gets here
-            module_name = node.modname + "." + name[0]
-            try:
-                ff = self.findFile(module_name + ".py")
-            except Exception:
-                ff = None
-            if ff:
-                self.add_imported_module(module_name)
-            else:
-                self.imported_classes[name[0]] = node.modname
-
-
-    def _compare(self, node, current_klass):
-        lhs = self.expr(node.expr, current_klass)
-
-        if len(node.ops) != 1:
-            raise TranslationError("only one ops supported (in _compare)", node)
-
-        op = node.ops[0][0]
-        rhs_node = node.ops[0][1]
-        rhs = self.expr(rhs_node, current_klass)
-
-        if op == "==":
-            return "pyjslib.eq(%s, %s)" % (lhs, rhs)
-        if op == "in":
-            return rhs + ".__contains__(" + lhs + ")"
-        elif op == "not in":
-            return "!" + rhs + ".__contains__(" + lhs + ")"
-        elif op == "is":
-            op = "==="
-        elif op == "is not":
-            op = "!=="
-
-        return "(" + lhs + " " + op + " " + rhs + ")"
-
-
-    def _not(self, node, current_klass):
-        expr = self.expr(node.expr, current_klass)
-
-        return "!(" + expr + ")"
-
-    def _or(self, node, current_klass):
-        expr = "("+(") || (".join([self.expr(child, current_klass) for child in node.nodes]))+')'
-        return expr
-
-    def _and(self, node, current_klass):
-        expr = "("+(") && (".join([self.expr(child, current_klass) for child in node.nodes]))+")"
-        return expr
-
-    def _for(self, node, current_klass):
-        assign_name = ""
-        assign_tuple = ""
-
-        # based on Bob Ippolito's Iteration in Javascript code
-        if isinstance(node.assign, ast.AssName):
-            assign_name = node.assign.name
-            self.add_local_arg(assign_name)
-            if node.assign.flags == "OP_ASSIGN":
-                op = "="
-        elif isinstance(node.assign, ast.AssTuple):
-            op = "="
-            i = 0
-            for child in node.assign:
-                child_name = child.name
-                if assign_name == "":
-                    assign_name = "temp_" + child_name
-                self.add_local_arg(child_name)
-                assign_tuple += """
-                var %(child_name)s %(op)s %(assign_name)s.__getitem__(%(i)i);
-                """ % locals()
-                i += 1
-        else:
-            raise TranslationError("unsupported type (in _for)", node.assign)
-
-        if isinstance(node.list, ast.Name):
-            list_expr = self._name(node.list, current_klass)
-        elif isinstance(node.list, ast.Getattr):
-            list_expr = self._getattr(node.list, current_klass)
-        elif isinstance(node.list, ast.CallFunc):
-            list_expr = self._callfunc(node.list, current_klass)
-        else:
-            raise TranslationError("unsupported type (in _for)", node.list)
-
-        lhs = "var " + assign_name
-        iterator_name = "__" + assign_name
-
-        print >>self.output, """
-        var %(iterator_name)s = %(list_expr)s.__iter__();
-        try {
-            while (true) {
-                %(lhs)s %(op)s %(iterator_name)s.next();
-                %(assign_tuple)s
-        """ % locals()
-        for node in node.body.nodes:
-            self._stmt(node, current_klass)
-        print >>self.output, """
-            }
-        } catch (e) {
-            if (e.__name__ != pyjslib.StopIteration.__name__) {
-                throw e;
-            }
-        }
-        """ % locals()
-
-
-    def _while(self, node, current_klass):
-        test = self.expr(node.test, current_klass)
-        print >>self.output, "    while (pyjslib.bool(" + test + ")) {"
-        if isinstance(node.body, ast.Stmt):
-            for child in node.body.nodes:
-                self._stmt(child, current_klass)
-        else:
-            raise TranslationError("unsupported type (in _while)", node.body)
-        print >>self.output, "    }"
-
-
-    def _const(self, node):
-        if isinstance(node.value, int):
-            return str(node.value)
-        elif isinstance(node.value, float):
-            return str(node.value)
-        elif isinstance(node.value, basestring):
-            v = node.value
-            if isinstance(node.value, unicode):
-                v = v.encode('utf-8')
-            return  "String('%s')" % escapejs(v)
-        elif node.value is None:
-            return "null"
-        else:
-            raise TranslationError("unsupported type (in _const)", node)
-
-    def _unaryadd(self, node, current_klass):
-        return self.expr(node.expr, current_klass)
-
-    def _unarysub(self, node, current_klass):
-        return "-" + self.expr(node.expr, current_klass)
-
-    def _add(self, node, current_klass):
-        return self.expr(node.left, current_klass) + " + " + self.expr(node.right, current_klass)
-
-    def _sub(self, node, current_klass):
-        return self.expr(node.left, current_klass) + " - " + self.expr(node.right, current_klass)
-
-    def _div(self, node, current_klass):
-        return self.expr(node.left, current_klass) + " / " + self.expr(node.right, current_klass)
-
-    def _mul(self, node, current_klass):
-        return self.expr(node.left, current_klass) + " * " + self.expr(node.right, current_klass)
-
-    def _mod(self, node, current_klass):
-        if isinstance(node.left, ast.Const) and isinstance(node.left.value, StringType):
-           self.imported_js.add("sprintf.js") # Include the sprintf functionality if it is used
-           return "sprintf("+self.expr(node.left, current_klass) + ", " + self.expr(node.right, current_klass)+")"
-        return self.expr(node.left, current_klass) + " % " + self.expr(node.right, current_klass)
-
-    def _invert(self, node, current_klass):
-        return "~" + self.expr(node.expr, current_klass)
-
-    def _bitand(self, node, current_klass):
-        return " & ".join([self.expr(child, current_klass) for child in node.nodes])
-
-    def _bitshiftleft(self, node, current_klass):
-        return self.expr(node.left, current_klass) + " << " + self.expr(node.right, current_klass)
-
-    def _bitshiftright(self, node, current_klass):
-        return self.expr(node.left, current_klass) + " >>> " + self.expr(node.right, current_klass)
-
-    def _bitxor(self,node, current_klass):
-        return " ^ ".join([self.expr(child, current_klass) for child in node.nodes])
-
-    def _bitor(self, node, current_klass):
-        return " | ".join([self.expr(child, current_klass) for child in node.nodes])
-
-    def _subscript(self, node, current_klass):
-        if node.flags == "OP_APPLY":
-            if len(node.subs) == 1:
-                return self.expr(node.expr, current_klass) + ".__getitem__(" + self.expr(node.subs[0], current_klass) + ")"
-            else:
-                raise TranslationError("must have one sub (in _subscript)", node)
-        else:
-            raise TranslationError("unsupported flag (in _subscript)", node)
-
-    def _subscript_stmt(self, node, current_klass):
-        if node.flags == "OP_DELETE":
-            print >>self.output, "    " + self.expr(node.expr, current_klass) + ".__delitem__(" + self.expr(node.subs[0], current_klass) + ");"
-        else:
-            raise TranslationError("unsupported flag (in _subscript)", node)
-
-    def _list(self, node, current_klass):
-        return "new pyjslib.List([" + ", ".join([self.expr(x, current_klass) for x in node.nodes]) + "])"
-
-    def _dict(self, node, current_klass):
-        items = []
-        for x in node.items:
-            key = self.expr(x[0], current_klass)
-            value = self.expr(x[1], current_klass)
-            items.append("[" + key + ", " + value + "]")
-        return "new pyjslib.Dict([" + ", ".join(items) + "])"
-
-    def _tuple(self, node, current_klass):
-        return "new pyjslib.Tuple([" + ", ".join([self.expr(x, current_klass) for x in node.nodes]) + "])"
-
-    def _lambda(self, node, current_klass):
-        if node.varargs:
-            raise TranslationError("varargs are not supported in Lambdas", node)
-        if node.kwargs:
-            raise TranslationError("kwargs are not supported in Lambdas", node)
-        res = cStringIO.StringIO()
-        arg_names = list(node.argnames)
-        function_args = ", ".join(arg_names)
-        for child in node.getChildNodes():
-            expr = self.expr(child, None)
-        print >> res, "function (%s){" % function_args
-        self._default_args_handler(node, arg_names, None,
-                                   output=res)
-        print >> res, 'return %s;}' % expr
-        return res.getvalue()
-
-    def _slice(self, node, current_klass):
-        if node.flags == "OP_APPLY":
-            lower = "null"
-            upper = "null"
-            if node.lower != None:
-                lower = self.expr(node.lower, current_klass)
-            if node.upper != None:
-                upper = self.expr(node.upper, current_klass)
-            return  "pyjslib.slice(" + self.expr(node.expr, current_klass) + ", " + lower + ", " + upper + ")"
-        else:
-            raise TranslationError("unsupported flag (in _slice)", node)
-
-    def _global(self, node, current_klass):
-        for name in node.names:
-            self.method_imported_globals.add(name)
-
-    def expr(self, node, current_klass):
-        if isinstance(node, ast.Const):
-            return self._const(node)
-        # @@@ not sure if the parentheses should be here or in individual operator functions - JKT
-        elif isinstance(node, ast.Mul):
-            return " ( " + self._mul(node, current_klass) + " ) "
-        elif isinstance(node, ast.Add):
-            return " ( " + self._add(node, current_klass) + " ) "
-        elif isinstance(node, ast.Sub):
-            return " ( " + self._sub(node, current_klass) + " ) "
-        elif isinstance(node, ast.Div):
-            return " ( " + self._div(node, current_klass) + " ) "
-        elif isinstance(node, ast.Mod):
-            return self._mod(node, current_klass)
-        elif isinstance(node, ast.UnaryAdd):
-            return self._unaryadd(node, current_klass)
-        elif isinstance(node, ast.UnarySub):
-            return self._unarysub(node, current_klass)
-        elif isinstance(node, ast.Not):
-            return self._not(node, current_klass)
-        elif isinstance(node, ast.Or):
-            return self._or(node, current_klass)
-        elif isinstance(node, ast.And):
-            return self._and(node, current_klass)
-        elif isinstance(node, ast.Invert):
-            return self._invert(node, current_klass)
-        elif isinstance(node, ast.Bitand):
-            return "("+self._bitand(node, current_klass)+")"
-        elif isinstance(node,ast.LeftShift):
-            return self._bitshiftleft(node, current_klass)
-        elif isinstance(node, ast.RightShift):
-            return self._bitshiftright(node, current_klass)
-        elif isinstance(node, ast.Bitxor):
-            return "("+self._bitxor(node, current_klass)+")"
-        elif isinstance(node, ast.Bitor):
-            return "("+self._bitor(node, current_klass)+")"
-        elif isinstance(node, ast.Compare):
-            return self._compare(node, current_klass)
-        elif isinstance(node, ast.CallFunc):
-            return self._callfunc(node, current_klass)
-        elif isinstance(node, ast.Name):
-            return self._name(node, current_klass)
-        elif isinstance(node, ast.Subscript):
-            return self._subscript(node, current_klass)
-        elif isinstance(node, ast.Getattr):
-            return self._getattr(node, current_klass)
-        elif isinstance(node, ast.List):
-            return self._list(node, current_klass)
-        elif isinstance(node, ast.Dict):
-            return self._dict(node, current_klass)
-        elif isinstance(node, ast.Tuple):
-            return self._tuple(node, current_klass)
-        elif isinstance(node, ast.Slice):
-            return self._slice(node, current_klass)
-        elif isinstance(node, ast.Lambda):
-            return self._lambda(node, current_klass)
-        else:
-            raise TranslationError("unsupported type (in expr)", node)
-
-
-
-import cStringIO
-
-def translate(file_name, module_name, debug=False):
-    f = file(file_name, "r")
-    src = f.read()
-    f.close()
-    output = cStringIO.StringIO()
-    mod = compiler.parseFile(file_name)
-    t = Translator(module_name, module_name, module_name, src, debug, mod, output)
-    return output.getvalue()
-
-
-class PlatformParser:
-    def __init__(self, platform_dir = "", verbose=True):
-        self.platform_dir = platform_dir
-        self.parse_cache = {}
-        self.platform = ""
-        self.verbose = verbose
-
-    def setPlatform(self, platform):
-        self.platform = platform
-
-    def parseModule(self, module_name, file_name):
-
-        importing = False
-        if not self.parse_cache.has_key(file_name):
-            importing = True
-            mod = compiler.parseFile(file_name)
-            self.parse_cache[file_name] = mod
-        else:
-            mod = self.parse_cache[file_name]
-
-        override = False
-        platform_file_name = self.generatePlatformFilename(file_name)
-        if self.platform and os.path.isfile(platform_file_name):
-            mod = copy.deepcopy(mod)
-            mod_override = compiler.parseFile(platform_file_name)
-            self.merge(mod, mod_override)
-            override = True
-
-        if self.verbose:
-            if override:
-                print "Importing %s (Platform %s)" % (module_name, self.platform)
-            elif importing:
-                print "Importing %s" % (module_name)
-
-        return mod, override
-
-    def generatePlatformFilename(self, file_name):
-        (module_name, extension) = os.path.splitext(os.path.basename(file_name))
-        platform_file_name = module_name + self.platform + extension
-
-        return os.path.join(os.path.dirname(file_name), self.platform_dir, platform_file_name)
-
-    def merge(self, tree1, tree2):
-        for child in tree2.node:
-            if isinstance(child, ast.Function):
-                self.replaceFunction(tree1, child.name, child)
-            elif isinstance(child, ast.Class):
-                self.replaceClassMethods(tree1, child.name, child)
-
-        return tree1
-
-    def replaceFunction(self, tree, function_name, function_node):
-        # find function to replace
-        for child in tree.node:
-            if isinstance(child, ast.Function) and child.name == function_name:
-                self.copyFunction(child, function_node)
-                return
-        raise TranslationError("function not found: " + function_name, function_node)
-
-    def replaceClassMethods(self, tree, class_name, class_node):
-        # find class to replace
-        old_class_node = None
-        for child in tree.node:
-            if isinstance(child, ast.Class) and child.name == class_name:
-                old_class_node = child
-                break
-
-        if not old_class_node:
-            raise TranslationError("class not found: " + class_name, class_node)
-
-        # replace methods
-        for function_node in class_node.code:
-            if isinstance(function_node, ast.Function):
-                found = False
-                for child in old_class_node.code:
-                    if isinstance(child, ast.Function) and child.name == function_node.name:
-                        found = True
-                        self.copyFunction(child, function_node)
-                        break
-
-                if not found:
-                    raise TranslationError("class method not found: " + class_name + "." + function_node.name, function_node)
-
-    def copyFunction(self, target, source):
-        target.code = source.code
-        target.argnames = source.argnames
-        target.defaults = source.defaults
-        target.doc = source.doc # @@@ not sure we need to do this any more
-
-def dotreplace(fname):
-    path, ext = os.path.splitext(fname)
-    return path.replace(".", "/") + ext
-
-class AppTranslator:
-
-    def __init__(self, library_dirs=[], parser=None, dynamic=False,
-                 optimize=False, verbose=True):
-        self.extension = ".py"
-        self.optimize = optimize
-        self.library_modules = []
-        self.overrides = {}
-        self.library_dirs = path + library_dirs
-        self.dynamic = dynamic
-        self.verbose = verbose
-
-        if not parser:
-            self.parser = PlatformParser()
-        else:
-            self.parser = parser
-
-        self.parser.dynamic = dynamic
-
-    def findFile(self, file_name):
-        if os.path.isfile(file_name):
-            return file_name
-
-        for library_dir in self.library_dirs:
-            file_name = dotreplace(file_name)
-            full_file_name = os.path.join(
-                os.path.abspath(os.path.dirname(__file__)), library_dir, file_name)
-            if os.path.isfile(full_file_name):
-                return full_file_name
-
-            fnameinit, ext = os.path.splitext(file_name)
-            fnameinit = fnameinit + "/__init__.py"
-
-            full_file_name = os.path.join(
-                os.path.abspath(os.path.dirname(__file__)), library_dir, fnameinit)
-            if os.path.isfile(full_file_name):
-                return full_file_name
-
-        raise Exception("file not found: " + file_name)
-
-    def _translate(self, module_name, is_app=True, debug=False,
-                   imported_js=set()):
-        if module_name not in self.library_modules:
-            self.library_modules.append(module_name)
-
-        file_name = self.findFile(module_name + self.extension)
-
-        output = cStringIO.StringIO()
-
-        f = file(file_name, "r")
-        src = f.read()
-        f.close()
-
-        mod, override = self.parser.parseModule(module_name, file_name)
-        if override:
-            override_name = "%s.%s" % (self.parser.platform.lower(),
-                                           module_name)
-            self.overrides[override_name] = override_name
-        if is_app:
-            mn = '__main__'
-        else:
-            mn = module_name
-        t = Translator(mn, module_name, module_name,
-                       src, debug, mod, output, self.dynamic, self.optimize,
-                       self.findFile)
-
-        module_str = output.getvalue()
-        imported_js.update(set(t.imported_js))
-        imported_modules_str = ""
-        for module in t.imported_modules:
-            if module not in self.library_modules:
-                self.library_modules.append(module)
-                #imported_js.update(set(t.imported_js))
-                #imported_modules_str += self._translate(
-                #    module, False, debug=debug, imported_js=imported_js)
-
-        return imported_modules_str + module_str
-
-
-    def translate(self, module_name, is_app=True, debug=False,
-                  library_modules=[]):
-        app_code = cStringIO.StringIO()
-        lib_code = cStringIO.StringIO()
-        imported_js = set()
-        self.library_modules = []
-        self.overrides = {}
-        for library in library_modules:
-            if library.endswith(".js"):
-                imported_js.add(library)
-                continue
-            self.library_modules.append(library)
-            if self.verbose:
-                print 'Including LIB', library
-            print >> lib_code, '\n//\n// BEGIN LIB '+library+'\n//\n'
-            print >> lib_code, self._translate(
-                library, False, debug=debug, imported_js=imported_js)
-
-            print >> lib_code, "/* initialize static library */"
-            print >> lib_code, "%s%s();\n" % (UU, library)
-
-            print >> lib_code, '\n//\n// END LIB '+library+'\n//\n'
-        if module_name:
-            print >> app_code, self._translate(
-                module_name, is_app, debug=debug, imported_js=imported_js)
-        for js in imported_js:
-           path = self.findFile(js)
-           if os.path.isfile(path):
-              if self.verbose:
-                  print 'Including JS', js
-              print >> lib_code,  '\n//\n// BEGIN JS '+js+'\n//\n'
-              print >> lib_code, file(path).read()
-              print >> lib_code,  '\n//\n// END JS '+js+'\n//\n'
-           else:
-              print >>sys.stderr, 'Warning: Unable to find imported javascript:', js
-        return lib_code.getvalue(), app_code.getvalue()
-
-usage = """
-  usage: %s file_name [module_name]
-"""
-
-def main():
-    import sys
-    if len(sys.argv)<2:
-        print >> sys.stderr, usage % sys.argv[0]
-        sys.exit(1)
-    file_name = os.path.abspath(sys.argv[1])
-    if not os.path.isfile(file_name):
-        print >> sys.stderr, "File not found %s" % file_name
-        sys.exit(1)
-    if len(sys.argv) > 2:
-        module_name = sys.argv[2]
-    else:
-        module_name = None
-    print translate(file_name, module_name),
-
-if __name__ == "__main__":
-    main()
-