svgui/pyjs/pyjs.py
changeset 1784 64beb9e9c749
parent 1783 3311eea28d56
child 1785 0ff2a45dcefa
equal deleted inserted replaced
1729:31e63e25b4cc 1784:64beb9e9c749
    18 from types import StringType
    18 from types import StringType
    19 import compiler
    19 import compiler
    20 from compiler import ast
    20 from compiler import ast
    21 import os
    21 import os
    22 import copy
    22 import copy
       
    23 import cStringIO
    23 
    24 
    24 # the standard location for builtins (e.g. pyjslib) can be
    25 # the standard location for builtins (e.g. pyjslib) can be
    25 # over-ridden by changing this.  it defaults to sys.prefix
    26 # over-ridden by changing this.  it defaults to sys.prefix
    26 # so that on a system-wide install of pyjamas the builtins
    27 # so that on a system-wide install of pyjamas the builtins
    27 # can be found in e.g. {sys.prefix}/share/pyjamas
    28 # can be found in e.g. {sys.prefix}/share/pyjamas
    29 # over-rides can be done by either explicitly modifying
    30 # over-rides can be done by either explicitly modifying
    30 # pyjs.prefix or by setting an environment variable, PYJSPREFIX.
    31 # pyjs.prefix or by setting an environment variable, PYJSPREFIX.
    31 
    32 
    32 prefix = sys.prefix
    33 prefix = sys.prefix
    33 
    34 
    34 if os.environ.has_key('PYJSPREFIX'):
    35 if 'PYJSPREFIX' in os.environ:
    35     prefix = os.environ['PYJSPREFIX']
    36     prefix = os.environ['PYJSPREFIX']
    36 
    37 
    37 # pyjs.path is the list of paths, just like sys.path, from which
    38 # pyjs.path is the list of paths, just like sys.path, from which
    38 # library modules will be searched for, for compile purposes.
    39 # library modules will be searched for, for compile purposes.
    39 # obviously we don't want to use sys.path because that would result
    40 # obviously we don't want to use sys.path because that would result
    40 # in compiling standard python modules into javascript!
    41 # in compiling standard python modules into javascript!
    41 
    42 
    42 path = [os.path.abspath('')]
    43 path = [os.path.abspath('')]
    43 
    44 
    44 if os.environ.has_key('PYJSPATH'):
    45 if 'PYJSPATH' in os.environ:
    45     for p in os.environ['PYJSPATH'].split(os.pathsep):
    46     for p in os.environ['PYJSPATH'].split(os.pathsep):
    46         p = os.path.abspath(p)
    47         p = os.path.abspath(p)
    47         if os.path.isdir(p):
    48         if os.path.isdir(p):
    48             path.append(p)
    49             path.append(p)
    49 
    50 
    50 # this is the python function used to wrap native javascript
    51 # this is the python function used to wrap native javascript
    51 NATIVE_JS_FUNC_NAME = "JS"
    52 NATIVE_JS_FUNC_NAME = "JS"
    52 
    53 
    53 UU = ""
    54 UU = ""
    54 
    55 
    55 PYJSLIB_BUILTIN_FUNCTIONS=("cmp",
    56 PYJSLIB_BUILTIN_FUNCTIONS = ("cmp",
    56                            "map",
    57                              "map",
    57                            "filter",
    58                              "filter",
    58                            "dir",
    59                              "dir",
    59                            "getattr",
    60                              "getattr",
    60                            "setattr",
    61                              "setattr",
    61                            "hasattr",
    62                              "hasattr",
    62                            "int",
    63                              "int",
    63                            "float",
    64                              "float",
    64                            "str",
    65                              "str",
    65                            "repr",
    66                              "repr",
    66                            "range",
    67                              "range",
    67                            "len",
    68                              "len",
    68                            "hash",
    69                              "hash",
    69                            "abs",
    70                              "abs",
    70                            "ord",
    71                              "ord",
    71                            "chr",
    72                              "chr",
    72                            "enumerate",
    73                              "enumerate",
    73                            "min",
    74                              "min",
    74                            "max",
    75                              "max",
    75                            "bool",
    76                              "bool",
    76                            "type",
    77                              "type",
    77                            "isinstance")
    78                              "isinstance")
    78 
    79 
    79 PYJSLIB_BUILTIN_CLASSES=("BaseException",
    80 PYJSLIB_BUILTIN_CLASSES = ("BaseException",
    80                          "Exception",
    81                            "Exception",
    81                          "StandardError",
    82                            "StandardError",
    82                          "StopIteration",
    83                            "StopIteration",
    83                          "AttributeError",
    84                            "AttributeError",
    84                          "TypeError",
    85                            "TypeError",
    85                          "KeyError",
    86                            "KeyError",
    86                          "LookupError",
    87                            "LookupError",
    87                          "list",
    88                            "list",
    88                          "dict",
    89                            "dict",
    89                          "object",
    90                            "object",
    90                          "tuple",
    91                            "tuple")
    91                         )
    92 
    92 
    93 
    93 def pyjs_builtin_remap(name):
    94 def pyjs_builtin_remap(name):
    94     # XXX HACK!
    95     # XXX HACK!
    95     if name == 'list':
    96     if name == 'list':
    96         name = 'List'
    97         name = 'List'
   100         name = 'Dict'
   101         name = 'Dict'
   101     if name == 'tuple':
   102     if name == 'tuple':
   102         name = 'Tuple'
   103         name = 'Tuple'
   103     return name
   104     return name
   104 
   105 
       
   106 
   105 # XXX: this is a hack: these should be dealt with another way
   107 # XXX: this is a hack: these should be dealt with another way
   106 # however, console is currently the only global name which is causing
   108 # however, console is currently the only global name which is causing
   107 # problems.
   109 # problems.
   108 PYJS_GLOBAL_VARS=("console")
   110 PYJS_GLOBAL_VARS = ("console")
   109 
   111 
   110 # This is taken from the django project.
   112 # This is taken from the django project.
   111 # Escape every ASCII character with a value less than 32.
   113 # Escape every ASCII character with a value less than 32.
   112 JS_ESCAPES = (
   114 JS_ESCAPES = (
   113     ('\\', r'\x5C'),
   115     ('\\', r'\x5C'),
   117     ('<', r'\x3C'),
   119     ('<', r'\x3C'),
   118     ('&', r'\x26'),
   120     ('&', r'\x26'),
   119     (';', r'\x3B')
   121     (';', r'\x3B')
   120     ) + tuple([('%c' % z, '\\x%02X' % z) for z in range(32)])
   122     ) + tuple([('%c' % z, '\\x%02X' % z) for z in range(32)])
   121 
   123 
       
   124 
   122 def escapejs(value):
   125 def escapejs(value):
   123     """Hex encodes characters for use in JavaScript strings."""
   126     """Hex encodes characters for use in JavaScript strings."""
   124     for bad, good in JS_ESCAPES:
   127     for bad, good in JS_ESCAPES:
   125         value = value.replace(bad, good)
   128         value = value.replace(bad, good)
   126     return value
   129     return value
   127 
   130 
       
   131 
   128 def uuprefix(name, leave_alone=0):
   132 def uuprefix(name, leave_alone=0):
   129     name = name.split(".")
   133     name = name.split(".")
   130     name = name[:leave_alone] + map(lambda x: "__%s" % x, name[leave_alone:])
   134     name = name[:leave_alone] + map(lambda x: "__%s" % x, name[leave_alone:])
   131     return '.'.join(name)
   135     return '.'.join(name)
       
   136 
   132 
   137 
   133 class Klass:
   138 class Klass:
   134 
   139 
   135     klasses = {}
   140     klasses = {}
   136 
   141 
   152         self.message = "line %s:\n%s\n%s" % (node.lineno, message, node)
   157         self.message = "line %s:\n%s\n%s" % (node.lineno, message, node)
   153 
   158 
   154     def __str__(self):
   159     def __str__(self):
   155         return self.message
   160         return self.message
   156 
   161 
       
   162 
   157 def strip_py(name):
   163 def strip_py(name):
   158     return name
   164     return name
       
   165 
   159 
   166 
   160 def mod_var_name_decl(raw_module_name):
   167 def mod_var_name_decl(raw_module_name):
   161     """ function to get the last component of the module e.g.
   168     """ function to get the last component of the module e.g.
   162         pyjamas.ui.DOM into the "namespace".  i.e. doing
   169         pyjamas.ui.DOM into the "namespace".  i.e. doing
   163         "import pyjamas.ui.DOM" actually ends up with _two_
   170         "import pyjamas.ui.DOM" actually ends up with _two_
   172     if len(name) == 1:
   179     if len(name) == 1:
   173         return ''
   180         return ''
   174     child_name = name[-1]
   181     child_name = name[-1]
   175     return "var %s = %s;\n" % (child_name, raw_module_name)
   182     return "var %s = %s;\n" % (child_name, raw_module_name)
   176 
   183 
       
   184 
   177 def gen_mod_import(parentName, importName, dynamic=1):
   185 def gen_mod_import(parentName, importName, dynamic=1):
   178     #pyjs_ajax_eval("%(n)s.cache.js", null, true);
   186     # pyjs_ajax_eval("%(n)s.cache.js", null, true);
   179     return """
   187     return """
   180     pyjslib.import_module(sys.loadpath, '%(p)s', '%(n)s', %(d)d, false);
   188     pyjslib.import_module(sys.loadpath, '%(p)s', '%(n)s', %(d)d, false);
   181     """ % ({'p': parentName, 'd': dynamic, 'n': importName}) + \
   189     """ % ({'p': parentName, 'd': dynamic, 'n': importName}) + \
   182     mod_var_name_decl(importName)
   190         mod_var_name_decl(importName)
       
   191 
   183 
   192 
   184 class Translator:
   193 class Translator:
   185 
   194 
   186     def __init__(self, mn, module_name, raw_module_name, src, debug, mod, output,
   195     def __init__(self, mn, module_name, raw_module_name, src, debug, mod, output,
   187                  dynamic=0, optimize=False,
   196                  dynamic=0, optimize=False,
   226 
   235 
   227         decl = mod_var_name_decl(raw_module_name)
   236         decl = mod_var_name_decl(raw_module_name)
   228         if decl:
   237         if decl:
   229             print >>self.output, decl
   238             print >>self.output, decl
   230 
   239 
   231 
       
   232         if self.debug:
   240         if self.debug:
   233             haltException = self.module_prefix + "HaltException"
   241             haltException = self.module_prefix + "HaltException"
   234             print >>self.output, haltException + ' = function () {'
   242             print >>self.output, haltException + ' = function () {'
   235             print >>self.output, '  this.message = "Program Halted";'
   243             print >>self.output, '  this.message = "Program Halted";'
   236             print >>self.output, '  this.name = "' + haltException + '";'
   244             print >>self.output, '  this.name = "' + haltException + '";'
   271                 self._function(child, False)
   279                 self._function(child, False)
   272             elif isinstance(child, ast.Class):
   280             elif isinstance(child, ast.Class):
   273                 self._class(child)
   281                 self._class(child)
   274             elif isinstance(child, ast.Import):
   282             elif isinstance(child, ast.Import):
   275                 importName = child.names[0][0]
   283                 importName = child.names[0][0]
   276                 if importName == '__pyjamas__': # special module to help make pyjamas modules loadable in the python interpreter
   284                 if importName == '__pyjamas__':  # special module to help make pyjamas modules loadable in the python interpreter
   277                     pass
   285                     pass
   278                 elif importName.endswith('.js'):
   286                 elif importName.endswith('.js'):
   279                    self.imported_js.add(importName)
   287                     self.imported_js.add(importName)
   280                 else:
   288                 else:
   281                    self.add_imported_module(strip_py(importName))
   289                     self.add_imported_module(strip_py(importName))
   282             elif isinstance(child, ast.From):
   290             elif isinstance(child, ast.From):
   283                 if child.modname == '__pyjamas__': # special module to help make pyjamas modules loadable in the python interpreter
   291                 if child.modname == '__pyjamas__':  # special module to help make pyjamas modules loadable in the python interpreter
   284                     pass
   292                     pass
   285                 else:
   293                 else:
   286                     self.add_imported_module(child.modname)
   294                     self.add_imported_module(child.modname)
   287                     self._from(child)
   295                     self._from(child)
   288             elif isinstance(child, ast.Discard):
   296             elif isinstance(child, ast.Discard):
   300             elif isinstance(child, ast.Subscript):
   308             elif isinstance(child, ast.Subscript):
   301                 self._subscript_stmt(child, None)
   309                 self._subscript_stmt(child, None)
   302             elif isinstance(child, ast.Global):
   310             elif isinstance(child, ast.Global):
   303                 self._global(child, None)
   311                 self._global(child, None)
   304             elif isinstance(child, ast.Printnl):
   312             elif isinstance(child, ast.Printnl):
   305                self._print(child, None)
   313                 self._print(child, None)
   306             elif isinstance(child, ast.Print):
   314             elif isinstance(child, ast.Print):
   307                self._print(child, None)
   315                 self._print(child, None)
   308             elif isinstance(child, ast.TryExcept):
   316             elif isinstance(child, ast.TryExcept):
   309                 self._tryExcept(child, None)
   317                 self._tryExcept(child, None)
   310             elif isinstance(child, ast.Raise):
   318             elif isinstance(child, ast.Raise):
   311                 self._raise(child, None)
   319                 self._raise(child, None)
   312             elif isinstance(child, ast.Stmt):
   320             elif isinstance(child, ast.Stmt):
   313                 self._stmt(child, None)
   321                 self._stmt(child, None)
   314             else:
   322             else:
   315                 raise TranslationError("unsupported type (in __init__)", child)
   323                 raise TranslationError("unsupported type (in __init__)", child)
   316 
   324 
   317         # Initialize all classes for this module
   325         # Initialize all classes for this module
   318         #print >> self.output, "__"+self.modpfx()+\
   326         # print >> self.output, "__"+self.modpfx()+\
   319         #          "classes_initialize = function() {\n"
   327         #          "classes_initialize = function() {\n"
   320         #for className in self.top_level_classes:
   328         # for className in self.top_level_classes:
   321         #    print >> self.output, "\t"+UU+self.modpfx()+"__"+className+"_initialize();"
   329         #    print >> self.output, "\t"+UU+self.modpfx()+"__"+className+"_initialize();"
   322         #print >> self.output, "};\n"
   330         # print >> self.output, "};\n"
   323 
   331 
   324         print >> self.output, "return this;\n"
   332         print >> self.output, "return this;\n"
   325         print >> self.output, "}; /* end %s */ \n"  % module_name
   333         print >> self.output, "}; /* end %s */ \n" % module_name
   326 
   334 
   327     def module_imports(self):
   335     def module_imports(self):
   328         return self.imported_modules + self.imported_modules_as
   336         return self.imported_modules + self.imported_modules_as
   329 
   337 
   330     def add_local_arg(self, varname):
   338     def add_local_arg(self, varname):
   343             # but don't add the short name to imported_modules
   351             # but don't add the short name to imported_modules
   344             # because then the short name would be attempted to be
   352             # because then the short name would be attempted to be
   345             # added to the dependencies, and it's half way up the
   353             # added to the dependencies, and it's half way up the
   346             # module import directory structure!
   354             # module import directory structure!
   347             child_name = name[-1]
   355             child_name = name[-1]
   348             self.imported_modules_as.append(child_name) 
   356             self.imported_modules_as.append(child_name)
   349         print >> self.output, gen_mod_import(self.raw_module_name,
   357         print >> self.output, gen_mod_import(self.raw_module_name,
   350                                              strip_py(importName),
   358                                              strip_py(importName),
   351                                              self.dynamic)
   359                                              self.dynamic)
   352 
   360 
   353     def _default_args_handler(self, node, arg_names, current_klass,
   361     def _default_args_handler(self, node, arg_names, current_klass,
   394 #                    default_value = self._unarysub(default_node, current_klass)
   402 #                    default_value = self._unarysub(default_node, current_klass)
   395 #                else:
   403 #                else:
   396 #                    raise TranslationError("unsupported type (in _method)", default_node)
   404 #                    raise TranslationError("unsupported type (in _method)", default_node)
   397 
   405 
   398                 default_name = arg_names[default_pos]
   406                 default_name = arg_names[default_pos]
   399                 print >>self.output, "    if (typeof %s == 'undefined')"%(default_name)
   407                 print >>self.output, "    if (typeof %s == 'undefined')" % (default_name)
   400                 print >>self.output, "        %s=__kwargs.%s;"% (default_name, default_name)
   408                 print >>self.output, "        %s=__kwargs.%s;" % (default_name, default_name)
   401                 default_pos += 1
   409                 default_pos += 1
   402 
   410 
   403             #self._default_args_handler(node, arg_names, current_klass)
   411             # self._default_args_handler(node, arg_names, current_klass)
   404             if node.kwargs: arg_names += ["pyjslib.Dict(__kwargs)"]
   412             if node.kwargs:
       
   413                 arg_names += ["pyjslib.Dict(__kwargs)"]
   405             print >>self.output, "    var __r = "+"".join(["[", ", ".join(arg_names), "]"])+";"
   414             print >>self.output, "    var __r = "+"".join(["[", ", ".join(arg_names), "]"])+";"
   406             if node.varargs:
   415             if node.varargs:
   407                 self._varargs_handler(node, "__args", arg_names, current_klass)
   416                 self._varargs_handler(node, "__args", arg_names, current_klass)
   408                 print >>self.output, "    __r.push.apply(__r, __args.getArray())"
   417                 print >>self.output, "    __r.push.apply(__r, __args.getArray())"
   409             print >>self.output, "    return __r;"
   418             print >>self.output, "    return __r;"
   416         else:
   425         else:
   417             function_name = UU + self.modpfx() + node.name
   426             function_name = UU + self.modpfx() + node.name
   418 
   427 
   419         arg_names = list(node.argnames)
   428         arg_names = list(node.argnames)
   420         normal_arg_names = list(arg_names)
   429         normal_arg_names = list(arg_names)
   421         if node.kwargs: kwargname = normal_arg_names.pop()
   430         if node.kwargs:
   422         if node.varargs: varargname = normal_arg_names.pop()
   431             kwargname = normal_arg_names.pop()
       
   432         if node.varargs:
       
   433             varargname = normal_arg_names.pop()
   423         declared_arg_names = list(normal_arg_names)
   434         declared_arg_names = list(normal_arg_names)
   424         if node.kwargs: declared_arg_names.append(kwargname)
   435         if node.kwargs:
       
   436             declared_arg_names.append(kwargname)
   425 
   437 
   426         function_args = "(" + ", ".join(declared_arg_names) + ")"
   438         function_args = "(" + ", ".join(declared_arg_names) + ")"
   427         print >>self.output, "%s = function%s {" % (function_name, function_args)
   439         print >>self.output, "%s = function%s {" % (function_name, function_args)
   428         self._default_args_handler(node, normal_arg_names, None)
   440         self._default_args_handler(node, normal_arg_names, None)
   429 
   441 
   430         local_arg_names = normal_arg_names + declared_arg_names 
   442         local_arg_names = normal_arg_names + declared_arg_names
   431 
   443 
   432         if node.varargs:
   444         if node.varargs:
   433             self._varargs_handler(node, varargname, declared_arg_names, None)
   445             self._varargs_handler(node, varargname, declared_arg_names, None)
   434             local_arg_names.append(varargname)
   446             local_arg_names.append(varargname)
   435 
   447 
   449                 print >>self.output, "    return null;"
   461                 print >>self.output, "    return null;"
   450 
   462 
   451         print >>self.output, "};"
   463         print >>self.output, "};"
   452         print >>self.output, "%s.__name__ = '%s';\n" % (function_name, node.name)
   464         print >>self.output, "%s.__name__ = '%s';\n" % (function_name, node.name)
   453 
   465 
   454 
       
   455         self._kwargs_parser(node, function_name, normal_arg_names, None)
   466         self._kwargs_parser(node, function_name, normal_arg_names, None)
   456 
       
   457 
   467 
   458     def _return(self, node, current_klass):
   468     def _return(self, node, current_klass):
   459         expr = self.expr(node.value, current_klass)
   469         expr = self.expr(node.value, current_klass)
   460         # in python a function call always returns None, so we do it
   470         # in python a function call always returns None, so we do it
   461         # here too
   471         # here too
   462         print >>self.output, "    return " + expr + ";"
   472         print >>self.output, "    return " + expr + ";"
   463 
   473 
   464 
       
   465     def _break(self, node, current_klass):
   474     def _break(self, node, current_klass):
   466         print >>self.output, "    break;"
   475         print >>self.output, "    break;"
   467 
   476 
   468 
       
   469     def _continue(self, node, current_klass):
   477     def _continue(self, node, current_klass):
   470         print >>self.output, "    continue;"
   478         print >>self.output, "    continue;"
   471 
       
   472 
   479 
   473     def _callfunc(self, v, current_klass):
   480     def _callfunc(self, v, current_klass):
   474 
   481 
   475         if isinstance(v.node, ast.Name):
   482         if isinstance(v.node, ast.Name):
   476             if v.node.name in self.top_level_functions:
   483             if v.node.name in self.top_level_functions:
   477                 call_name = self.modpfx() + v.node.name
   484                 call_name = self.modpfx() + v.node.name
   478             elif v.node.name in self.top_level_classes:
   485             elif v.node.name in self.top_level_classes:
   479                 call_name = self.modpfx() + v.node.name
   486                 call_name = self.modpfx() + v.node.name
   480             elif self.imported_classes.has_key(v.node.name):
   487             elif v.node.name in self.imported_classes:
   481                 call_name = self.imported_classes[v.node.name] + '.' + v.node.name
   488                 call_name = self.imported_classes[v.node.name] + '.' + v.node.name
   482             elif v.node.name in PYJSLIB_BUILTIN_FUNCTIONS:
   489             elif v.node.name in PYJSLIB_BUILTIN_FUNCTIONS:
   483                 call_name = 'pyjslib.' + v.node.name
   490                 call_name = 'pyjslib.' + v.node.name
   484             elif v.node.name in PYJSLIB_BUILTIN_CLASSES:
   491             elif v.node.name in PYJSLIB_BUILTIN_CLASSES:
   485                 name = pyjs_builtin_remap(v.node.name)
   492                 name = pyjs_builtin_remap(v.node.name)
   533             fn_args = ", ".join(call_args)
   540             fn_args = ", ".join(call_args)
   534 
   541 
   535         if kwargs or star_arg_name:
   542         if kwargs or star_arg_name:
   536             if not star_arg_name:
   543             if not star_arg_name:
   537                 star_arg_name = 'null'
   544                 star_arg_name = 'null'
   538             try: call_this, method_name = call_name.rsplit(".", 1)
   545             try:
       
   546                 call_this, method_name = call_name.rsplit(".", 1)
   539             except ValueError:
   547             except ValueError:
   540                 # Must be a function call ...
   548                 # Must be a function call ...
   541                 return ("pyjs_kwargs_function_call("+call_name+", "
   549                 return ("pyjs_kwargs_function_call("+call_name+", "
   542                                   + star_arg_name 
   550                         + star_arg_name + ", ["+fn_args+"]" + ")")
   543                                   + ", ["+fn_args+"]"
       
   544                                   + ")" )
       
   545             else:
   551             else:
   546                 return ("pyjs_kwargs_method_call("+call_this+", '"+method_name+"', "
   552                 return ("pyjs_kwargs_method_call("+call_this+", '"+method_name+"', "
   547                                   + star_arg_name 
   553                         + star_arg_name + ", ["+fn_args+"]" + ")")
   548                                   + ", ["+fn_args+"]"
       
   549                                   + ")")
       
   550         else:
   554         else:
   551             return call_name + "(" + ", ".join(call_args) + ")"
   555             return call_name + "(" + ", ".join(call_args) + ")"
   552 
   556 
   553     def _print(self, node, current_klass):
   557     def _print(self, node, current_klass):
   554         if self.optimize:
   558         if self.optimize:
   579         print >>self.output, "    try {"
   583         print >>self.output, "    try {"
   580         for stmt in node.body.nodes:
   584         for stmt in node.body.nodes:
   581             self._stmt(stmt, current_klass)
   585             self._stmt(stmt, current_klass)
   582         print >> self.output, "    } catch(%s) {" % errName
   586         print >> self.output, "    } catch(%s) {" % errName
   583         if expr:
   587         if expr:
   584             l = []
   588             k = []
   585             if isinstance(expr, ast.Tuple):
   589             if isinstance(expr, ast.Tuple):
   586                 for x in expr.nodes:
   590                 for x in expr.nodes:
   587                     l.append("(%(err)s.__name__ == %(expr)s.__name__)" % dict (err=errName, expr=self.expr(x, current_klass)))
   591                     k.append("(%(err)s.__name__ == %(expr)s.__name__)" % dict(err=errName, expr=self.expr(x, current_klass)))
   588             else:
   592             else:
   589                 l = [ " (%(err)s.__name__ == %(expr)s.__name__) " % dict (err=errName, expr=self.expr(expr, current_klass)) ]
   593                 k = [" (%(err)s.__name__ == %(expr)s.__name__) " % dict(err=errName, expr=self.expr(expr, current_klass))]
   590             print >> self.output, "   if(%s) {" % '||\n\t\t'.join(l)
   594             print >> self.output, "   if(%s) {" % '||\n\t\t'.join(k)
   591         for stmt in node.handlers[0][2]:
   595         for stmt in node.handlers[0][2]:
   592             self._stmt(stmt, current_klass)
   596             self._stmt(stmt, current_klass)
   593         if expr:
   597         if expr:
   594             #print >> self.output, "} else { throw(%s); } " % errName
   598             # print >> self.output, "} else { throw(%s); } " % errName
   595             print >> self.output, "}"
   599             print >> self.output, "}"
   596         if node.else_ != None:
   600         if node.else_ is not None:
   597             print >>self.output, "    } finally {"
   601             print >>self.output, "    } finally {"
   598             for stmt in node.else_:
   602             for stmt in node.else_:
   599                 self._stmt(stmt, current_klass)
   603                 self._stmt(stmt, current_klass)
   600         print >>self.output, "    }"
   604         print >>self.output, "    }"
   601 
   605 
   603     # but incurring a 100% performance penalty. oops.
   607     # but incurring a 100% performance penalty. oops.
   604     def _getattr(self, v, current_klass, use_getattr=False):
   608     def _getattr(self, v, current_klass, use_getattr=False):
   605         attr_name = v.attrname
   609         attr_name = v.attrname
   606         if isinstance(v.expr, ast.Name):
   610         if isinstance(v.expr, ast.Name):
   607             obj = self._name(v.expr, current_klass, return_none_for_module=True)
   611             obj = self._name(v.expr, current_klass, return_none_for_module=True)
   608             if obj == None and v.expr.name in self.module_imports():
   612             if obj is None and v.expr.name in self.module_imports():
   609                 # XXX TODO: distinguish between module import classes
   613                 # XXX TODO: distinguish between module import classes
   610                 # and variables.  right now, this is a hack to get
   614                 # and variables.  right now, this is a hack to get
   611                 # the sys module working.
   615                 # the sys module working.
   612                 #if v.expr.name == 'sys':
   616                 # if v.expr.name == 'sys':
   613                 return v.expr.name+'.'+attr_name
   617                 return v.expr.name+'.'+attr_name
   614                 #return v.expr.name+'.__'+attr_name+'.prototype.__class__'
   618                 # return v.expr.name+'.__'+attr_name+'.prototype.__class__'
   615             if not use_getattr or attr_name == '__class__' or \
   619             if not use_getattr or attr_name == '__class__' or \
   616                     attr_name == '__name__':
   620                     attr_name == '__name__':
   617                 return obj + "." + attr_name
   621                 return obj + "." + attr_name
   618             return "pyjslib.getattr(%s, '%s')" % (obj, attr_name)
   622             return "pyjslib.getattr(%s, '%s')" % (obj, attr_name)
   619         elif isinstance(v.expr, ast.Getattr):
   623         elif isinstance(v.expr, ast.Getattr):
   623         elif isinstance(v.expr, ast.CallFunc):
   627         elif isinstance(v.expr, ast.CallFunc):
   624             return self._callfunc(v.expr, self.modpfx()) + "." + attr_name
   628             return self._callfunc(v.expr, self.modpfx()) + "." + attr_name
   625         else:
   629         else:
   626             raise TranslationError("unsupported type (in _getattr)", v.expr)
   630             raise TranslationError("unsupported type (in _getattr)", v.expr)
   627 
   631 
   628 
       
   629     def modpfx(self):
   632     def modpfx(self):
   630         return strip_py(self.module_prefix)
   633         return strip_py(self.module_prefix)
   631         
   634 
   632     def _name(self, v, current_klass, top_level=False,
   635     def _name(self, v, current_klass, top_level=False,
   633                                       return_none_for_module=False):
   636               return_none_for_module=False):
   634 
   637 
   635         if v.name == 'ilikesillynamesfornicedebugcode':
   638         if v.name == 'ilikesillynamesfornicedebugcode':
   636             print top_level, current_klass, repr(v)
   639             print top_level, current_klass, repr(v)
   637             print self.top_level_vars
   640             print self.top_level_vars
   638             print self.top_level_functions
   641             print self.top_level_functions
   660             return UU+self.modpfx() + v.name
   663             return UU+self.modpfx() + v.name
   661         elif not current_klass and las == 1 and v.name in self.top_level_vars:
   664         elif not current_klass and las == 1 and v.name in self.top_level_vars:
   662             return UU+self.modpfx() + v.name
   665             return UU+self.modpfx() + v.name
   663         elif v.name in local_var_names:
   666         elif v.name in local_var_names:
   664             return v.name
   667             return v.name
   665         elif self.imported_classes.has_key(v.name):
   668         elif v.name in self.imported_classes:
   666             return UU+self.imported_classes[v.name] + '.__' + v.name + ".prototype.__class__"
   669             return UU+self.imported_classes[v.name] + '.__' + v.name + ".prototype.__class__"
   667         elif v.name in self.top_level_classes:
   670         elif v.name in self.top_level_classes:
   668             return UU+self.modpfx() + "__" + v.name + ".prototype.__class__"
   671             return UU+self.modpfx() + "__" + v.name + ".prototype.__class__"
   669         elif v.name in self.module_imports() and return_none_for_module:
   672         elif v.name in self.module_imports() and return_none_for_module:
   670             return None
   673             return None
   671         elif v.name in PYJSLIB_BUILTIN_CLASSES:
   674         elif v.name in PYJSLIB_BUILTIN_CLASSES:
   672             return "pyjslib." + pyjs_builtin_remap( v.name )
   675             return "pyjslib." + pyjs_builtin_remap(v.name)
   673         elif current_klass:
   676         elif current_klass:
   674             if v.name not in local_var_names and \
   677             if v.name not in local_var_names and \
   675                v.name not in self.top_level_vars and \
   678                v.name not in self.top_level_vars and \
   676                v.name not in PYJS_GLOBAL_VARS and \
   679                v.name not in PYJS_GLOBAL_VARS and \
   677                v.name not in self.top_level_functions:
   680                v.name not in self.top_level_functions:
   679                 cls_name = current_klass
   682                 cls_name = current_klass
   680                 if hasattr(cls_name, "name"):
   683                 if hasattr(cls_name, "name"):
   681                     cls_name_ = cls_name.name_
   684                     cls_name_ = cls_name.name_
   682                     cls_name = cls_name.name
   685                     cls_name = cls_name.name
   683                 else:
   686                 else:
   684                     cls_name_ = current_klass + "_" # XXX ???
   687                     cls_name_ = current_klass + "_"  # XXX ???
   685                 name = UU+cls_name_ + ".prototype.__class__." \
   688                 name = UU+cls_name_ + ".prototype.__class__." + v.name
   686                                    + v.name
       
   687                 if v.name == 'listener':
   689                 if v.name == 'listener':
   688                     name = 'listener+' + name
   690                     name = 'listener+' + name
   689                 return name
   691                 return name
   690 
   692 
   691         return v.name
   693         return v.name
   693     def _name2(self, v, current_klass, attr_name):
   695     def _name2(self, v, current_klass, attr_name):
   694         obj = v.name
   696         obj = v.name
   695 
   697 
   696         if obj in self.method_imported_globals:
   698         if obj in self.method_imported_globals:
   697             call_name = UU+self.modpfx() + obj + "." + attr_name
   699             call_name = UU+self.modpfx() + obj + "." + attr_name
   698         elif self.imported_classes.has_key(obj):
   700         elif obj in self.imported_classes:
   699             #attr_str = ""
   701             # attr_str = ""
   700             #if attr_name != "__init__":
   702             # if attr_name != "__init__":
   701             attr_str = ".prototype.__class__." + attr_name
   703             attr_str = ".prototype.__class__." + attr_name
   702             call_name = UU+self.imported_classes[obj] + '.__' + obj + attr_str
   704             call_name = UU+self.imported_classes[obj] + '.__' + obj + attr_str
   703         elif obj in self.module_imports():
   705         elif obj in self.module_imports():
   704             call_name = obj + "." + attr_name
   706             call_name = obj + "." + attr_name
   705         elif obj[0] == obj[0].upper(): # XXX HACK ALERT
   707         elif obj[0] == obj[0].upper():  # XXX HACK ALERT
   706             call_name = UU + self.modpfx() + "__" + obj + ".prototype.__class__." + attr_name
   708             call_name = UU + self.modpfx() + "__" + obj + ".prototype.__class__." + attr_name
   707         else:
   709         else:
   708             call_name = UU+self._name(v, current_klass) + "." + attr_name
   710             call_name = UU+self._name(v, current_klass) + "." + attr_name
   709 
   711 
   710         return call_name
   712         return call_name
   711 
       
   712 
   713 
   713     def _getattr2(self, v, current_klass, attr_name):
   714     def _getattr2(self, v, current_klass, attr_name):
   714         if isinstance(v.expr, ast.Getattr):
   715         if isinstance(v.expr, ast.Getattr):
   715             call_name = self._getattr2(v.expr, current_klass, v.attrname + "." + attr_name)
   716             call_name = self._getattr2(v.expr, current_klass, v.attrname + "." + attr_name)
   716         elif isinstance(v.expr, ast.Name) and v.expr.name in self.module_imports():
   717         elif isinstance(v.expr, ast.Name) and v.expr.name in self.module_imports():
   717             call_name = UU+v.expr.name + '.__' +v.attrname+".prototype.__class__."+attr_name
   718             call_name = UU+v.expr.name + '.__' + v.attrname+".prototype.__class__."+attr_name
   718         else:
   719         else:
   719             obj = self.expr(v.expr, current_klass)
   720             obj = self.expr(v.expr, current_klass)
   720             call_name = obj + "." + v.attrname + "." + attr_name
   721             call_name = obj + "." + v.attrname + "." + attr_name
   721 
   722 
   722         return call_name
   723         return call_name
   723 
       
   724 
   724 
   725     def _class(self, node):
   725     def _class(self, node):
   726         """
   726         """
   727         Handle a class definition.
   727         Handle a class definition.
   728 
   728 
   759             if isinstance(child, ast.Function):
   759             if isinstance(child, ast.Function):
   760                 current_klass.add_function(child.name)
   760                 current_klass.add_function(child.name)
   761                 if child.name == "__init__":
   761                 if child.name == "__init__":
   762                     init_method = child
   762                     init_method = child
   763 
   763 
   764 
       
   765         if len(node.bases) == 0:
   764         if len(node.bases) == 0:
   766             base_class = "pyjslib.__Object"
   765             base_class = "pyjslib.__Object"
   767         elif len(node.bases) == 1:
   766         elif len(node.bases) == 1:
   768             if isinstance(node.bases[0], ast.Name):
   767             if isinstance(node.bases[0], ast.Name):
   769                 if self.imported_classes.has_key(node.bases[0].name):
   768                 if node.bases[0].name in self.imported_classes:
   770                     base_class_ = self.imported_classes[node.bases[0].name] + '.__' + node.bases[0].name
   769                     base_class_ = self.imported_classes[node.bases[0].name] + '.__' + node.bases[0].name
   771                     base_class = self.imported_classes[node.bases[0].name] + '.' + node.bases[0].name
   770                     base_class = self.imported_classes[node.bases[0].name] + '.' + node.bases[0].name
   772                 else:
   771                 else:
   773                     base_class_ = self.modpfx() + "__" + node.bases[0].name
   772                     base_class_ = self.modpfx() + "__" + node.bases[0].name
   774                     base_class = self.modpfx() + node.bases[0].name
   773                     base_class = self.modpfx() + node.bases[0].name
   775             elif isinstance(node.bases[0], ast.Getattr):
   774             elif isinstance(node.bases[0], ast.Getattr):
   776                 # the bases are not in scope of the class so do not
   775                 # the bases are not in scope of the class so do not
   777                 # pass our class to self._name
   776                 # pass our class to self._name
   778                 base_class_ = self._name(node.bases[0].expr, None) + \
   777                 base_class_ = self._name(node.bases[0].expr, None) + \
   779                              ".__" + node.bases[0].attrname
   778                              ".__" + node.bases[0].attrname
   780                 base_class = self._name(node.bases[0].expr, None) + \
   779                 base_class = \
   781                              "." + node.bases[0].attrname
   780                     self._name(node.bases[0].expr, None) + \
       
   781                     "." + node.bases[0].attrname
   782             else:
   782             else:
   783                 raise TranslationError("unsupported type (in _class)", node.bases[0])
   783                 raise TranslationError("unsupported type (in _class)", node.bases[0])
   784 
   784 
   785             current_klass.set_base(base_class)
   785             current_klass.set_base(base_class)
   786         else:
   786         else:
   787             raise TranslationError("more than one base (in _class)", node)
   787             raise TranslationError("more than one base (in _class)", node)
   788 
   788 
   789         print >>self.output, UU+class_name_ + " = function () {"
   789         print >>self.output, UU+class_name_ + " = function () {"
   790         # call superconstructor
   790         # call superconstructor
   791         #if base_class:
   791         # if base_class:
   792         #    print >>self.output, "    __" + base_class + ".call(this);"
   792         #    print >>self.output, "    __" + base_class + ".call(this);"
   793         print >>self.output, "}"
   793         print >>self.output, "}"
   794 
   794 
   795         if not init_method:
   795         if not init_method:
   796             init_method = ast.Function([], "__init__", ["self"], [], 0, None, [])
   796             init_method = ast.Function([], "__init__", ["self"], [], 0, None, [])
   797             #self._method(init_method, current_klass, class_name)
   797             # self._method(init_method, current_klass, class_name)
   798 
   798 
   799         # Generate a function which constructs the object
   799         # Generate a function which constructs the object
   800         clsfunc = ast.Function([],
   800         clsfunc = ast.Function(
   801            node.name,
   801             [], node.name,
   802            init_method.argnames[1:],
   802             init_method.argnames[1:],
   803            init_method.defaults,
   803             init_method.defaults,
   804            init_method.flags,
   804             init_method.flags,
   805            None,
   805             None,
   806            [ast.Discard(ast.CallFunc(ast.Name("JS"), [ast.Const(
   806             [ast.Discard(ast.CallFunc(ast.Name("JS"), [ast.Const(
   807 #            I attempted lazy initialization, but then you can't access static class members
   807                 #            I attempted lazy initialization, but then you can't access static class members
   808 #            "    if(!__"+base_class+".__was_initialized__)"+
   808                 #            "    if(!__"+base_class+".__was_initialized__)"+
   809 #            "        __" + class_name + "_initialize();\n" +
   809                 #            "        __" + class_name + "_initialize();\n" +
   810             "    var instance = new " + UU + class_name_ + "();\n" +
   810                 "    var instance = new " + UU + class_name_ + "();\n" +
   811             "    if(instance.__init__) instance.__init__.apply(instance, arguments);\n" +
   811                 "    if(instance.__init__) instance.__init__.apply(instance, arguments);\n" +
   812             "    return instance;"
   812                 "    return instance;"
   813             )]))])
   813             )]))])
   814 
   814 
   815         self._function(clsfunc, False)
   815         self._function(clsfunc, False)
   816         print >>self.output, UU+class_name_ + ".__initialize__ = function () {"
   816         print >>self.output, UU+class_name_ + ".__initialize__ = function () {"
   817         print >>self.output, "    if("+UU+class_name_+".__was_initialized__) return;"
   817         print >>self.output, "    if("+UU+class_name_+".__was_initialized__) return;"
   845                 raise TranslationError("unsupported type (in _class)", child)
   845                 raise TranslationError("unsupported type (in _class)", child)
   846         print >>self.output, "}"
   846         print >>self.output, "}"
   847 
   847 
   848         print >> self.output, class_name_+".__initialize__();"
   848         print >> self.output, class_name_+".__initialize__();"
   849 
   849 
   850 
       
   851     def classattr(self, node, current_klass):
   850     def classattr(self, node, current_klass):
   852         self._assign(node, current_klass, True)
   851         self._assign(node, current_klass, True)
   853 
   852 
   854     def _raise(self, node, current_klass):
   853     def _raise(self, node, current_klass):
   855         if node.expr2:
   854         if node.expr2:
   874                     staticmethod = True
   873                     staticmethod = True
   875 
   874 
   876         if staticmethod:
   875         if staticmethod:
   877             staticfunc = ast.Function([], class_name_+"."+node.name, node.argnames, node.defaults, node.flags, node.doc, node.code, node.lineno)
   876             staticfunc = ast.Function([], class_name_+"."+node.name, node.argnames, node.defaults, node.flags, node.doc, node.code, node.lineno)
   878             self._function(staticfunc, True)
   877             self._function(staticfunc, True)
   879             print >>self.output, "    " + UU+class_name_ + ".prototype.__class__." + node.name + " = " + class_name_+"."+node.name+";";
   878             print >>self.output, "    " + UU+class_name_ + ".prototype.__class__." + node.name + " = " + class_name_+"."+node.name+";"
   880             print >>self.output, "    " + UU+class_name_ + ".prototype.__class__." + node.name + ".static_method = true;";
   879             print >>self.output, "    " + UU+class_name_ + ".prototype.__class__." + node.name + ".static_method = true;"
   881             return
   880             return
   882         else:
   881         else:
   883             if len(arg_names) == 0:
   882             if len(arg_names) == 0:
   884                 raise TranslationError("methods must take an argument 'self' (in _method)", node)
   883                 raise TranslationError("methods must take an argument 'self' (in _method)", node)
   885             self.method_self = arg_names[0]
   884             self.method_self = arg_names[0]
   886 
   885 
   887             #if not classmethod and arg_names[0] != "self":
   886             # if not classmethod and arg_names[0] != "self":
   888             #    raise TranslationError("first arg not 'self' (in _method)", node)
   887             #    raise TranslationError("first arg not 'self' (in _method)", node)
   889 
   888 
   890         normal_arg_names = arg_names[1:]
   889         normal_arg_names = arg_names[1:]
   891         if node.kwargs: kwargname = normal_arg_names.pop()
   890         if node.kwargs:
   892         if node.varargs: varargname = normal_arg_names.pop()
   891             kwargname = normal_arg_names.pop()
       
   892         if node.varargs:
       
   893             varargname = normal_arg_names.pop()
   893         declared_arg_names = list(normal_arg_names)
   894         declared_arg_names = list(normal_arg_names)
   894         if node.kwargs: declared_arg_names.append(kwargname)
   895         if node.kwargs:
       
   896             declared_arg_names.append(kwargname)
   895 
   897 
   896         function_args = "(" + ", ".join(declared_arg_names) + ")"
   898         function_args = "(" + ", ".join(declared_arg_names) + ")"
   897 
   899 
   898         if classmethod:
   900         if classmethod:
   899             fexpr = UU + class_name_ + ".prototype.__class__." + node.name
   901             fexpr = UU + class_name_ + ".prototype.__class__." + node.name
   902         print >>self.output, "    "+fexpr + " = function" + function_args + " {"
   904         print >>self.output, "    "+fexpr + " = function" + function_args + " {"
   903 
   905 
   904         # default arguments
   906         # default arguments
   905         self._default_args_handler(node, normal_arg_names, current_klass)
   907         self._default_args_handler(node, normal_arg_names, current_klass)
   906 
   908 
   907         local_arg_names = normal_arg_names + declared_arg_names 
   909         local_arg_names = normal_arg_names + declared_arg_names
   908 
   910 
   909         if node.varargs:
   911         if node.varargs:
   910             self._varargs_handler(node, varargname, declared_arg_names, current_klass)
   912             self._varargs_handler(node, varargname, declared_arg_names, current_klass)
   911             local_arg_names.append(varargname)
   913             local_arg_names.append(varargname)
   912 
       
   913 
   914 
   914         # stack of local variable names for this function call
   915         # stack of local variable names for this function call
   915         self.local_arg_stack.append(local_arg_names)
   916         self.local_arg_stack.append(local_arg_names)
   916 
   917 
   917         for child in node.code:
   918         for child in node.code:
   942             print >>self.output, "    "+altexpr+".unbound_method = true;"
   943             print >>self.output, "    "+altexpr+".unbound_method = true;"
   943             print >>self.output, "    "+fexpr+".instance_method = true;"
   944             print >>self.output, "    "+fexpr+".instance_method = true;"
   944             print >>self.output, "    "+altexpr+".__name__ = '%s';" % node.name
   945             print >>self.output, "    "+altexpr+".__name__ = '%s';" % node.name
   945 
   946 
   946         print >>self.output, UU + class_name_ + ".prototype.%s.__name__ = '%s';" % \
   947         print >>self.output, UU + class_name_ + ".prototype.%s.__name__ = '%s';" % \
   947                 (node.name, node.name)
   948             (node.name, node.name)
   948 
   949 
   949         if node.kwargs or len(node.defaults):
   950         if node.kwargs or len(node.defaults):
   950             print >>self.output, "    "+altexpr + ".parse_kwargs = " + fexpr + ".parse_kwargs;"
   951             print >>self.output, "    "+altexpr + ".parse_kwargs = " + fexpr + ".parse_kwargs;"
   951 
   952 
   952         self.method_self = None
   953         self.method_self = None
   990         elif isinstance(node, ast.Pass):
   991         elif isinstance(node, ast.Pass):
   991             pass
   992             pass
   992         elif isinstance(node, ast.Function):
   993         elif isinstance(node, ast.Function):
   993             self._function(node, True)
   994             self._function(node, True)
   994         elif isinstance(node, ast.Printnl):
   995         elif isinstance(node, ast.Printnl):
   995            self._print(node, current_klass)
   996             self._print(node, current_klass)
   996         elif isinstance(node, ast.Print):
   997         elif isinstance(node, ast.Print):
   997            self._print(node, current_klass)
   998             self._print(node, current_klass)
   998         elif isinstance(node, ast.TryExcept):
   999         elif isinstance(node, ast.TryExcept):
   999             self._tryExcept(node, current_klass)
  1000             self._tryExcept(node, current_klass)
  1000         elif isinstance(node, ast.Raise):
  1001         elif isinstance(node, ast.Raise):
  1001             self._raise(node, current_klass)
  1002             self._raise(node, current_klass)
  1002         else:
  1003         else:
  1007             lt = self.get_line_trace(node)
  1008             lt = self.get_line_trace(node)
  1008 
  1009 
  1009             haltException = self.module_prefix + "HaltException"
  1010             haltException = self.module_prefix + "HaltException"
  1010             isHaltFunction = self.module_prefix + "IsHaltException"
  1011             isHaltFunction = self.module_prefix + "IsHaltException"
  1011 
  1012 
  1012             print >>self.output, '  } catch (__err) {'
  1013             out = (
  1013             print >>self.output, '      if (' + isHaltFunction + '(__err.name)) {'
  1014                 '  } catch (__err) {',
  1014             print >>self.output, '          throw __err;'
  1015                 '      if (' + isHaltFunction + '(__err.name)) {',
  1015             print >>self.output, '      } else {'
  1016                 '          throw __err;',
  1016             print >>self.output, "          st = sys.printstack() + "\
  1017                 '      } else {',
  1017                                                 + '"%s"' % lt + "+ '\\n' ;"
  1018                 '          st = sys.printstack() + ' + '"%s"' % lt + "+ '\\n' ;"
  1018             print >>self.output, '          alert("' + "Error in " \
  1019                 '          alert("' + 'Error in ' + lt + '"'
  1019                                                 + lt + '"' \
  1020                 + '+"\\n"+__err.name+": "+__err.message'
  1020                                                 + '+"\\n"+__err.name+": "+__err.message'\
  1021                 + '+"\\n\\nStack trace:\\n"' + '+st' + ');',
  1021                                                 + '+"\\n\\nStack trace:\\n"' \
  1022                 '          debugger;',
  1022                                                 + '+st' \
  1023                 '          throw new ' + self.module_prefix + 'HaltException();',
  1023                                                 + ');'
  1024                 '      }',
  1024             print >>self.output, '          debugger;'
  1025                 '  }'
  1025 
  1026             )
  1026             print >>self.output, '          throw new ' + self.module_prefix + "HaltException();"
  1027             for s in out:
  1027             print >>self.output, '      }'
  1028                 print >>self.output, s
  1028             print >>self.output, '  }'
       
  1029 
       
  1030 
  1029 
  1031     def get_line_trace(self, node):
  1030     def get_line_trace(self, node):
  1032         lineNum = "Unknown"
  1031         lineNum = "Unknown"
  1033         srcLine = ""
  1032         srcLine = ""
  1034         if hasattr(node, "lineno"):
  1033         if hasattr(node, "lineno"):
  1035             if node.lineno != None:
  1034             if node.lineno is not None:
  1036                 lineNum = node.lineno
  1035                 lineNum = node.lineno
  1037                 srcLine = self.src[min(lineNum, len(self.src))-1]
  1036                 srcLine = self.src[min(lineNum, len(self.src))-1]
  1038                 srcLine = srcLine.replace('\\', '\\\\')
  1037                 srcLine = srcLine.replace('\\', '\\\\')
  1039                 srcLine = srcLine.replace('"', '\\"')
  1038                 srcLine = srcLine.replace('"', '\\"')
  1040                 srcLine = srcLine.replace("'", "\\'")
  1039                 srcLine = srcLine.replace("'", "\\'")
  1041 
  1040 
  1042         return self.raw_module_name + ".py, line " \
  1041         return self.raw_module_name + ".py, line " \
  1043                + str(lineNum) + ":"\
  1042             + str(lineNum) + ":"\
  1044                + "\\n" \
  1043             + "\\n" \
  1045                + "    " + srcLine
  1044             + "    " + srcLine
  1046 
  1045 
  1047     def _augassign(self, node, current_klass):
  1046     def _augassign(self, node, current_klass):
  1048         v = node.node
  1047         v = node.node
  1049         if isinstance(v, ast.Getattr):
  1048         if isinstance(v, ast.Getattr):
  1050             # XXX HACK!  don't allow += on return result of getattr.
  1049             # XXX HACK!  don't allow += on return result of getattr.
  1054             lhs = self._name(node.node, current_klass)
  1053             lhs = self._name(node.node, current_klass)
  1055         op = node.op
  1054         op = node.op
  1056         rhs = self.expr(node.expr, current_klass)
  1055         rhs = self.expr(node.expr, current_klass)
  1057         print >>self.output, "    " + lhs + " " + op + " " + rhs + ";"
  1056         print >>self.output, "    " + lhs + " " + op + " " + rhs + ";"
  1058 
  1057 
  1059 
  1058     def _assign(self, node, current_klass, top_level=False):
  1060     def _assign(self, node, current_klass, top_level = False):
       
  1061         if len(node.nodes) != 1:
  1059         if len(node.nodes) != 1:
  1062             tempvar = '__temp'+str(node.lineno)
  1060             tempvar = '__temp'+str(node.lineno)
  1063             tnode = ast.Assign([ast.AssName(tempvar, "OP_ASSIGN", node.lineno)], node.expr, node.lineno)
  1061             tnode = ast.Assign([ast.AssName(tempvar, "OP_ASSIGN", node.lineno)], node.expr, node.lineno)
  1064             self._assign(tnode, current_klass, top_level)
  1062             self._assign(tnode, current_klass, top_level)
  1065             for v in node.nodes:
  1063             for v in node.nodes:
  1066                tnode2 = ast.Assign([v], ast.Name(tempvar, node.lineno), node.lineno)
  1064                 tnode2 = ast.Assign([v], ast.Name(tempvar, node.lineno), node.lineno)
  1067                self._assign(tnode2, current_klass, top_level)
  1065                 self._assign(tnode2, current_klass, top_level)
  1068             return
  1066             return
  1069 
  1067 
  1070         local_var_names = None
  1068         local_var_names = None
  1071         if len(self.local_arg_stack) > 0:
  1069         if len(self.local_arg_stack) > 0:
  1072             local_var_names = self.local_arg_stack[-1]
  1070             local_var_names = self.local_arg_stack[-1]
  1091                                + v.name
  1089                                + v.name
  1092                 else:
  1090                 else:
  1093                     self.top_level_vars.add(v.name)
  1091                     self.top_level_vars.add(v.name)
  1094                     vname = self.modpfx() + v.name
  1092                     vname = self.modpfx() + v.name
  1095                     if not self.modpfx() and v.name not in\
  1093                     if not self.modpfx() and v.name not in\
  1096                            self.method_imported_globals:
  1094                        self.method_imported_globals:
  1097                         lhs = "var " + vname
  1095                         lhs = "var " + vname
  1098                     else:
  1096                     else:
  1099                         lhs = UU + vname
  1097                         lhs = UU + vname
  1100                     self.add_local_arg(v.name)
  1098                     self.add_local_arg(v.name)
  1101             else:
  1099             else:
  1138             uniqueID = self.nextTupleAssignID
  1136             uniqueID = self.nextTupleAssignID
  1139             self.nextTupleAssignID += 1
  1137             self.nextTupleAssignID += 1
  1140             tempName = "__tupleassign" + str(uniqueID) + "__"
  1138             tempName = "__tupleassign" + str(uniqueID) + "__"
  1141             print >>self.output, "    var " + tempName + " = " + \
  1139             print >>self.output, "    var " + tempName + " = " + \
  1142                                  self.expr(node.expr, current_klass) + ";"
  1140                                  self.expr(node.expr, current_klass) + ";"
  1143             for index,child in enumerate(v.getChildNodes()):
  1141             for index, child in enumerate(v.getChildNodes()):
  1144                 rhs = tempName + ".__getitem__(" + str(index) + ")"
  1142                 rhs = tempName + ".__getitem__(" + str(index) + ")"
  1145 
  1143 
  1146                 if isinstance(child, ast.AssAttr):
  1144                 if isinstance(child, ast.AssAttr):
  1147                     lhs = _lhsFromAttr(child, current_klass)
  1145                     lhs = _lhsFromAttr(child, current_klass)
  1148                 elif isinstance(child, ast.AssName):
  1146                 elif isinstance(child, ast.AssName):
  1154                             raise TranslationError("must have one sub " +
  1152                             raise TranslationError("must have one sub " +
  1155                                                    "(in _assign)", child)
  1153                                                    "(in _assign)", child)
  1156                         idx = self.expr(child.subs[0], current_klass)
  1154                         idx = self.expr(child.subs[0], current_klass)
  1157                         value = self.expr(node.expr, current_klass)
  1155                         value = self.expr(node.expr, current_klass)
  1158                         print >>self.output, "    " + obj + ".__setitem__(" \
  1156                         print >>self.output, "    " + obj + ".__setitem__(" \
  1159                                            + idx + ", " + rhs + ");"
  1157                             + idx + ", " + rhs + ");"
  1160                         continue
  1158                         continue
  1161                 print >>self.output, "    " + lhs + " = " + rhs + ";"
  1159                 print >>self.output, "    " + lhs + " = " + rhs + ";"
  1162             return
  1160             return
  1163         else:
  1161         else:
  1164             raise TranslationError("unsupported type (in _assign)", v)
  1162             raise TranslationError("unsupported type (in _assign)", v)
  1166         rhs = self.expr(node.expr, current_klass)
  1164         rhs = self.expr(node.expr, current_klass)
  1167         if dbg:
  1165         if dbg:
  1168             print "b", repr(node.expr), rhs
  1166             print "b", repr(node.expr), rhs
  1169         print >>self.output, "    " + lhs + " " + op + " " + rhs + ";"
  1167         print >>self.output, "    " + lhs + " " + op + " " + rhs + ";"
  1170 
  1168 
  1171 
       
  1172     def _discard(self, node, current_klass):
  1169     def _discard(self, node, current_klass):
  1173         
  1170 
  1174         if isinstance(node.expr, ast.CallFunc):
  1171         if isinstance(node.expr, ast.CallFunc):
  1175             debugStmt = self.debug and not self._isNativeFunc(node)
  1172             debugStmt = self.debug and not self._isNativeFunc(node)
  1176             if debugStmt and isinstance(node.expr.node, ast.Name) and \
  1173             if debugStmt and isinstance(node.expr.node, ast.Name) and \
  1177                node.expr.node.name == 'import_wait':
  1174                node.expr.node.name == 'import_wait':
  1178                debugStmt = False
  1175                 debugStmt = False
  1179             if debugStmt:
  1176             if debugStmt:
  1180                 st = self.get_line_trace(node)
  1177                 st = self.get_line_trace(node)
  1181                 print >>self.output, "sys.addstack('%s');\n" % st
  1178                 print >>self.output, "sys.addstack('%s');\n" % st
  1182             if isinstance(node.expr.node, ast.Name) and node.expr.node.name == NATIVE_JS_FUNC_NAME:
  1179             if isinstance(node.expr.node, ast.Name) and node.expr.node.name == NATIVE_JS_FUNC_NAME:
  1183                 if len(node.expr.args) != 1:
  1180                 if len(node.expr.args) != 1:
  1192 
  1189 
  1193             if debugStmt:
  1190             if debugStmt:
  1194                 print >>self.output, "sys.popstack();\n"
  1191                 print >>self.output, "sys.popstack();\n"
  1195 
  1192 
  1196         elif isinstance(node.expr, ast.Const):
  1193         elif isinstance(node.expr, ast.Const):
  1197             if node.expr.value is not None: # Empty statements generate ignore None
  1194             if node.expr.value is not None:  # Empty statements generate ignore None
  1198                 print >>self.output, self._const(node.expr)
  1195                 print >>self.output, self._const(node.expr)
  1199         else:
  1196         else:
  1200             raise TranslationError("unsupported type (in _discard)", node.expr)
  1197             raise TranslationError("unsupported type (in _discard)", node.expr)
  1201 
       
  1202 
  1198 
  1203     def _if(self, node, current_klass):
  1199     def _if(self, node, current_klass):
  1204         for i in range(len(node.tests)):
  1200         for i in range(len(node.tests)):
  1205             test, consequence = node.tests[i]
  1201             test, consequence = node.tests[i]
  1206             if i == 0:
  1202             if i == 0:
  1215             test = None
  1211             test = None
  1216             consequence = node.else_
  1212             consequence = node.else_
  1217 
  1213 
  1218             self._if_test(keyword, test, consequence, current_klass)
  1214             self._if_test(keyword, test, consequence, current_klass)
  1219 
  1215 
  1220 
       
  1221     def _if_test(self, keyword, test, consequence, current_klass):
  1216     def _if_test(self, keyword, test, consequence, current_klass):
  1222         if test:
  1217         if test:
  1223             expr = self.expr(test, current_klass)
  1218             expr = self.expr(test, current_klass)
  1224 
  1219 
  1225             print >>self.output, "    " + keyword + " (pyjslib.bool(" + expr + ")) {"
  1220             print >>self.output, "    " + keyword + " (pyjslib.bool(" + expr + ")) {"
  1231                 self._stmt(child, current_klass)
  1226                 self._stmt(child, current_klass)
  1232         else:
  1227         else:
  1233             raise TranslationError("unsupported type (in _if_test)", consequence)
  1228             raise TranslationError("unsupported type (in _if_test)", consequence)
  1234 
  1229 
  1235         print >>self.output, "    }"
  1230         print >>self.output, "    }"
  1236 
       
  1237 
  1231 
  1238     def _from(self, node):
  1232     def _from(self, node):
  1239         for name in node.names:
  1233         for name in node.names:
  1240             # look up "hack" in AppTranslator as to how findFile gets here
  1234             # look up "hack" in AppTranslator as to how findFile gets here
  1241             module_name = node.modname + "." + name[0]
  1235             module_name = node.modname + "." + name[0]
  1246             if ff:
  1240             if ff:
  1247                 self.add_imported_module(module_name)
  1241                 self.add_imported_module(module_name)
  1248             else:
  1242             else:
  1249                 self.imported_classes[name[0]] = node.modname
  1243                 self.imported_classes[name[0]] = node.modname
  1250 
  1244 
  1251 
       
  1252     def _compare(self, node, current_klass):
  1245     def _compare(self, node, current_klass):
  1253         lhs = self.expr(node.expr, current_klass)
  1246         lhs = self.expr(node.expr, current_klass)
  1254 
  1247 
  1255         if len(node.ops) != 1:
  1248         if len(node.ops) != 1:
  1256             raise TranslationError("only one ops supported (in _compare)", node)
  1249             raise TranslationError("only one ops supported (in _compare)", node)
  1269             op = "==="
  1262             op = "==="
  1270         elif op == "is not":
  1263         elif op == "is not":
  1271             op = "!=="
  1264             op = "!=="
  1272 
  1265 
  1273         return "(" + lhs + " " + op + " " + rhs + ")"
  1266         return "(" + lhs + " " + op + " " + rhs + ")"
  1274 
       
  1275 
  1267 
  1276     def _not(self, node, current_klass):
  1268     def _not(self, node, current_klass):
  1277         expr = self.expr(node.expr, current_klass)
  1269         expr = self.expr(node.expr, current_klass)
  1278 
  1270 
  1279         return "!(" + expr + ")"
  1271         return "!(" + expr + ")"
  1339                 throw e;
  1331                 throw e;
  1340             }
  1332             }
  1341         }
  1333         }
  1342         """ % locals()
  1334         """ % locals()
  1343 
  1335 
  1344 
       
  1345     def _while(self, node, current_klass):
  1336     def _while(self, node, current_klass):
  1346         test = self.expr(node.test, current_klass)
  1337         test = self.expr(node.test, current_klass)
  1347         print >>self.output, "    while (pyjslib.bool(" + test + ")) {"
  1338         print >>self.output, "    while (pyjslib.bool(" + test + ")) {"
  1348         if isinstance(node.body, ast.Stmt):
  1339         if isinstance(node.body, ast.Stmt):
  1349             for child in node.body.nodes:
  1340             for child in node.body.nodes:
  1350                 self._stmt(child, current_klass)
  1341                 self._stmt(child, current_klass)
  1351         else:
  1342         else:
  1352             raise TranslationError("unsupported type (in _while)", node.body)
  1343             raise TranslationError("unsupported type (in _while)", node.body)
  1353         print >>self.output, "    }"
  1344         print >>self.output, "    }"
  1354 
       
  1355 
  1345 
  1356     def _const(self, node):
  1346     def _const(self, node):
  1357         if isinstance(node.value, int):
  1347         if isinstance(node.value, int):
  1358             return str(node.value)
  1348             return str(node.value)
  1359         elif isinstance(node.value, float):
  1349         elif isinstance(node.value, float):
  1360             return str(node.value)
  1350             return str(node.value)
  1361         elif isinstance(node.value, basestring):
  1351         elif isinstance(node.value, basestring):
  1362             v = node.value
  1352             v = node.value
  1363             if isinstance(node.value, unicode):
  1353             if isinstance(node.value, unicode):
  1364                 v = v.encode('utf-8')
  1354                 v = v.encode('utf-8')
  1365             return  "String('%s')" % escapejs(v)
  1355             return "String('%s')" % escapejs(v)
  1366         elif node.value is None:
  1356         elif node.value is None:
  1367             return "null"
  1357             return "null"
  1368         else:
  1358         else:
  1369             raise TranslationError("unsupported type (in _const)", node)
  1359             raise TranslationError("unsupported type (in _const)", node)
  1370 
  1360 
  1386     def _mul(self, node, current_klass):
  1376     def _mul(self, node, current_klass):
  1387         return self.expr(node.left, current_klass) + " * " + self.expr(node.right, current_klass)
  1377         return self.expr(node.left, current_klass) + " * " + self.expr(node.right, current_klass)
  1388 
  1378 
  1389     def _mod(self, node, current_klass):
  1379     def _mod(self, node, current_klass):
  1390         if isinstance(node.left, ast.Const) and isinstance(node.left.value, StringType):
  1380         if isinstance(node.left, ast.Const) and isinstance(node.left.value, StringType):
  1391            self.imported_js.add("sprintf.js") # Include the sprintf functionality if it is used
  1381             self.imported_js.add("sprintf.js")  # Include the sprintf functionality if it is used
  1392            return "sprintf("+self.expr(node.left, current_klass) + ", " + self.expr(node.right, current_klass)+")"
  1382             return "sprintf("+self.expr(node.left, current_klass) + ", " + self.expr(node.right, current_klass)+")"
  1393         return self.expr(node.left, current_klass) + " % " + self.expr(node.right, current_klass)
  1383         return self.expr(node.left, current_klass) + " % " + self.expr(node.right, current_klass)
  1394 
  1384 
  1395     def _invert(self, node, current_klass):
  1385     def _invert(self, node, current_klass):
  1396         return "~" + self.expr(node.expr, current_klass)
  1386         return "~" + self.expr(node.expr, current_klass)
  1397 
  1387 
  1402         return self.expr(node.left, current_klass) + " << " + self.expr(node.right, current_klass)
  1392         return self.expr(node.left, current_klass) + " << " + self.expr(node.right, current_klass)
  1403 
  1393 
  1404     def _bitshiftright(self, node, current_klass):
  1394     def _bitshiftright(self, node, current_klass):
  1405         return self.expr(node.left, current_klass) + " >>> " + self.expr(node.right, current_klass)
  1395         return self.expr(node.left, current_klass) + " >>> " + self.expr(node.right, current_klass)
  1406 
  1396 
  1407     def _bitxor(self,node, current_klass):
  1397     def _bitxor(self, node, current_klass):
  1408         return " ^ ".join([self.expr(child, current_klass) for child in node.nodes])
  1398         return " ^ ".join([self.expr(child, current_klass) for child in node.nodes])
  1409 
  1399 
  1410     def _bitor(self, node, current_klass):
  1400     def _bitor(self, node, current_klass):
  1411         return " | ".join([self.expr(child, current_klass) for child in node.nodes])
  1401         return " | ".join([self.expr(child, current_klass) for child in node.nodes])
  1412 
  1402 
  1457 
  1447 
  1458     def _slice(self, node, current_klass):
  1448     def _slice(self, node, current_klass):
  1459         if node.flags == "OP_APPLY":
  1449         if node.flags == "OP_APPLY":
  1460             lower = "null"
  1450             lower = "null"
  1461             upper = "null"
  1451             upper = "null"
  1462             if node.lower != None:
  1452             if node.lower is not None:
  1463                 lower = self.expr(node.lower, current_klass)
  1453                 lower = self.expr(node.lower, current_klass)
  1464             if node.upper != None:
  1454             if node.upper is not None:
  1465                 upper = self.expr(node.upper, current_klass)
  1455                 upper = self.expr(node.upper, current_klass)
  1466             return  "pyjslib.slice(" + self.expr(node.expr, current_klass) + ", " + lower + ", " + upper + ")"
  1456             return "pyjslib.slice(" + self.expr(node.expr, current_klass) + ", " + lower + ", " + upper + ")"
  1467         else:
  1457         else:
  1468             raise TranslationError("unsupported flag (in _slice)", node)
  1458             raise TranslationError("unsupported flag (in _slice)", node)
  1469 
  1459 
  1470     def _global(self, node, current_klass):
  1460     def _global(self, node, current_klass):
  1471         for name in node.names:
  1461         for name in node.names:
  1497             return self._and(node, current_klass)
  1487             return self._and(node, current_klass)
  1498         elif isinstance(node, ast.Invert):
  1488         elif isinstance(node, ast.Invert):
  1499             return self._invert(node, current_klass)
  1489             return self._invert(node, current_klass)
  1500         elif isinstance(node, ast.Bitand):
  1490         elif isinstance(node, ast.Bitand):
  1501             return "("+self._bitand(node, current_klass)+")"
  1491             return "("+self._bitand(node, current_klass)+")"
  1502         elif isinstance(node,ast.LeftShift):
  1492         elif isinstance(node, ast.LeftShift):
  1503             return self._bitshiftleft(node, current_klass)
  1493             return self._bitshiftleft(node, current_klass)
  1504         elif isinstance(node, ast.RightShift):
  1494         elif isinstance(node, ast.RightShift):
  1505             return self._bitshiftright(node, current_klass)
  1495             return self._bitshiftright(node, current_klass)
  1506         elif isinstance(node, ast.Bitxor):
  1496         elif isinstance(node, ast.Bitxor):
  1507             return "("+self._bitxor(node, current_klass)+")"
  1497             return "("+self._bitxor(node, current_klass)+")"
  1529             return self._lambda(node, current_klass)
  1519             return self._lambda(node, current_klass)
  1530         else:
  1520         else:
  1531             raise TranslationError("unsupported type (in expr)", node)
  1521             raise TranslationError("unsupported type (in expr)", node)
  1532 
  1522 
  1533 
  1523 
  1534 
       
  1535 import cStringIO
       
  1536 
       
  1537 def translate(file_name, module_name, debug=False):
  1524 def translate(file_name, module_name, debug=False):
  1538     f = file(file_name, "r")
  1525     f = file(file_name, "r")
  1539     src = f.read()
  1526     src = f.read()
  1540     f.close()
  1527     f.close()
  1541     output = cStringIO.StringIO()
  1528     output = cStringIO.StringIO()
  1543     t = Translator(module_name, module_name, module_name, src, debug, mod, output)
  1530     t = Translator(module_name, module_name, module_name, src, debug, mod, output)
  1544     return output.getvalue()
  1531     return output.getvalue()
  1545 
  1532 
  1546 
  1533 
  1547 class PlatformParser:
  1534 class PlatformParser:
  1548     def __init__(self, platform_dir = "", verbose=True):
  1535     def __init__(self, platform_dir="", verbose=True):
  1549         self.platform_dir = platform_dir
  1536         self.platform_dir = platform_dir
  1550         self.parse_cache = {}
  1537         self.parse_cache = {}
  1551         self.platform = ""
  1538         self.platform = ""
  1552         self.verbose = verbose
  1539         self.verbose = verbose
  1553 
  1540 
  1555         self.platform = platform
  1542         self.platform = platform
  1556 
  1543 
  1557     def parseModule(self, module_name, file_name):
  1544     def parseModule(self, module_name, file_name):
  1558 
  1545 
  1559         importing = False
  1546         importing = False
  1560         if not self.parse_cache.has_key(file_name):
  1547         if file_name not in self.parse_cache:
  1561             importing = True
  1548             importing = True
  1562             mod = compiler.parseFile(file_name)
  1549             mod = compiler.parseFile(file_name)
  1563             self.parse_cache[file_name] = mod
  1550             self.parse_cache[file_name] = mod
  1564         else:
  1551         else:
  1565             mod = self.parse_cache[file_name]
  1552             mod = self.parse_cache[file_name]
  1629 
  1616 
  1630     def copyFunction(self, target, source):
  1617     def copyFunction(self, target, source):
  1631         target.code = source.code
  1618         target.code = source.code
  1632         target.argnames = source.argnames
  1619         target.argnames = source.argnames
  1633         target.defaults = source.defaults
  1620         target.defaults = source.defaults
  1634         target.doc = source.doc # @@@ not sure we need to do this any more
  1621         target.doc = source.doc  # @@@ not sure we need to do this any more
       
  1622 
  1635 
  1623 
  1636 def dotreplace(fname):
  1624 def dotreplace(fname):
  1637     path, ext = os.path.splitext(fname)
  1625     path, ext = os.path.splitext(fname)
  1638     return path.replace(".", "/") + ext
  1626     return path.replace(".", "/") + ext
       
  1627 
  1639 
  1628 
  1640 class AppTranslator:
  1629 class AppTranslator:
  1641 
  1630 
  1642     def __init__(self, library_dirs=[], parser=None, dynamic=False,
  1631     def __init__(self, library_dirs=[], parser=None, dynamic=False,
  1643                  optimize=False, verbose=True):
  1632                  optimize=False, verbose=True):
  1691         f.close()
  1680         f.close()
  1692 
  1681 
  1693         mod, override = self.parser.parseModule(module_name, file_name)
  1682         mod, override = self.parser.parseModule(module_name, file_name)
  1694         if override:
  1683         if override:
  1695             override_name = "%s.%s" % (self.parser.platform.lower(),
  1684             override_name = "%s.%s" % (self.parser.platform.lower(),
  1696                                            module_name)
  1685                                        module_name)
  1697             self.overrides[override_name] = override_name
  1686             self.overrides[override_name] = override_name
  1698         if is_app:
  1687         if is_app:
  1699             mn = '__main__'
  1688             mn = '__main__'
  1700         else:
  1689         else:
  1701             mn = module_name
  1690             mn = module_name
  1707         imported_js.update(set(t.imported_js))
  1696         imported_js.update(set(t.imported_js))
  1708         imported_modules_str = ""
  1697         imported_modules_str = ""
  1709         for module in t.imported_modules:
  1698         for module in t.imported_modules:
  1710             if module not in self.library_modules:
  1699             if module not in self.library_modules:
  1711                 self.library_modules.append(module)
  1700                 self.library_modules.append(module)
  1712                 #imported_js.update(set(t.imported_js))
  1701                 # imported_js.update(set(t.imported_js))
  1713                 #imported_modules_str += self._translate(
  1702                 # imported_modules_str += self._translate(
  1714                 #    module, False, debug=debug, imported_js=imported_js)
  1703                 #    module, False, debug=debug, imported_js=imported_js)
  1715 
  1704 
  1716         return imported_modules_str + module_str
  1705         return imported_modules_str + module_str
  1717 
       
  1718 
  1706 
  1719     def translate(self, module_name, is_app=True, debug=False,
  1707     def translate(self, module_name, is_app=True, debug=False,
  1720                   library_modules=[]):
  1708                   library_modules=[]):
  1721         app_code = cStringIO.StringIO()
  1709         app_code = cStringIO.StringIO()
  1722         lib_code = cStringIO.StringIO()
  1710         lib_code = cStringIO.StringIO()
  1740             print >> lib_code, '\n//\n// END LIB '+library+'\n//\n'
  1728             print >> lib_code, '\n//\n// END LIB '+library+'\n//\n'
  1741         if module_name:
  1729         if module_name:
  1742             print >> app_code, self._translate(
  1730             print >> app_code, self._translate(
  1743                 module_name, is_app, debug=debug, imported_js=imported_js)
  1731                 module_name, is_app, debug=debug, imported_js=imported_js)
  1744         for js in imported_js:
  1732         for js in imported_js:
  1745            path = self.findFile(js)
  1733             path = self.findFile(js)
  1746            if os.path.isfile(path):
  1734             if os.path.isfile(path):
  1747               if self.verbose:
  1735                 if self.verbose:
  1748                   print 'Including JS', js
  1736                     print 'Including JS', js
  1749               print >> lib_code,  '\n//\n// BEGIN JS '+js+'\n//\n'
  1737                 print >> lib_code,  '\n//\n// BEGIN JS '+js+'\n//\n'
  1750               print >> lib_code, file(path).read()
  1738                 print >> lib_code, file(path).read()
  1751               print >> lib_code,  '\n//\n// END JS '+js+'\n//\n'
  1739                 print >> lib_code,  '\n//\n// END JS '+js+'\n//\n'
  1752            else:
  1740             else:
  1753               print >>sys.stderr, 'Warning: Unable to find imported javascript:', js
  1741                 print >>sys.stderr, 'Warning: Unable to find imported javascript:', js
  1754         return lib_code.getvalue(), app_code.getvalue()
  1742         return lib_code.getvalue(), app_code.getvalue()
       
  1743 
  1755 
  1744 
  1756 usage = """
  1745 usage = """
  1757   usage: %s file_name [module_name]
  1746   usage: %s file_name [module_name]
  1758 """
  1747 """
  1759 
  1748 
       
  1749 
  1760 def main():
  1750 def main():
  1761     import sys
  1751     import sys
  1762     if len(sys.argv)<2:
  1752     if len(sys.argv) < 2:
  1763         print >> sys.stderr, usage % sys.argv[0]
  1753         print >> sys.stderr, usage % sys.argv[0]
  1764         sys.exit(1)
  1754         sys.exit(1)
  1765     file_name = os.path.abspath(sys.argv[1])
  1755     file_name = os.path.abspath(sys.argv[1])
  1766     if not os.path.isfile(file_name):
  1756     if not os.path.isfile(file_name):
  1767         print >> sys.stderr, "File not found %s" % file_name
  1757         print >> sys.stderr, "File not found %s" % file_name
  1770         module_name = sys.argv[2]
  1760         module_name = sys.argv[2]
  1771     else:
  1761     else:
  1772         module_name = None
  1762         module_name = None
  1773     print translate(file_name, module_name),
  1763     print translate(file_name, module_name),
  1774 
  1764 
       
  1765 
  1775 if __name__ == "__main__":
  1766 if __name__ == "__main__":
  1776     main()
  1767     main()
  1777