infer plain object for bytes_string[i] and str/unicode for indexed unicode/str objects
[cython.git] / Cython / CodeWriter.py
index aad485c6a3c2568cfe3a0177b35f99f0320df00d..0be3881729bf7e5b083ceaf309d9e0849385ce30 100644 (file)
@@ -1,7 +1,6 @@
 from Cython.Compiler.Visitor import TreeVisitor
 from Cython.Compiler.Nodes import *
 from Cython.Compiler.ExprNodes import *
-from Cython.Compiler.Symtab import TempName
 
 """
 Serializes a Cython code tree to Cython code. This is primarily useful for
@@ -38,6 +37,7 @@ class CodeWriter(TreeVisitor):
         self.result = result
         self.numindents = 0
         self.tempnames = {}
+        self.tempblockindex = 0
     
     def write(self, tree):
         self.visit(tree)
@@ -61,18 +61,13 @@ class CodeWriter(TreeVisitor):
         self.startline(s)
         self.endline()
 
-    def putname(self, name):
-        if isinstance(name, TempName):
-            name = self.tempnames.setdefault(name, u"$" + name.description)
-        self.put(name)
-    
-    def comma_seperated_list(self, items, output_rhs=False):
+    def comma_separated_list(self, items, output_rhs=False):
         if len(items) > 0:
             for item in items[:-1]:
                 self.visit(item)
-                if output_rhs and item.rhs is not None:
+                if output_rhs and item.default is not None:
                     self.put(u" = ")
-                    self.visit(item.rhs)
+                    self.visit(item.default)
                 self.put(u", ")
             self.visit(items[-1])
     
@@ -87,7 +82,7 @@ class CodeWriter(TreeVisitor):
 
     def visit_FuncDefNode(self, node):
         self.startline(u"def %s(" % node.name)
-        self.comma_seperated_list(node.args)
+        self.comma_separated_list(node.args)
         self.endline(u"):")
         self.indent()
         self.visit(node.body)
@@ -123,12 +118,27 @@ class CodeWriter(TreeVisitor):
         self.visit(node.rhs)
         self.endline()
     
+    def visit_CascadedAssignmentNode(self, node):
+        self.startline()
+        for lhs in node.lhs_list:
+            self.visit(lhs)
+            self.put(u" = ")
+        self.visit(node.rhs)
+        self.endline()
+    
     def visit_NameNode(self, node):
-        self.putname(node.name)
+        self.put(node.name)
     
     def visit_IntNode(self, node):
         self.put(node.value)
-        
+
+    # FIXME: represent string nodes correctly
+    def visit_StringNode(self, node):
+        value = node.value
+        if value.encoding is not None:
+            value = value.encode(value.encoding)
+        self.put(repr(value))
+
     def visit_IfStatNode(self, node):
         # The IfClauseNode is handled directly without a seperate match
         # for clariy.
@@ -157,7 +167,7 @@ class CodeWriter(TreeVisitor):
     
     def visit_PrintStatNode(self, node):
         self.startline(u"print ")
-        self.comma_seperated_list(node.arg_tuple.args)
+        self.comma_separated_list(node.arg_tuple.args)
         if not node.append_newline:
             self.put(u",")
         self.endline()
@@ -171,7 +181,7 @@ class CodeWriter(TreeVisitor):
         self.startline(u"cdef ")
         self.visit(node.base_type)
         self.put(u" ")
-        self.comma_seperated_list(node.declarators, output_rhs=True)
+        self.comma_separated_list(node.declarators, output_rhs=True)
         self.endline()
 
     def visit_ForInStatNode(self, node):
@@ -190,12 +200,12 @@ class CodeWriter(TreeVisitor):
             self.dedent()
 
     def visit_SequenceNode(self, node):
-        self.comma_seperated_list(node.args) # Might need to discover whether we need () around tuples...hmm...
+        self.comma_separated_list(node.args) # Might need to discover whether we need () around tuples...hmm...
     
     def visit_SimpleCallNode(self, node):
         self.visit(node.function)
         self.put(u"(")
-        self.comma_seperated_list(node.args)
+        self.comma_separated_list(node.args)
         self.put(")")
 
     def visit_GeneralCallNode(self, node):
@@ -205,7 +215,7 @@ class CodeWriter(TreeVisitor):
         if isinstance(posarg, AsTupleNode):
             self.visit(posarg.arg)
         else:
-            self.comma_seperated_list(posarg)
+            self.comma_separated_list(posarg)
         if node.keyword_args is not None or node.starstar_arg is not None:
             raise Exception("Not implemented yet")
         self.put(u")")
@@ -274,6 +284,16 @@ class CodeWriter(TreeVisitor):
         self.visit(node.body)
         self.dedent()
 
+    def visit_ReturnStatNode(self, node):
+        self.startline("return ")
+        self.visit(node.value)
+        self.endline()
+
+    def visit_DecoratorNode(self, node):
+        self.startline("@")
+        self.visit(node.decorator)
+        self.endline()
+
     def visit_ReraiseStatNode(self, node):
         self.line("raise")
 
@@ -288,3 +308,18 @@ class CodeWriter(TreeVisitor):
         self.visit(node.operand)
         self.put(u")")
 
+    def visit_TempsBlockNode(self, node):
+        """
+        Temporaries are output like $1_1', where the first number is
+        an index of the TempsBlockNode and the second number is an index
+        of the temporary which that block allocates.
+        """
+        idx = 0
+        for handle in node.temps:
+            self.tempnames[handle] = "$%d_%d" % (self.tempblockindex, idx)
+            idx += 1
+        self.tempblockindex += 1
+        self.visit(node.body)
+
+    def visit_TempRefNode(self, node):
+        self.put(self.tempnames[node.handle])