224 |
225 |
225 if module_name.find(".") >= 0: |
226 if module_name.find(".") >= 0: |
226 vdec = '' |
227 vdec = '' |
227 else: |
228 else: |
228 vdec = 'var ' |
229 vdec = 'var ' |
229 print >>self.output, UU+"%s%s = function (__mod_name__) {" % (vdec, module_name) |
230 self.printo(UU+"%s%s = function (__mod_name__) {" % (vdec, module_name)) |
230 |
231 |
231 print >>self.output, " if("+module_name+".__was_initialized__) return;" |
232 self.printo(" if("+module_name+".__was_initialized__) return;") |
232 print >>self.output, " "+UU+module_name+".__was_initialized__ = true;" |
233 self.printo(" "+UU+module_name+".__was_initialized__ = true;") |
233 print >>self.output, UU+"if (__mod_name__ == null) __mod_name__ = '%s';" % (mn) |
234 self.printo(UU+"if (__mod_name__ == null) __mod_name__ = '%s';" % (mn)) |
234 print >>self.output, UU+"%s.__name__ = __mod_name__;" % (raw_module_name) |
235 self.printo(UU+"%s.__name__ = __mod_name__;" % (raw_module_name)) |
235 |
236 |
236 decl = mod_var_name_decl(raw_module_name) |
237 decl = mod_var_name_decl(raw_module_name) |
237 if decl: |
238 if decl: |
238 print >>self.output, decl |
239 self.printo(decl) |
239 |
240 |
240 if self.debug: |
241 if self.debug: |
241 haltException = self.module_prefix + "HaltException" |
242 haltException = self.module_prefix + "HaltException" |
242 print >>self.output, haltException + ' = function () {' |
243 self.printo(haltException + ' = function () {') |
243 print >>self.output, ' this.message = "Program Halted";' |
244 self.printo(' this.message = "Program Halted";') |
244 print >>self.output, ' this.name = "' + haltException + '";' |
245 self.printo(' this.name = "' + haltException + '";') |
245 print >>self.output, '}' |
246 self.printo('}') |
246 print >>self.output, '' |
247 self.printo('') |
247 print >>self.output, haltException + ".prototype.__str__ = function()" |
248 self.printo(haltException + ".prototype.__str__ = function()") |
248 print >>self.output, '{' |
249 self.printo('{') |
249 print >>self.output, 'return this.message ;' |
250 self.printo('return this.message ;') |
250 print >>self.output, '}' |
251 self.printo('}') |
251 |
252 |
252 print >>self.output, haltException + ".prototype.toString = function()" |
253 self.printo(haltException + ".prototype.toString = function()") |
253 print >>self.output, '{' |
254 self.printo('{') |
254 print >>self.output, 'return this.name + ": \\"" + this.message + "\\"";' |
255 self.printo('return this.name + ": \\"" + this.message + "\\"";') |
255 print >>self.output, '}' |
256 self.printo('}') |
256 |
257 |
257 isHaltFunction = self.module_prefix + "IsHaltException" |
258 isHaltFunction = self.module_prefix + "IsHaltException" |
258 print >>self.output, """ |
259 self.printo(""") |
259 %s = function (s) { |
260 %s = function (s) { |
260 var suffix="HaltException"; |
261 var suffix="HaltException"; |
261 if (s.length < suffix.length) { |
262 if (s.length < suffix.length) { |
262 //alert(s + " " + suffix); |
263 //alert(s + " " + suffix); |
263 return false; |
264 return false; |
321 self._stmt(child, None) |
322 self._stmt(child, None) |
322 else: |
323 else: |
323 raise TranslationError("unsupported type (in __init__)", child) |
324 raise TranslationError("unsupported type (in __init__)", child) |
324 |
325 |
325 # Initialize all classes for this module |
326 # Initialize all classes for this module |
326 # print >> self.output, "__"+self.modpfx()+\ |
327 # self.printo("__"+self.modpfx()+\ |
327 # "classes_initialize = function() {\n" |
328 # "classes_initialize = function() {\n") |
328 # for className in self.top_level_classes: |
329 # for className in self.top_level_classes: |
329 # print >> self.output, "\t"+UU+self.modpfx()+"__"+className+"_initialize();" |
330 # self.printo("\t"+UU+self.modpfx()+"__"+className+"_initialize();") |
330 # print >> self.output, "};\n" |
331 # self.printo("};\n") |
331 |
332 |
332 print >> self.output, "return this;\n" |
333 self.printo("return this;\n") |
333 print >> self.output, "}; /* end %s */ \n" % module_name |
334 self.printo("}; /* end %s */ \n" % module_name) |
|
335 |
|
336 def printo(self, *args): |
|
337 print(*args, file=self.output) |
334 |
338 |
335 def module_imports(self): |
339 def module_imports(self): |
336 return self.imported_modules + self.imported_modules_as |
340 return self.imported_modules + self.imported_modules_as |
337 |
341 |
338 def add_local_arg(self, varname): |
342 def add_local_arg(self, varname): |
352 # because then the short name would be attempted to be |
356 # because then the short name would be attempted to be |
353 # added to the dependencies, and it's half way up the |
357 # added to the dependencies, and it's half way up the |
354 # module import directory structure! |
358 # module import directory structure! |
355 child_name = name[-1] |
359 child_name = name[-1] |
356 self.imported_modules_as.append(child_name) |
360 self.imported_modules_as.append(child_name) |
357 print >> self.output, gen_mod_import(self.raw_module_name, |
361 self.printo(gen_mod_import(self.raw_module_name, |
358 strip_py(importName), |
362 strip_py(importName), |
359 self.dynamic) |
363 self.dynamic)) |
360 |
364 |
361 def _default_args_handler(self, node, arg_names, current_klass, |
365 def _default_args_handler(self, node, arg_names, current_klass, |
362 output=None): |
366 output=None): |
363 if len(node.defaults): |
367 if len(node.defaults): |
364 output = output or self.output |
368 output = output or self.output |
375 else: |
379 else: |
376 raise TranslationError("unsupported type (in _method)", default_node) |
380 raise TranslationError("unsupported type (in _method)", default_node) |
377 |
381 |
378 default_name = arg_names[default_pos] |
382 default_name = arg_names[default_pos] |
379 default_pos += 1 |
383 default_pos += 1 |
380 print >> output, " if (typeof %s == 'undefined') %s=%s;" % (default_name, default_name, default_value) |
384 self.printo(" if (typeof %s == 'undefined') %s=%s;" % (default_name, default_name, default_value)) |
381 |
385 |
382 def _varargs_handler(self, node, varargname, arg_names, current_klass): |
386 def _varargs_handler(self, node, varargname, arg_names, current_klass): |
383 print >>self.output, " var", varargname, '= new pyjslib.Tuple();' |
387 self.printo(" var", varargname, '= new pyjslib.Tuple();') |
384 print >>self.output, " for(var __va_arg="+str(len(arg_names))+"; __va_arg < arguments.length; __va_arg++) {" |
388 self.printo(" for(var __va_arg="+str(len(arg_names))+"; __va_arg < arguments.length; __va_arg++) {") |
385 print >>self.output, " var __arg = arguments[__va_arg];" |
389 self.printo(" var __arg = arguments[__va_arg];") |
386 print >>self.output, " "+varargname+".append(__arg);" |
390 self.printo(" "+varargname+".append(__arg);") |
387 print >>self.output, " }" |
391 self.printo(" }") |
388 |
392 |
389 def _kwargs_parser(self, node, function_name, arg_names, current_klass): |
393 def _kwargs_parser(self, node, function_name, arg_names, current_klass): |
390 if len(node.defaults) or node.kwargs: |
394 if len(node.defaults) or node.kwargs: |
391 default_pos = len(arg_names) - len(node.defaults) |
395 default_pos = len(arg_names) - len(node.defaults) |
392 if arg_names and arg_names[0] == self.method_self: |
396 if arg_names and arg_names[0] == self.method_self: |
393 default_pos -= 1 |
397 default_pos -= 1 |
394 print >>self.output, function_name+'.parse_kwargs = function (', ", ".join(["__kwargs"]+arg_names), ") {" |
398 self.printo(function_name+'.parse_kwargs = function (', ", ".join(["__kwargs"]+arg_names), ") {") |
395 for default_node in node.defaults: |
399 for default_node in node.defaults: |
396 default_value = self.expr(default_node, current_klass) |
400 default_value = self.expr(default_node, current_klass) |
397 # if isinstance(default_node, ast.Const): |
401 # if isinstance(default_node, ast.Const): |
398 # default_value = self._const(default_node) |
402 # default_value = self._const(default_node) |
399 # elif isinstance(default_node, ast.Name): |
403 # elif isinstance(default_node, ast.Name): |
402 # default_value = self._unarysub(default_node, current_klass) |
406 # default_value = self._unarysub(default_node, current_klass) |
403 # else: |
407 # else: |
404 # raise TranslationError("unsupported type (in _method)", default_node) |
408 # raise TranslationError("unsupported type (in _method)", default_node) |
405 |
409 |
406 default_name = arg_names[default_pos] |
410 default_name = arg_names[default_pos] |
407 print >>self.output, " if (typeof %s == 'undefined')" % (default_name) |
411 self.printo(" if (typeof %s == 'undefined')" % (default_name)) |
408 print >>self.output, " %s=__kwargs.%s;" % (default_name, default_name) |
412 self.printo(" %s=__kwargs.%s;" % (default_name, default_name)) |
409 default_pos += 1 |
413 default_pos += 1 |
410 |
414 |
411 # self._default_args_handler(node, arg_names, current_klass) |
415 # self._default_args_handler(node, arg_names, current_klass) |
412 if node.kwargs: |
416 if node.kwargs: |
413 arg_names += ["pyjslib.Dict(__kwargs)"] |
417 arg_names += ["pyjslib.Dict(__kwargs)"] |
414 print >>self.output, " var __r = "+"".join(["[", ", ".join(arg_names), "]"])+";" |
418 self.printo(" var __r = "+"".join(["[", ", ".join(arg_names), "]"])+";") |
415 if node.varargs: |
419 if node.varargs: |
416 self._varargs_handler(node, "__args", arg_names, current_klass) |
420 self._varargs_handler(node, "__args", arg_names, current_klass) |
417 print >>self.output, " __r.push.apply(__r, __args.getArray())" |
421 self.printo(" __r.push.apply(__r, __args.getArray())") |
418 print >>self.output, " return __r;" |
422 self.printo(" return __r;") |
419 print >>self.output, "};" |
423 self.printo("};") |
420 |
424 |
421 def _function(self, node, local=False): |
425 def _function(self, node, local=False): |
422 if local: |
426 if local: |
423 function_name = node.name |
427 function_name = node.name |
424 self.add_local_arg(function_name) |
428 self.add_local_arg(function_name) |
456 |
460 |
457 # we need to return null always, so it is not undefined |
461 # we need to return null always, so it is not undefined |
458 lastStmt = [p for p in node.code][-1] |
462 lastStmt = [p for p in node.code][-1] |
459 if not isinstance(lastStmt, ast.Return): |
463 if not isinstance(lastStmt, ast.Return): |
460 if not self._isNativeFunc(lastStmt): |
464 if not self._isNativeFunc(lastStmt): |
461 print >>self.output, " return null;" |
465 self.printo(" return null;") |
462 |
466 |
463 print >>self.output, "};" |
467 self.printo("};") |
464 print >>self.output, "%s.__name__ = '%s';\n" % (function_name, node.name) |
468 self.printo("%s.__name__ = '%s';\n" % (function_name, node.name)) |
465 |
469 |
466 self._kwargs_parser(node, function_name, normal_arg_names, None) |
470 self._kwargs_parser(node, function_name, normal_arg_names, None) |
467 |
471 |
468 def _return(self, node, current_klass): |
472 def _return(self, node, current_klass): |
469 expr = self.expr(node.value, current_klass) |
473 expr = self.expr(node.value, current_klass) |
470 # in python a function call always returns None, so we do it |
474 # in python a function call always returns None, so we do it |
471 # here too |
475 # here too |
472 print >>self.output, " return " + expr + ";" |
476 self.printo(" return " + expr + ";") |
473 |
477 |
474 def _break(self, node, current_klass): |
478 def _break(self, node, current_klass): |
475 print >>self.output, " break;" |
479 self.printo(" break;") |
476 |
480 |
477 def _continue(self, node, current_klass): |
481 def _continue(self, node, current_klass): |
478 print >>self.output, " continue;" |
482 self.printo(" continue;") |
479 |
483 |
480 def _callfunc(self, v, current_klass): |
484 def _callfunc(self, v, current_klass): |
481 |
485 |
482 if isinstance(v.node, ast.Name): |
486 if isinstance(v.node, ast.Name): |
483 if v.node.name in self.top_level_functions: |
487 if v.node.name in self.top_level_functions: |
560 call_args = [] |
564 call_args = [] |
561 for ch4 in node.nodes: |
565 for ch4 in node.nodes: |
562 arg = self.expr(ch4, current_klass) |
566 arg = self.expr(ch4, current_klass) |
563 call_args.append(arg) |
567 call_args.append(arg) |
564 |
568 |
565 print >>self.output, "pyjslib.printFunc([", ', '.join(call_args), "],", int(isinstance(node, ast.Printnl)), ");" |
569 self.printo("pyjslib.printFunc([", ', '.join(call_args), "],", int(isinstance(node, ast.Printnl)), ");") |
566 |
570 |
567 def _tryExcept(self, node, current_klass): |
571 def _tryExcept(self, node, current_klass): |
568 if len(node.handlers) != 1: |
572 if len(node.handlers) != 1: |
569 raise TranslationError("except statements in this form are" + |
573 raise TranslationError("except statements in this form are" + |
570 " not supported", node) |
574 " not supported", node) |
578 |
582 |
579 # XXX TODO: check that this should instead be added as a _separate_ |
583 # XXX TODO: check that this should instead be added as a _separate_ |
580 # local scope, temporary to the function. oh dearie me. |
584 # local scope, temporary to the function. oh dearie me. |
581 self.add_local_arg(errName) |
585 self.add_local_arg(errName) |
582 |
586 |
583 print >>self.output, " try {" |
587 self.printo(" try {") |
584 for stmt in node.body.nodes: |
588 for stmt in node.body.nodes: |
585 self._stmt(stmt, current_klass) |
589 self._stmt(stmt, current_klass) |
586 print >> self.output, " } catch(%s) {" % errName |
590 self.printo(" } catch(%s) {" % errName) |
587 if expr: |
591 if expr: |
588 k = [] |
592 k = [] |
589 if isinstance(expr, ast.Tuple): |
593 if isinstance(expr, ast.Tuple): |
590 for x in expr.nodes: |
594 for x in expr.nodes: |
591 k.append("(%(err)s.__name__ == %(expr)s.__name__)" % dict(err=errName, expr=self.expr(x, current_klass))) |
595 k.append("(%(err)s.__name__ == %(expr)s.__name__)" % dict(err=errName, expr=self.expr(x, current_klass))) |
592 else: |
596 else: |
593 k = [" (%(err)s.__name__ == %(expr)s.__name__) " % dict(err=errName, expr=self.expr(expr, current_klass))] |
597 k = [" (%(err)s.__name__ == %(expr)s.__name__) " % dict(err=errName, expr=self.expr(expr, current_klass))] |
594 print >> self.output, " if(%s) {" % '||\n\t\t'.join(k) |
598 self.printo(" if(%s) {" % '||\n\t\t'.join(k)) |
595 for stmt in node.handlers[0][2]: |
599 for stmt in node.handlers[0][2]: |
596 self._stmt(stmt, current_klass) |
600 self._stmt(stmt, current_klass) |
597 if expr: |
601 if expr: |
598 # print >> self.output, "} else { throw(%s); } " % errName |
602 # self.printo("} else { throw(%s); } " % errName) |
599 print >> self.output, "}" |
603 self.printo("}") |
600 if node.else_ is not None: |
604 if node.else_ is not None: |
601 print >>self.output, " } finally {" |
605 self.printo(" } finally {") |
602 for stmt in node.else_: |
606 for stmt in node.else_: |
603 self._stmt(stmt, current_klass) |
607 self._stmt(stmt, current_klass) |
604 print >>self.output, " }" |
608 self.printo(" }") |
605 |
609 |
606 # XXX: change use_getattr to True to enable "strict" compilation |
610 # XXX: change use_getattr to True to enable "strict" compilation |
607 # but incurring a 100% performance penalty. oops. |
611 # but incurring a 100% performance penalty. oops. |
608 def _getattr(self, v, current_klass, use_getattr=False): |
612 def _getattr(self, v, current_klass, use_getattr=False): |
609 attr_name = v.attrname |
613 attr_name = v.attrname |
634 |
638 |
635 def _name(self, v, current_klass, top_level=False, |
639 def _name(self, v, current_klass, top_level=False, |
636 return_none_for_module=False): |
640 return_none_for_module=False): |
637 |
641 |
638 if v.name == 'ilikesillynamesfornicedebugcode': |
642 if v.name == 'ilikesillynamesfornicedebugcode': |
639 print top_level, current_klass, repr(v) |
643 print(top_level, current_klass, repr(v)) |
640 print self.top_level_vars |
644 print(self.top_level_vars) |
641 print self.top_level_functions |
645 print(self.top_level_functions) |
642 print self.local_arg_stack |
646 print(self.local_arg_stack) |
643 print "error..." |
647 print("error...") |
644 |
648 |
645 local_var_names = None |
649 local_var_names = None |
646 las = len(self.local_arg_stack) |
650 las = len(self.local_arg_stack) |
647 if las > 0: |
651 if las > 0: |
648 local_var_names = self.local_arg_stack[-1] |
652 local_var_names = self.local_arg_stack[-1] |
784 |
788 |
785 current_klass.set_base(base_class) |
789 current_klass.set_base(base_class) |
786 else: |
790 else: |
787 raise TranslationError("more than one base (in _class)", node) |
791 raise TranslationError("more than one base (in _class)", node) |
788 |
792 |
789 print >>self.output, UU+class_name_ + " = function () {" |
793 self.printo(UU+class_name_ + " = function () {") |
790 # call superconstructor |
794 # call superconstructor |
791 # if base_class: |
795 # if base_class: |
792 # print >>self.output, " __" + base_class + ".call(this);" |
796 # self.printo(" __" + base_class + ".call(this);") |
793 print >>self.output, "}" |
797 self.printo("}") |
794 |
798 |
795 if not init_method: |
799 if not init_method: |
796 init_method = ast.Function([], "__init__", ["self"], [], 0, None, []) |
800 init_method = ast.Function([], "__init__", ["self"], [], 0, None, []) |
797 # self._method(init_method, current_klass, class_name) |
801 # self._method(init_method, current_klass, class_name) |
798 |
802 |
811 " if(instance.__init__) instance.__init__.apply(instance, arguments);\n" + |
815 " if(instance.__init__) instance.__init__.apply(instance, arguments);\n" + |
812 " return instance;" |
816 " return instance;" |
813 )]))]) |
817 )]))]) |
814 |
818 |
815 self._function(clsfunc, False) |
819 self._function(clsfunc, False) |
816 print >>self.output, UU+class_name_ + ".__initialize__ = function () {" |
820 self.printo(UU+class_name_ + ".__initialize__ = function () {") |
817 print >>self.output, " if("+UU+class_name_+".__was_initialized__) return;" |
821 self.printo(" if("+UU+class_name_+".__was_initialized__) return;") |
818 print >>self.output, " "+UU+class_name_+".__was_initialized__ = true;" |
822 self.printo(" "+UU+class_name_+".__was_initialized__ = true;") |
819 cls_obj = UU+class_name_ + '.prototype.__class__' |
823 cls_obj = UU+class_name_ + '.prototype.__class__' |
820 |
824 |
821 if class_name == "pyjslib.__Object": |
825 if class_name == "pyjslib.__Object": |
822 print >>self.output, " "+cls_obj+" = {};" |
826 self.printo(" "+cls_obj+" = {};") |
823 else: |
827 else: |
824 if base_class and base_class not in ("object", "pyjslib.__Object"): |
828 if base_class and base_class not in ("object", "pyjslib.__Object"): |
825 print >>self.output, " if(!"+UU+base_class_+".__was_initialized__)" |
829 self.printo(" if(!"+UU+base_class_+".__was_initialized__)") |
826 print >>self.output, " "+UU+base_class_+".__initialize__();" |
830 self.printo(" "+UU+base_class_+".__initialize__();") |
827 print >>self.output, " pyjs_extend(" + UU+class_name_ + ", "+UU+base_class_+");" |
831 self.printo(" pyjs_extend(" + UU+class_name_ + ", "+UU+base_class_+");") |
828 else: |
832 else: |
829 print >>self.output, " pyjs_extend(" + UU+class_name_ + ", "+UU+"pyjslib.__Object);" |
833 self.printo(" pyjs_extend(" + UU+class_name_ + ", "+UU+"pyjslib.__Object);") |
830 |
834 |
831 print >>self.output, " "+cls_obj+".__new__ = "+UU+class_name+";" |
835 self.printo(" "+cls_obj+".__new__ = "+UU+class_name+";") |
832 print >>self.output, " "+cls_obj+".__name__ = '"+UU+node.name+"';" |
836 self.printo(" "+cls_obj+".__name__ = '"+UU+node.name+"';") |
833 |
837 |
834 for child in node.code: |
838 for child in node.code: |
835 if isinstance(child, ast.Pass): |
839 if isinstance(child, ast.Pass): |
836 pass |
840 pass |
837 elif isinstance(child, ast.Function): |
841 elif isinstance(child, ast.Function): |
841 elif isinstance(child, ast.Discard) and isinstance(child.expr, ast.Const): |
845 elif isinstance(child, ast.Discard) and isinstance(child.expr, ast.Const): |
842 # Probably a docstring, turf it |
846 # Probably a docstring, turf it |
843 pass |
847 pass |
844 else: |
848 else: |
845 raise TranslationError("unsupported type (in _class)", child) |
849 raise TranslationError("unsupported type (in _class)", child) |
846 print >>self.output, "}" |
850 self.printo("}") |
847 |
851 |
848 print >> self.output, class_name_+".__initialize__();" |
852 self.printo(class_name_+".__initialize__();") |
849 |
853 |
850 def classattr(self, node, current_klass): |
854 def classattr(self, node, current_klass): |
851 self._assign(node, current_klass, True) |
855 self._assign(node, current_klass, True) |
852 |
856 |
853 def _raise(self, node, current_klass): |
857 def _raise(self, node, current_klass): |
854 if node.expr2: |
858 if node.expr2: |
855 raise TranslationError("More than one expression unsupported", |
859 raise TranslationError("More than one expression unsupported", |
856 node) |
860 node) |
857 print >> self.output, "throw (%s);" % self.expr( |
861 self.printo("throw (%s);" % self.expr( |
858 node.expr1, current_klass) |
862 node.expr1, current_klass)) |
859 |
863 |
860 def _method(self, node, current_klass, class_name, class_name_): |
864 def _method(self, node, current_klass, class_name, class_name_): |
861 # reset global var scope |
865 # reset global var scope |
862 self.method_imported_globals = set() |
866 self.method_imported_globals = set() |
863 |
867 |
873 staticmethod = True |
877 staticmethod = True |
874 |
878 |
875 if staticmethod: |
879 if staticmethod: |
876 staticfunc = ast.Function([], class_name_+"."+node.name, node.argnames, node.defaults, node.flags, node.doc, node.code, node.lineno) |
880 staticfunc = ast.Function([], class_name_+"."+node.name, node.argnames, node.defaults, node.flags, node.doc, node.code, node.lineno) |
877 self._function(staticfunc, True) |
881 self._function(staticfunc, True) |
878 print >>self.output, " " + UU+class_name_ + ".prototype.__class__." + node.name + " = " + class_name_+"."+node.name+";" |
882 self.printo(" " + UU+class_name_ + ".prototype.__class__." + node.name + " = " + class_name_+"."+node.name+";") |
879 print >>self.output, " " + UU+class_name_ + ".prototype.__class__." + node.name + ".static_method = true;" |
883 self.printo(" " + UU+class_name_ + ".prototype.__class__." + node.name + ".static_method = true;") |
880 return |
884 return |
881 else: |
885 else: |
882 if len(arg_names) == 0: |
886 if len(arg_names) == 0: |
883 raise TranslationError("methods must take an argument 'self' (in _method)", node) |
887 raise TranslationError("methods must take an argument 'self' (in _method)", node) |
884 self.method_self = arg_names[0] |
888 self.method_self = arg_names[0] |
919 self._stmt(child, current_klass) |
923 self._stmt(child, current_klass) |
920 |
924 |
921 # remove the top local arg names |
925 # remove the top local arg names |
922 self.local_arg_stack.pop() |
926 self.local_arg_stack.pop() |
923 |
927 |
924 print >>self.output, " };" |
928 self.printo(" };") |
925 |
929 |
926 self._kwargs_parser(node, fexpr, normal_arg_names, current_klass) |
930 self._kwargs_parser(node, fexpr, normal_arg_names, current_klass) |
927 |
931 |
928 if classmethod: |
932 if classmethod: |
929 # Have to create a version on the instances which automatically passes the |
933 # Have to create a version on the instances which automatically passes the |
930 # class as "self" |
934 # class as "self" |
931 altexpr = UU + class_name_ + ".prototype." + node.name |
935 altexpr = UU + class_name_ + ".prototype." + node.name |
932 print >>self.output, " "+altexpr + " = function() {" |
936 self.printo(" "+altexpr + " = function() {") |
933 print >>self.output, " return " + fexpr + ".apply(this.__class__, arguments);" |
937 self.printo(" return " + fexpr + ".apply(this.__class__, arguments);") |
934 print >>self.output, " };" |
938 self.printo(" };") |
935 print >>self.output, " "+fexpr+".class_method = true;" |
939 self.printo(" "+fexpr+".class_method = true;") |
936 print >>self.output, " "+altexpr+".instance_method = true;" |
940 self.printo(" "+altexpr+".instance_method = true;") |
937 else: |
941 else: |
938 # For instance methods, we need an unbound version in the class object |
942 # For instance methods, we need an unbound version in the class object |
939 altexpr = UU + class_name_ + ".prototype.__class__." + node.name |
943 altexpr = UU + class_name_ + ".prototype.__class__." + node.name |
940 print >>self.output, " "+altexpr + " = function() {" |
944 self.printo(" "+altexpr + " = function() {") |
941 print >>self.output, " return " + fexpr + ".call.apply("+fexpr+", arguments);" |
945 self.printo(" return " + fexpr + ".call.apply("+fexpr+", arguments);") |
942 print >>self.output, " };" |
946 self.printo(" };") |
943 print >>self.output, " "+altexpr+".unbound_method = true;" |
947 self.printo(" "+altexpr+".unbound_method = true;") |
944 print >>self.output, " "+fexpr+".instance_method = true;" |
948 self.printo(" "+fexpr+".instance_method = true;") |
945 print >>self.output, " "+altexpr+".__name__ = '%s';" % node.name |
949 self.printo(" "+altexpr+".__name__ = '%s';" % node.name) |
946 |
950 |
947 print >>self.output, UU + class_name_ + ".prototype.%s.__name__ = '%s';" % \ |
951 self.printo(UU + class_name_ + ".prototype.%s.__name__ = '%s';" % |
948 (node.name, node.name) |
952 (node.name, node.name)) |
949 |
953 |
950 if node.kwargs or len(node.defaults): |
954 if node.kwargs or len(node.defaults): |
951 print >>self.output, " "+altexpr + ".parse_kwargs = " + fexpr + ".parse_kwargs;" |
955 self.printo(" "+altexpr + ".parse_kwargs = " + fexpr + ".parse_kwargs;") |
952 |
956 |
953 self.method_self = None |
957 self.method_self = None |
954 self.method_imported_globals = set() |
958 self.method_imported_globals = set() |
955 |
959 |
956 def _isNativeFunc(self, node): |
960 def _isNativeFunc(self, node): |
962 return False |
966 return False |
963 |
967 |
964 def _stmt(self, node, current_klass): |
968 def _stmt(self, node, current_klass): |
965 debugStmt = self.debug and not self._isNativeFunc(node) |
969 debugStmt = self.debug and not self._isNativeFunc(node) |
966 if debugStmt: |
970 if debugStmt: |
967 print >>self.output, ' try {' |
971 self.printo(' try {') |
968 |
972 |
969 if isinstance(node, ast.Return): |
973 if isinstance(node, ast.Return): |
970 self._return(node, current_klass) |
974 self._return(node, current_klass) |
971 elif isinstance(node, ast.Break): |
975 elif isinstance(node, ast.Break): |
972 self._break(node, current_klass) |
976 self._break(node, current_klass) |
1051 lhs = self._getattr(v, current_klass, False) |
1055 lhs = self._getattr(v, current_klass, False) |
1052 else: |
1056 else: |
1053 lhs = self._name(node.node, current_klass) |
1057 lhs = self._name(node.node, current_klass) |
1054 op = node.op |
1058 op = node.op |
1055 rhs = self.expr(node.expr, current_klass) |
1059 rhs = self.expr(node.expr, current_klass) |
1056 print >>self.output, " " + lhs + " " + op + " " + rhs + ";" |
1060 self.printo(" " + lhs + " " + op + " " + rhs + ";") |
1057 |
1061 |
1058 def _assign(self, node, current_klass, top_level=False): |
1062 def _assign(self, node, current_klass, top_level=False): |
1059 if len(node.nodes) != 1: |
1063 if len(node.nodes) != 1: |
1060 tempvar = '__temp'+str(node.lineno) |
1064 tempvar = '__temp'+str(node.lineno) |
1061 tnode = ast.Assign([ast.AssName(tempvar, "OP_ASSIGN", node.lineno)], node.expr, node.lineno) |
1065 tnode = ast.Assign([ast.AssName(tempvar, "OP_ASSIGN", node.lineno)], node.expr, node.lineno) |
1126 obj = self.expr(v.expr, current_klass) |
1130 obj = self.expr(v.expr, current_klass) |
1127 if len(v.subs) != 1: |
1131 if len(v.subs) != 1: |
1128 raise TranslationError("must have one sub (in _assign)", v) |
1132 raise TranslationError("must have one sub (in _assign)", v) |
1129 idx = self.expr(v.subs[0], current_klass) |
1133 idx = self.expr(v.subs[0], current_klass) |
1130 value = self.expr(node.expr, current_klass) |
1134 value = self.expr(node.expr, current_klass) |
1131 print >>self.output, " " + obj + ".__setitem__(" + idx + ", " + value + ");" |
1135 self.printo(" " + obj + ".__setitem__(" + idx + ", " + value + ");") |
1132 return |
1136 return |
1133 else: |
1137 else: |
1134 raise TranslationError("unsupported flag (in _assign)", v) |
1138 raise TranslationError("unsupported flag (in _assign)", v) |
1135 elif isinstance(v, (ast.AssList, ast.AssTuple)): |
1139 elif isinstance(v, (ast.AssList, ast.AssTuple)): |
1136 uniqueID = self.nextTupleAssignID |
1140 uniqueID = self.nextTupleAssignID |
1137 self.nextTupleAssignID += 1 |
1141 self.nextTupleAssignID += 1 |
1138 tempName = "__tupleassign" + str(uniqueID) + "__" |
1142 tempName = "__tupleassign" + str(uniqueID) + "__" |
1139 print >>self.output, " var " + tempName + " = " + \ |
1143 self.printo(" var " + tempName + " = " + self.expr(node.expr, current_klass) + ";") |
1140 self.expr(node.expr, current_klass) + ";" |
|
1141 for index, child in enumerate(v.getChildNodes()): |
1144 for index, child in enumerate(v.getChildNodes()): |
1142 rhs = tempName + ".__getitem__(" + str(index) + ")" |
1145 rhs = tempName + ".__getitem__(" + str(index) + ")" |
1143 |
1146 |
1144 if isinstance(child, ast.AssAttr): |
1147 if isinstance(child, ast.AssAttr): |
1145 lhs = _lhsFromAttr(child, current_klass) |
1148 lhs = _lhsFromAttr(child, current_klass) |
1151 if len(child.subs) != 1: |
1154 if len(child.subs) != 1: |
1152 raise TranslationError("must have one sub " + |
1155 raise TranslationError("must have one sub " + |
1153 "(in _assign)", child) |
1156 "(in _assign)", child) |
1154 idx = self.expr(child.subs[0], current_klass) |
1157 idx = self.expr(child.subs[0], current_klass) |
1155 value = self.expr(node.expr, current_klass) |
1158 value = self.expr(node.expr, current_klass) |
1156 print >>self.output, " " + obj + ".__setitem__(" \ |
1159 self.printo(" " + obj + ".__setitem__(" + idx + ", " + rhs + ");") |
1157 + idx + ", " + rhs + ");" |
|
1158 continue |
1160 continue |
1159 print >>self.output, " " + lhs + " = " + rhs + ";" |
1161 self.printo(" " + lhs + " = " + rhs + ";") |
1160 return |
1162 return |
1161 else: |
1163 else: |
1162 raise TranslationError("unsupported type (in _assign)", v) |
1164 raise TranslationError("unsupported type (in _assign)", v) |
1163 |
1165 |
1164 rhs = self.expr(node.expr, current_klass) |
1166 rhs = self.expr(node.expr, current_klass) |
1165 if dbg: |
1167 if dbg: |
1166 print "b", repr(node.expr), rhs |
1168 print("b", repr(node.expr), rhs) |
1167 print >>self.output, " " + lhs + " " + op + " " + rhs + ";" |
1169 self.printo(" " + lhs + " " + op + " " + rhs + ";") |
1168 |
1170 |
1169 def _discard(self, node, current_klass): |
1171 def _discard(self, node, current_klass): |
1170 |
1172 |
1171 if isinstance(node.expr, ast.CallFunc): |
1173 if isinstance(node.expr, ast.CallFunc): |
1172 debugStmt = self.debug and not self._isNativeFunc(node) |
1174 debugStmt = self.debug and not self._isNativeFunc(node) |
1173 if debugStmt and isinstance(node.expr.node, ast.Name) and \ |
1175 if debugStmt and isinstance(node.expr.node, ast.Name) and \ |
1174 node.expr.node.name == 'import_wait': |
1176 node.expr.node.name == 'import_wait': |
1175 debugStmt = False |
1177 debugStmt = False |
1176 if debugStmt: |
1178 if debugStmt: |
1177 st = self.get_line_trace(node) |
1179 st = self.get_line_trace(node) |
1178 print >>self.output, "sys.addstack('%s');\n" % st |
1180 self.printo("sys.addstack('%s');\n" % st) |
1179 if isinstance(node.expr.node, ast.Name) and node.expr.node.name == NATIVE_JS_FUNC_NAME: |
1181 if isinstance(node.expr.node, ast.Name) and node.expr.node.name == NATIVE_JS_FUNC_NAME: |
1180 if len(node.expr.args) != 1: |
1182 if len(node.expr.args) != 1: |
1181 raise TranslationError("native javascript function %s must have one arg" % NATIVE_JS_FUNC_NAME, node.expr) |
1183 raise TranslationError("native javascript function %s must have one arg" % NATIVE_JS_FUNC_NAME, node.expr) |
1182 if not isinstance(node.expr.args[0], ast.Const): |
1184 if not isinstance(node.expr.args[0], ast.Const): |
1183 raise TranslationError("native javascript function %s must have constant arg" % NATIVE_JS_FUNC_NAME, node.expr) |
1185 raise TranslationError("native javascript function %s must have constant arg" % NATIVE_JS_FUNC_NAME, node.expr) |
1184 raw_js = node.expr.args[0].value |
1186 raw_js = node.expr.args[0].value |
1185 print >>self.output, raw_js |
1187 self.printo(raw_js) |
1186 else: |
1188 else: |
1187 expr = self._callfunc(node.expr, current_klass) |
1189 expr = self._callfunc(node.expr, current_klass) |
1188 print >>self.output, " " + expr + ";" |
1190 self.printo(" " + expr + ";") |
1189 |
1191 |
1190 if debugStmt: |
1192 if debugStmt: |
1191 print >>self.output, "sys.popstack();\n" |
1193 self.printo("sys.popstack();\n") |
1192 |
1194 |
1193 elif isinstance(node.expr, ast.Const): |
1195 elif isinstance(node.expr, ast.Const): |
1194 if node.expr.value is not None: # Empty statements generate ignore None |
1196 if node.expr.value is not None: # Empty statements generate ignore None |
1195 print >>self.output, self._const(node.expr) |
1197 self.printo(self._const(node.expr)) |
1196 else: |
1198 else: |
1197 raise TranslationError("unsupported type (in _discard)", node.expr) |
1199 raise TranslationError("unsupported type (in _discard)", node.expr) |
1198 |
1200 |
1199 def _if(self, node, current_klass): |
1201 def _if(self, node, current_klass): |
1200 for i in range(len(node.tests)): |
1202 for i in range(len(node.tests)): |
1215 |
1217 |
1216 def _if_test(self, keyword, test, consequence, current_klass): |
1218 def _if_test(self, keyword, test, consequence, current_klass): |
1217 if test: |
1219 if test: |
1218 expr = self.expr(test, current_klass) |
1220 expr = self.expr(test, current_klass) |
1219 |
1221 |
1220 print >>self.output, " " + keyword + " (pyjslib.bool(" + expr + ")) {" |
1222 self.printo(" " + keyword + " (pyjslib.bool(" + expr + ")) {") |
1221 else: |
1223 else: |
1222 print >>self.output, " " + keyword + " {" |
1224 self.printo(" " + keyword + " {") |
1223 |
1225 |
1224 if isinstance(consequence, ast.Stmt): |
1226 if isinstance(consequence, ast.Stmt): |
1225 for child in consequence.nodes: |
1227 for child in consequence.nodes: |
1226 self._stmt(child, current_klass) |
1228 self._stmt(child, current_klass) |
1227 else: |
1229 else: |
1228 raise TranslationError("unsupported type (in _if_test)", consequence) |
1230 raise TranslationError("unsupported type (in _if_test)", consequence) |
1229 |
1231 |
1230 print >>self.output, " }" |
1232 self.printo(" }") |
1231 |
1233 |
1232 def _from(self, node): |
1234 def _from(self, node): |
1233 for name in node.names: |
1235 for name in node.names: |
1234 # look up "hack" in AppTranslator as to how findFile gets here |
1236 # look up "hack" in AppTranslator as to how findFile gets here |
1235 module_name = node.modname + "." + name[0] |
1237 module_name = node.modname + "." + name[0] |
1313 raise TranslationError("unsupported type (in _for)", node.list) |
1315 raise TranslationError("unsupported type (in _for)", node.list) |
1314 |
1316 |
1315 lhs = "var " + assign_name |
1317 lhs = "var " + assign_name |
1316 iterator_name = "__" + assign_name |
1318 iterator_name = "__" + assign_name |
1317 |
1319 |
1318 print >>self.output, """ |
1320 self.printo(""" |
1319 var %(iterator_name)s = %(list_expr)s.__iter__(); |
1321 var %(iterator_name)s = %(list_expr)s.__iter__(); |
1320 try { |
1322 try { |
1321 while (true) { |
1323 while (true) { |
1322 %(lhs)s %(op)s %(iterator_name)s.next(); |
1324 %(lhs)s %(op)s %(iterator_name)s.next(); |
1323 %(assign_tuple)s |
1325 %(assign_tuple)s |
1324 """ % locals() |
1326 """ % locals()) |
1325 for node in node.body.nodes: |
1327 for node in node.body.nodes: |
1326 self._stmt(node, current_klass) |
1328 self._stmt(node, current_klass) |
1327 print >>self.output, """ |
1329 self.printo(""" |
1328 } |
1330 } |
1329 } catch (e) { |
1331 } catch (e) { |
1330 if (e.__name__ != pyjslib.StopIteration.__name__) { |
1332 if (e.__name__ != pyjslib.StopIteration.__name__) { |
1331 throw e; |
1333 throw e; |
1332 } |
1334 } |
1333 } |
1335 } |
1334 """ % locals() |
1336 """ % locals()) |
1335 |
1337 |
1336 def _while(self, node, current_klass): |
1338 def _while(self, node, current_klass): |
1337 test = self.expr(node.test, current_klass) |
1339 test = self.expr(node.test, current_klass) |
1338 print >>self.output, " while (pyjslib.bool(" + test + ")) {" |
1340 self.printo(" while (pyjslib.bool(" + test + ")) {") |
1339 if isinstance(node.body, ast.Stmt): |
1341 if isinstance(node.body, ast.Stmt): |
1340 for child in node.body.nodes: |
1342 for child in node.body.nodes: |
1341 self._stmt(child, current_klass) |
1343 self._stmt(child, current_klass) |
1342 else: |
1344 else: |
1343 raise TranslationError("unsupported type (in _while)", node.body) |
1345 raise TranslationError("unsupported type (in _while)", node.body) |
1344 print >>self.output, " }" |
1346 self.printo(" }") |
1345 |
1347 |
1346 def _const(self, node): |
1348 def _const(self, node): |
1347 if isinstance(node.value, int): |
1349 if isinstance(node.value, int): |
1348 return str(node.value) |
1350 return str(node.value) |
1349 elif isinstance(node.value, float): |
1351 elif isinstance(node.value, float): |
1409 else: |
1411 else: |
1410 raise TranslationError("unsupported flag (in _subscript)", node) |
1412 raise TranslationError("unsupported flag (in _subscript)", node) |
1411 |
1413 |
1412 def _subscript_stmt(self, node, current_klass): |
1414 def _subscript_stmt(self, node, current_klass): |
1413 if node.flags == "OP_DELETE": |
1415 if node.flags == "OP_DELETE": |
1414 print >>self.output, " " + self.expr(node.expr, current_klass) + ".__delitem__(" + self.expr(node.subs[0], current_klass) + ");" |
1416 self.printo(" " + self.expr(node.expr, current_klass) + ".__delitem__(" + self.expr(node.subs[0], current_klass) + ");") |
1415 else: |
1417 else: |
1416 raise TranslationError("unsupported flag (in _subscript)", node) |
1418 raise TranslationError("unsupported flag (in _subscript)", node) |
1417 |
1419 |
1418 def _list(self, node, current_klass): |
1420 def _list(self, node, current_klass): |
1419 return "new pyjslib.List([" + ", ".join([self.expr(x, current_klass) for x in node.nodes]) + "])" |
1421 return "new pyjslib.List([" + ", ".join([self.expr(x, current_klass) for x in node.nodes]) + "])" |
1437 res = cStringIO.StringIO() |
1439 res = cStringIO.StringIO() |
1438 arg_names = list(node.argnames) |
1440 arg_names = list(node.argnames) |
1439 function_args = ", ".join(arg_names) |
1441 function_args = ", ".join(arg_names) |
1440 for child in node.getChildNodes(): |
1442 for child in node.getChildNodes(): |
1441 expr = self.expr(child, None) |
1443 expr = self.expr(child, None) |
1442 print >> res, "function (%s){" % function_args |
1444 print("function (%s){" % function_args, file=res) |
1443 self._default_args_handler(node, arg_names, None, |
1445 self._default_args_handler(node, arg_names, None, |
1444 output=res) |
1446 output=res) |
1445 print >> res, 'return %s;}' % expr |
1447 print('return %s;}' % expr, file=res) |
1446 return res.getvalue() |
1448 return res.getvalue() |
1447 |
1449 |
1448 def _slice(self, node, current_klass): |
1450 def _slice(self, node, current_klass): |
1449 if node.flags == "OP_APPLY": |
1451 if node.flags == "OP_APPLY": |
1450 lower = "null" |
1452 lower = "null" |
1715 if library.endswith(".js"): |
1717 if library.endswith(".js"): |
1716 imported_js.add(library) |
1718 imported_js.add(library) |
1717 continue |
1719 continue |
1718 self.library_modules.append(library) |
1720 self.library_modules.append(library) |
1719 if self.verbose: |
1721 if self.verbose: |
1720 print 'Including LIB', library |
1722 print('Including LIB', library) |
1721 print >> lib_code, '\n//\n// BEGIN LIB '+library+'\n//\n' |
1723 print('\n//\n// BEGIN LIB '+library+'\n//\n', file=lib_code) |
1722 print >> lib_code, self._translate( |
1724 print(self._translate(library, False, debug=debug, imported_js=imported_js), |
1723 library, False, debug=debug, imported_js=imported_js) |
1725 file=lib_code) |
1724 |
1726 |
1725 print >> lib_code, "/* initialize static library */" |
1727 print("/* initialize static library */", file=lib_code) |
1726 print >> lib_code, "%s%s();\n" % (UU, library) |
1728 print("%s%s();\n" % (UU, library), file=lib_code) |
1727 |
1729 |
1728 print >> lib_code, '\n//\n// END LIB '+library+'\n//\n' |
1730 print('\n//\n// END LIB '+library+'\n//\n', file=lib_code) |
1729 if module_name: |
1731 if module_name: |
1730 print >> app_code, self._translate( |
1732 print(self._translate(module_name, is_app, debug=debug, imported_js=imported_js), |
1731 module_name, is_app, debug=debug, imported_js=imported_js) |
1733 file=app_code) |
1732 for js in imported_js: |
1734 for js in imported_js: |
1733 path = self.findFile(js) |
1735 path = self.findFile(js) |
1734 if os.path.isfile(path): |
1736 if os.path.isfile(path): |
1735 if self.verbose: |
1737 if self.verbose: |
1736 print 'Including JS', js |
1738 print('Including JS', js) |
1737 print >> lib_code, '\n//\n// BEGIN JS '+js+'\n//\n' |
1739 print('\n//\n// BEGIN JS '+js+'\n//\n', file=lib_code) |
1738 print >> lib_code, file(path).read() |
1740 print(file(path).read(), file=lib_code) |
1739 print >> lib_code, '\n//\n// END JS '+js+'\n//\n' |
1741 print('\n//\n// END JS '+js+'\n//\n', file=lib_code) |
1740 else: |
1742 else: |
1741 print >>sys.stderr, 'Warning: Unable to find imported javascript:', js |
1743 print('Warning: Unable to find imported javascript:', js, file=sys.stderr) |
1742 return lib_code.getvalue(), app_code.getvalue() |
1744 return lib_code.getvalue(), app_code.getvalue() |
1743 |
1745 |
1744 |
1746 |
1745 usage = """ |
1747 usage = """ |
1746 usage: %s file_name [module_name] |
1748 usage: %s file_name [module_name] |
1748 |
1750 |
1749 |
1751 |
1750 def main(): |
1752 def main(): |
1751 import sys |
1753 import sys |
1752 if len(sys.argv) < 2: |
1754 if len(sys.argv) < 2: |
1753 print >> sys.stderr, usage % sys.argv[0] |
1755 print(usage % sys.argv[0], file=sys.stderr) |
1754 sys.exit(1) |
1756 sys.exit(1) |
1755 file_name = os.path.abspath(sys.argv[1]) |
1757 file_name = os.path.abspath(sys.argv[1]) |
1756 if not os.path.isfile(file_name): |
1758 if not os.path.isfile(file_name): |
1757 print >> sys.stderr, "File not found %s" % file_name |
1759 print("File not found %s" % file_name, file=sys.stderr) |
1758 sys.exit(1) |
1760 sys.exit(1) |
1759 if len(sys.argv) > 2: |
1761 if len(sys.argv) > 2: |
1760 module_name = sys.argv[2] |
1762 module_name = sys.argv[2] |
1761 else: |
1763 else: |
1762 module_name = None |
1764 module_name = None |
1763 print translate(file_name, module_name), |
1765 print(translate(file_name, module_name), end="") |
1764 |
1766 |
1765 |
1767 |
1766 if __name__ == "__main__": |
1768 if __name__ == "__main__": |
1767 main() |
1769 main() |