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' |
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, |
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: |
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;" |
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] |
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: |
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)+")" |
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): |
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 |