1 from Cython.Compiler.Visitor import TreeVisitor
2 from Cython.Compiler.Nodes import *
5 Serializes a Cython code tree to Cython code. This is primarily useful for
6 debugging and testing purposes.
8 The output is in a strict format, no whitespace or comments from the input
9 is preserved (and it could not be as it is not present in the code tree).
12 class LinesResult(object):
21 self.lines.append(self.s)
28 class CodeWriter(TreeVisitor):
32 def __init__(self, result = None):
33 super(CodeWriter, self).__init__()
35 result = LinesResult()
39 def write(self, tree):
48 def startline(self, s = u""):
49 self.result.put(self.indent_string * self.numindents + s)
54 def endline(self, s = u""):
55 self.result.putline(s)
61 def comma_seperated_list(self, items, output_rhs=False):
63 for item in items[:-1]:
65 if output_rhs and item.rhs is not None:
71 def visit_Node(self, node):
72 raise AssertionError("Node not handled by serializer: %r" % node)
74 def visit_ModuleNode(self, node):
75 self.visitchildren(node)
77 def visit_StatListNode(self, node):
78 self.visitchildren(node)
80 def visit_FuncDefNode(self, node):
81 self.startline(u"def %s(" % node.name)
82 self.comma_seperated_list(node.args)
88 def visit_CArgDeclNode(self, node):
89 if node.base_type.name is not None:
90 self.visit(node.base_type)
92 self.visit(node.declarator)
93 if node.default is not None:
95 self.visit(node.default)
97 def visit_CNameDeclaratorNode(self, node):
100 def visit_CSimpleBaseTypeNode(self, node):
101 # See Parsing.p_sign_and_longness
102 if node.is_basic_c_type:
103 self.put(("unsigned ", "", "signed ")[node.signed])
104 if node.longness < 0:
105 self.put("short " * -node.longness)
106 elif node.longness > 0:
107 self.put("long " * node.longness)
111 def visit_SingleAssignmentNode(self, node):
118 def visit_NameNode(self, node):
121 def visit_IntNode(self, node):
124 def visit_IfStatNode(self, node):
125 # The IfClauseNode is handled directly without a seperate match
127 self.startline(u"if ")
128 self.visit(node.if_clauses[0].condition)
131 self.visit(node.if_clauses[0].body)
133 for clause in node.if_clauses[1:]:
134 self.startline("elif ")
135 self.visit(clause.condition)
138 self.visit(clause.body)
140 if node.else_clause is not None:
143 self.visit(node.else_clause)
146 def visit_PassStatNode(self, node):
147 self.startline(u"pass")
150 def visit_PrintStatNode(self, node):
151 self.startline(u"print ")
152 self.comma_seperated_list(node.arg_tuple.args)
153 if not node.append_newline:
157 def visit_BinopNode(self, node):
158 self.visit(node.operand1)
159 self.put(u" %s " % node.operator)
160 self.visit(node.operand2)
162 def visit_CVarDefNode(self, node):
163 self.startline(u"cdef ")
164 self.visit(node.base_type)
166 self.comma_seperated_list(node.declarators, output_rhs=True)
169 def visit_ForInStatNode(self, node):
170 self.startline(u"for ")
171 self.visit(node.target)
173 self.visit(node.iterator.sequence)
176 self.visit(node.body)
178 if node.else_clause is not None:
181 self.visit(node.else_clause)
184 def visit_SequenceNode(self, node):
185 self.comma_seperated_list(node.args) # Might need to discover whether we need () around tuples...hmm...
187 def visit_SimpleCallNode(self, node):
188 self.put(node.function.name + u"(")
189 self.comma_seperated_list(node.args)
192 def visit_ExprStatNode(self, node):
194 self.visit(node.expr)
197 def visit_InPlaceAssignmentNode(self, node):
200 self.put(" %s= " % node.operator)