233 print >>self.output, UU+"%s.__name__ = __mod_name__;" % (raw_module_name) |
233 print >>self.output, UU+"%s.__name__ = __mod_name__;" % (raw_module_name) |
234 |
234 |
235 decl = mod_var_name_decl(raw_module_name) |
235 decl = mod_var_name_decl(raw_module_name) |
236 if decl: |
236 if decl: |
237 print >>self.output, decl |
237 print >>self.output, decl |
238 |
|
239 |
238 |
240 if self.debug: |
239 if self.debug: |
241 haltException = self.module_prefix + "HaltException" |
240 haltException = self.module_prefix + "HaltException" |
242 print >>self.output, haltException + ' = function () {' |
241 print >>self.output, haltException + ' = function () {' |
243 print >>self.output, ' this.message = "Program Halted";' |
242 print >>self.output, ' this.message = "Program Halted";' |
457 print >>self.output, " return null;" |
456 print >>self.output, " return null;" |
458 |
457 |
459 print >>self.output, "};" |
458 print >>self.output, "};" |
460 print >>self.output, "%s.__name__ = '%s';\n" % (function_name, node.name) |
459 print >>self.output, "%s.__name__ = '%s';\n" % (function_name, node.name) |
461 |
460 |
462 |
|
463 self._kwargs_parser(node, function_name, normal_arg_names, None) |
461 self._kwargs_parser(node, function_name, normal_arg_names, None) |
464 |
|
465 |
462 |
466 def _return(self, node, current_klass): |
463 def _return(self, node, current_klass): |
467 expr = self.expr(node.value, current_klass) |
464 expr = self.expr(node.value, current_klass) |
468 # in python a function call always returns None, so we do it |
465 # in python a function call always returns None, so we do it |
469 # here too |
466 # here too |
470 print >>self.output, " return " + expr + ";" |
467 print >>self.output, " return " + expr + ";" |
471 |
468 |
472 |
|
473 def _break(self, node, current_klass): |
469 def _break(self, node, current_klass): |
474 print >>self.output, " break;" |
470 print >>self.output, " break;" |
475 |
471 |
476 |
|
477 def _continue(self, node, current_klass): |
472 def _continue(self, node, current_klass): |
478 print >>self.output, " continue;" |
473 print >>self.output, " continue;" |
479 |
|
480 |
474 |
481 def _callfunc(self, v, current_klass): |
475 def _callfunc(self, v, current_klass): |
482 |
476 |
483 if isinstance(v.node, ast.Name): |
477 if isinstance(v.node, ast.Name): |
484 if v.node.name in self.top_level_functions: |
478 if v.node.name in self.top_level_functions: |
630 return self._subscript(v.expr, self.modpfx()) + "." + attr_name |
624 return self._subscript(v.expr, self.modpfx()) + "." + attr_name |
631 elif isinstance(v.expr, ast.CallFunc): |
625 elif isinstance(v.expr, ast.CallFunc): |
632 return self._callfunc(v.expr, self.modpfx()) + "." + attr_name |
626 return self._callfunc(v.expr, self.modpfx()) + "." + attr_name |
633 else: |
627 else: |
634 raise TranslationError("unsupported type (in _getattr)", v.expr) |
628 raise TranslationError("unsupported type (in _getattr)", v.expr) |
635 |
|
636 |
629 |
637 def modpfx(self): |
630 def modpfx(self): |
638 return strip_py(self.module_prefix) |
631 return strip_py(self.module_prefix) |
639 |
632 |
640 def _name(self, v, current_klass, top_level=False, |
633 def _name(self, v, current_klass, top_level=False, |
715 else: |
708 else: |
716 call_name = UU+self._name(v, current_klass) + "." + attr_name |
709 call_name = UU+self._name(v, current_klass) + "." + attr_name |
717 |
710 |
718 return call_name |
711 return call_name |
719 |
712 |
720 |
|
721 def _getattr2(self, v, current_klass, attr_name): |
713 def _getattr2(self, v, current_klass, attr_name): |
722 if isinstance(v.expr, ast.Getattr): |
714 if isinstance(v.expr, ast.Getattr): |
723 call_name = self._getattr2(v.expr, current_klass, v.attrname + "." + attr_name) |
715 call_name = self._getattr2(v.expr, current_klass, v.attrname + "." + attr_name) |
724 elif isinstance(v.expr, ast.Name) and v.expr.name in self.module_imports(): |
716 elif isinstance(v.expr, ast.Name) and v.expr.name in self.module_imports(): |
725 call_name = UU+v.expr.name + '.__' +v.attrname+".prototype.__class__."+attr_name |
717 call_name = UU+v.expr.name + '.__' +v.attrname+".prototype.__class__."+attr_name |
726 else: |
718 else: |
727 obj = self.expr(v.expr, current_klass) |
719 obj = self.expr(v.expr, current_klass) |
728 call_name = obj + "." + v.attrname + "." + attr_name |
720 call_name = obj + "." + v.attrname + "." + attr_name |
729 |
721 |
730 return call_name |
722 return call_name |
731 |
|
732 |
723 |
733 def _class(self, node): |
724 def _class(self, node): |
734 """ |
725 """ |
735 Handle a class definition. |
726 Handle a class definition. |
736 |
727 |
766 for child in node.code: |
757 for child in node.code: |
767 if isinstance(child, ast.Function): |
758 if isinstance(child, ast.Function): |
768 current_klass.add_function(child.name) |
759 current_klass.add_function(child.name) |
769 if child.name == "__init__": |
760 if child.name == "__init__": |
770 init_method = child |
761 init_method = child |
771 |
|
772 |
762 |
773 if len(node.bases) == 0: |
763 if len(node.bases) == 0: |
774 base_class = "pyjslib.__Object" |
764 base_class = "pyjslib.__Object" |
775 elif len(node.bases) == 1: |
765 elif len(node.bases) == 1: |
776 if isinstance(node.bases[0], ast.Name): |
766 if isinstance(node.bases[0], ast.Name): |
853 raise TranslationError("unsupported type (in _class)", child) |
843 raise TranslationError("unsupported type (in _class)", child) |
854 print >>self.output, "}" |
844 print >>self.output, "}" |
855 |
845 |
856 print >> self.output, class_name_+".__initialize__();" |
846 print >> self.output, class_name_+".__initialize__();" |
857 |
847 |
858 |
|
859 def classattr(self, node, current_klass): |
848 def classattr(self, node, current_klass): |
860 self._assign(node, current_klass, True) |
849 self._assign(node, current_klass, True) |
861 |
850 |
862 def _raise(self, node, current_klass): |
851 def _raise(self, node, current_klass): |
863 if node.expr2: |
852 if node.expr2: |
915 local_arg_names = normal_arg_names + declared_arg_names |
904 local_arg_names = normal_arg_names + declared_arg_names |
916 |
905 |
917 if node.varargs: |
906 if node.varargs: |
918 self._varargs_handler(node, varargname, declared_arg_names, current_klass) |
907 self._varargs_handler(node, varargname, declared_arg_names, current_klass) |
919 local_arg_names.append(varargname) |
908 local_arg_names.append(varargname) |
920 |
|
921 |
909 |
922 # stack of local variable names for this function call |
910 # stack of local variable names for this function call |
923 self.local_arg_stack.append(local_arg_names) |
911 self.local_arg_stack.append(local_arg_names) |
924 |
912 |
925 for child in node.code: |
913 for child in node.code: |
1033 |
1021 |
1034 print >>self.output, ' throw new ' + self.module_prefix + "HaltException();" |
1022 print >>self.output, ' throw new ' + self.module_prefix + "HaltException();" |
1035 print >>self.output, ' }' |
1023 print >>self.output, ' }' |
1036 print >>self.output, ' }' |
1024 print >>self.output, ' }' |
1037 |
1025 |
1038 |
|
1039 def get_line_trace(self, node): |
1026 def get_line_trace(self, node): |
1040 lineNum = "Unknown" |
1027 lineNum = "Unknown" |
1041 srcLine = "" |
1028 srcLine = "" |
1042 if hasattr(node, "lineno"): |
1029 if hasattr(node, "lineno"): |
1043 if node.lineno != None: |
1030 if node.lineno != None: |
1061 else: |
1048 else: |
1062 lhs = self._name(node.node, current_klass) |
1049 lhs = self._name(node.node, current_klass) |
1063 op = node.op |
1050 op = node.op |
1064 rhs = self.expr(node.expr, current_klass) |
1051 rhs = self.expr(node.expr, current_klass) |
1065 print >>self.output, " " + lhs + " " + op + " " + rhs + ";" |
1052 print >>self.output, " " + lhs + " " + op + " " + rhs + ";" |
1066 |
|
1067 |
1053 |
1068 def _assign(self, node, current_klass, top_level = False): |
1054 def _assign(self, node, current_klass, top_level = False): |
1069 if len(node.nodes) != 1: |
1055 if len(node.nodes) != 1: |
1070 tempvar = '__temp'+str(node.lineno) |
1056 tempvar = '__temp'+str(node.lineno) |
1071 tnode = ast.Assign([ast.AssName(tempvar, "OP_ASSIGN", node.lineno)], node.expr, node.lineno) |
1057 tnode = ast.Assign([ast.AssName(tempvar, "OP_ASSIGN", node.lineno)], node.expr, node.lineno) |
1174 rhs = self.expr(node.expr, current_klass) |
1160 rhs = self.expr(node.expr, current_klass) |
1175 if dbg: |
1161 if dbg: |
1176 print "b", repr(node.expr), rhs |
1162 print "b", repr(node.expr), rhs |
1177 print >>self.output, " " + lhs + " " + op + " " + rhs + ";" |
1163 print >>self.output, " " + lhs + " " + op + " " + rhs + ";" |
1178 |
1164 |
1179 |
|
1180 def _discard(self, node, current_klass): |
1165 def _discard(self, node, current_klass): |
1181 |
1166 |
1182 if isinstance(node.expr, ast.CallFunc): |
1167 if isinstance(node.expr, ast.CallFunc): |
1183 debugStmt = self.debug and not self._isNativeFunc(node) |
1168 debugStmt = self.debug and not self._isNativeFunc(node) |
1184 if debugStmt and isinstance(node.expr.node, ast.Name) and \ |
1169 if debugStmt and isinstance(node.expr.node, ast.Name) and \ |
1205 if node.expr.value is not None: # Empty statements generate ignore None |
1190 if node.expr.value is not None: # Empty statements generate ignore None |
1206 print >>self.output, self._const(node.expr) |
1191 print >>self.output, self._const(node.expr) |
1207 else: |
1192 else: |
1208 raise TranslationError("unsupported type (in _discard)", node.expr) |
1193 raise TranslationError("unsupported type (in _discard)", node.expr) |
1209 |
1194 |
1210 |
|
1211 def _if(self, node, current_klass): |
1195 def _if(self, node, current_klass): |
1212 for i in range(len(node.tests)): |
1196 for i in range(len(node.tests)): |
1213 test, consequence = node.tests[i] |
1197 test, consequence = node.tests[i] |
1214 if i == 0: |
1198 if i == 0: |
1215 keyword = "if" |
1199 keyword = "if" |
1223 test = None |
1207 test = None |
1224 consequence = node.else_ |
1208 consequence = node.else_ |
1225 |
1209 |
1226 self._if_test(keyword, test, consequence, current_klass) |
1210 self._if_test(keyword, test, consequence, current_klass) |
1227 |
1211 |
1228 |
|
1229 def _if_test(self, keyword, test, consequence, current_klass): |
1212 def _if_test(self, keyword, test, consequence, current_klass): |
1230 if test: |
1213 if test: |
1231 expr = self.expr(test, current_klass) |
1214 expr = self.expr(test, current_klass) |
1232 |
1215 |
1233 print >>self.output, " " + keyword + " (pyjslib.bool(" + expr + ")) {" |
1216 print >>self.output, " " + keyword + " (pyjslib.bool(" + expr + ")) {" |
1239 self._stmt(child, current_klass) |
1222 self._stmt(child, current_klass) |
1240 else: |
1223 else: |
1241 raise TranslationError("unsupported type (in _if_test)", consequence) |
1224 raise TranslationError("unsupported type (in _if_test)", consequence) |
1242 |
1225 |
1243 print >>self.output, " }" |
1226 print >>self.output, " }" |
1244 |
|
1245 |
1227 |
1246 def _from(self, node): |
1228 def _from(self, node): |
1247 for name in node.names: |
1229 for name in node.names: |
1248 # look up "hack" in AppTranslator as to how findFile gets here |
1230 # look up "hack" in AppTranslator as to how findFile gets here |
1249 module_name = node.modname + "." + name[0] |
1231 module_name = node.modname + "." + name[0] |
1254 if ff: |
1236 if ff: |
1255 self.add_imported_module(module_name) |
1237 self.add_imported_module(module_name) |
1256 else: |
1238 else: |
1257 self.imported_classes[name[0]] = node.modname |
1239 self.imported_classes[name[0]] = node.modname |
1258 |
1240 |
1259 |
|
1260 def _compare(self, node, current_klass): |
1241 def _compare(self, node, current_klass): |
1261 lhs = self.expr(node.expr, current_klass) |
1242 lhs = self.expr(node.expr, current_klass) |
1262 |
1243 |
1263 if len(node.ops) != 1: |
1244 if len(node.ops) != 1: |
1264 raise TranslationError("only one ops supported (in _compare)", node) |
1245 raise TranslationError("only one ops supported (in _compare)", node) |
1277 op = "===" |
1258 op = "===" |
1278 elif op == "is not": |
1259 elif op == "is not": |
1279 op = "!==" |
1260 op = "!==" |
1280 |
1261 |
1281 return "(" + lhs + " " + op + " " + rhs + ")" |
1262 return "(" + lhs + " " + op + " " + rhs + ")" |
1282 |
|
1283 |
1263 |
1284 def _not(self, node, current_klass): |
1264 def _not(self, node, current_klass): |
1285 expr = self.expr(node.expr, current_klass) |
1265 expr = self.expr(node.expr, current_klass) |
1286 |
1266 |
1287 return "!(" + expr + ")" |
1267 return "!(" + expr + ")" |
1347 throw e; |
1327 throw e; |
1348 } |
1328 } |
1349 } |
1329 } |
1350 """ % locals() |
1330 """ % locals() |
1351 |
1331 |
1352 |
|
1353 def _while(self, node, current_klass): |
1332 def _while(self, node, current_klass): |
1354 test = self.expr(node.test, current_klass) |
1333 test = self.expr(node.test, current_klass) |
1355 print >>self.output, " while (pyjslib.bool(" + test + ")) {" |
1334 print >>self.output, " while (pyjslib.bool(" + test + ")) {" |
1356 if isinstance(node.body, ast.Stmt): |
1335 if isinstance(node.body, ast.Stmt): |
1357 for child in node.body.nodes: |
1336 for child in node.body.nodes: |
1358 self._stmt(child, current_klass) |
1337 self._stmt(child, current_klass) |
1359 else: |
1338 else: |
1360 raise TranslationError("unsupported type (in _while)", node.body) |
1339 raise TranslationError("unsupported type (in _while)", node.body) |
1361 print >>self.output, " }" |
1340 print >>self.output, " }" |
1362 |
|
1363 |
1341 |
1364 def _const(self, node): |
1342 def _const(self, node): |
1365 if isinstance(node.value, int): |
1343 if isinstance(node.value, int): |
1366 return str(node.value) |
1344 return str(node.value) |
1367 elif isinstance(node.value, float): |
1345 elif isinstance(node.value, float): |
1537 return self._lambda(node, current_klass) |
1515 return self._lambda(node, current_klass) |
1538 else: |
1516 else: |
1539 raise TranslationError("unsupported type (in expr)", node) |
1517 raise TranslationError("unsupported type (in expr)", node) |
1540 |
1518 |
1541 |
1519 |
1542 |
|
1543 import cStringIO |
1520 import cStringIO |
1544 |
1521 |
1545 |
1522 |
1546 def translate(file_name, module_name, debug=False): |
1523 def translate(file_name, module_name, debug=False): |
1547 f = file(file_name, "r") |
1524 f = file(file_name, "r") |
1723 #imported_js.update(set(t.imported_js)) |
1700 #imported_js.update(set(t.imported_js)) |
1724 #imported_modules_str += self._translate( |
1701 #imported_modules_str += self._translate( |
1725 # module, False, debug=debug, imported_js=imported_js) |
1702 # module, False, debug=debug, imported_js=imported_js) |
1726 |
1703 |
1727 return imported_modules_str + module_str |
1704 return imported_modules_str + module_str |
1728 |
|
1729 |
1705 |
1730 def translate(self, module_name, is_app=True, debug=False, |
1706 def translate(self, module_name, is_app=True, debug=False, |
1731 library_modules=[]): |
1707 library_modules=[]): |
1732 app_code = cStringIO.StringIO() |
1708 app_code = cStringIO.StringIO() |
1733 lib_code = cStringIO.StringIO() |
1709 lib_code = cStringIO.StringIO() |