2525from ast import parse
2626from ast import NodeVisitor
2727
28+ import typedpython
2829import ministdlib
2930import inline_function
3031import code_writer
3132from ast_utils import *
3233
33-
3434## TODO
3535def log (txt ):
3636 pass
3737
3838
39+ POWER_OF_TWO = [ 2 ** i for i in range (32 ) ]
40+
3941GLOBAL_VARIABLE_SCOPE = False ## Python style
4042if '--global-variable-scope' in sys .argv : ## JavaScript style
4143 GLOBAL_VARIABLE_SCOPE = True
@@ -121,6 +123,9 @@ class PythonToPythonJS(NodeVisitor, inline_function.Inliner):
121123 _func_typedefs = ()
122124
123125 def __init__ (self , source = None , module = None , module_path = None , dart = False , coffee = False , lua = False ):
126+
127+ source = typedpython .transform_source ( source )
128+
124129 super (PythonToPythonJS , self ).__init__ ()
125130 self .setup_inliner ( writer )
126131
@@ -144,7 +149,8 @@ def __init__(self, source=None, module=None, module_path=None, dart=False, coffe
144149 self ._instance_attributes = dict () ## class name : [attribute names]
145150 self ._class_attributes = dict ()
146151 self ._catch_attributes = None
147- self ._names = set () ## not used?
152+ self ._typedef_vars = dict ()
153+ #self._names = set() ## not used?
148154 self ._instances = dict () ## instance name : class name
149155 self ._decorator_properties = dict ()
150156 self ._decorator_class_props = dict ()
@@ -1162,6 +1168,14 @@ def visit_BinOp(self, node):
11621168 else :
11631169 return '[%s]' % ',' .join (expanded )
11641170
1171+ elif op == '*' and left in self ._typedef_vars and self ._typedef_vars [left ]== 'int' and isinstance (node .right , ast .Num ) and node .right .n in POWER_OF_TWO :
1172+ power = POWER_OF_TWO .index ( node .right .n )
1173+ return '%s << %s' % (left , power )
1174+
1175+ elif op == '//' and left in self ._typedef_vars and self ._typedef_vars [left ]== 'int' and isinstance (node .right , ast .Num ) and node .right .n in POWER_OF_TWO :
1176+ power = POWER_OF_TWO .index ( node .right .n )
1177+ return '%s >> %s' % (left , power )
1178+
11651179 elif op == '//' :
11661180 if self ._with_dart :
11671181 return '(%s/%s).floor()' % (left , right )
@@ -1174,6 +1188,9 @@ def visit_BinOp(self, node):
11741188 elif op == '+' and not self ._with_dart :
11751189 if '+' in self ._direct_operators :
11761190 return '%s+%s' % (left , right )
1191+ elif left in self ._typedef_vars and self ._typedef_vars [left ] in typedpython .number_types :
1192+ return '%s+%s' % (left , right )
1193+
11771194 elif self ._with_lua or self ._in_lambda or self ._in_while_test :
11781195 ## this is also required when in an inlined lambda like "(lambda a,b: a+b)(1,2)"
11791196 return '__add_op(%s, %s)' % (left , right )
@@ -1444,7 +1461,16 @@ def visit_Assign(self, node):
14441461 writer .write ('try:' )
14451462 writer .push ()
14461463
1447- for target in node .targets :
1464+ targets = list ( node .targets )
1465+ target = targets [0 ]
1466+ if isinstance (target , ast .Name ) and target .id in typedpython .types :
1467+ if len (targets )== 2 and isinstance (targets [1 ], ast .Name ):
1468+ self ._typedef_vars [ targets [1 ].id ] = target .id
1469+ targets = targets [1 :]
1470+ else :
1471+ raise SyntaxError (targets )
1472+
1473+ for target in targets :
14481474 self ._visit_assign_helper ( node , target )
14491475 node = ast .Expr ( value = target )
14501476
@@ -2664,6 +2690,8 @@ def visit_FunctionDef(self, node):
26642690
26652691 writer .pull () ## end function body
26662692
2693+ self ._typedef_vars = dict () ## clear typed variables
2694+
26672695 if inline :
26682696 self ._with_inline = False
26692697
0 commit comments