self.put(s)
self.newline()
-class CodeWriter(TreeVisitor):
+class DeclarationWriter(TreeVisitor):
indent_string = u" "
def __init__(self, result = None):
- super(CodeWriter, self).__init__()
+ super(DeclarationWriter, self).__init__()
if result is None:
result = LinesResult()
self.result = result
def write(self, tree):
self.visit(tree)
+ return self.result
def indent(self):
self.numindents += 1
def put(self, s):
self.result.put(s)
+ def putline(self, s):
+ self.result.putline(self.indent_string * self.numindents + s)
+
def endline(self, s = u""):
self.result.putline(s)
def visit_StatListNode(self, node):
self.visitchildren(node)
-
- def visit_FuncDefNode(self, node):
- self.startline(u"def %s(" % node.name)
- self.comma_separated_list(node.args)
- self.endline(u"):")
+
+ def visit_CDefExternNode(self, node):
+ if node.include_file is None:
+ file = u'*'
+ else:
+ file = u'"%s"' % node.include_file
+ self.putline(u"cdef extern from %s:" % file)
self.indent()
self.visit(node.body)
self.dedent()
- def visit_CArgDeclNode(self, node):
- if node.base_type.name is not None:
- self.visit(node.base_type)
- self.put(u" ")
- self.visit(node.declarator)
- if node.default is not None:
- self.put(u" = ")
- self.visit(node.default)
+ def visit_CPtrDeclaratorNode(self, node):
+ self.put('*')
+ self.visit(node.base)
+
+ def visit_CReferenceDeclaratorNode(self, node):
+ self.put('&')
+ self.visit(node.base)
+
+ def visit_CArrayDeclaratorNode(self, node):
+ self.visit(node.base)
+ self.put(u'[')
+ if node.dimension is not None:
+ self.visit(node.dimension)
+ self.put(u']')
+
+ def visit_CArrayDeclaratorNode(self, node):
+ self.visit(node.base)
+ self.put(u'[')
+ if node.dimension is not None:
+ self.visit(node.dimension)
+ self.put(u']')
+
+ def visit_CFuncDeclaratorNode(self, node):
+ # TODO: except, gil, etc.
+ self.visit(node.base)
+ self.put(u'(')
+ self.comma_separated_list(node.args)
+ self.endline(u')')
def visit_CNameDeclaratorNode(self, node):
self.put(node.name)
self.put("short " * -node.longness)
elif node.longness > 0:
self.put("long " * node.longness)
+ self.put(node.name)
+
+ def visit_CComplexBaseTypeNode(self, node):
+ self.put(u'(')
+ self.visit(node.base_type)
+ self.visit(node.declarator)
+ self.put(u')')
+ def visit_CNestedBaseTypeNode(self, node):
+ self.visit(node.base_type)
+ self.put(u'.')
self.put(node.name)
- def visit_SingleAssignmentNode(self, node):
- self.startline()
- self.visit(node.lhs)
- self.put(u" = ")
- self.visit(node.rhs)
+ def visit_TemplatedTypeNode(self, node):
+ self.visit(node.base_type_node)
+ self.put(u'[')
+ self.comma_separated_list(node.positional_args + node.keyword_args.key_value_pairs)
+ self.put(u']')
+
+ def visit_CVarDefNode(self, node):
+ self.startline(u"cdef ")
+ self.visit(node.base_type)
+ self.put(u" ")
+ self.comma_separated_list(node.declarators, output_rhs=True)
self.endline()
- def visit_CascadedAssignmentNode(self, node):
- self.startline()
- for lhs in node.lhs_list:
- self.visit(lhs)
+ def visit_container_node(self, node, decl, extras, attributes):
+ # TODO: visibility
+ self.startline(decl)
+ if node.name:
+ self.put(u' ')
+ self.put(node.name)
+ if node.cname is not None:
+ self.put(u' "%s"' % node.cname)
+ if extras:
+ self.put(extras)
+ self.endline(':')
+ self.indent()
+ if not attributes:
+ self.putline('pass')
+ else:
+ for attribute in attributes:
+ self.visit(attribute)
+ self.dedent()
+
+ def visit_CStructOrUnionDefNode(self, node):
+ if node.typedef_flag:
+ decl = u'ctypedef '
+ else:
+ decl = u'cdef '
+ if node.visibility == 'public':
+ decl += u'public '
+ if node.packed:
+ decl += u'packed '
+ decl += node.kind
+ self.visit_container_node(node, decl, None, node.attributes)
+
+ def visit_CppClassNode(self, node):
+ extras = ""
+ if node.templates:
+ extras = u"[%s]" % ", ".join(node.templates)
+ if node.base_classes:
+ extras += "(%s)" % ", ".join(node.base_classes)
+ self.visit_container_node(node, u"cdef cppclass", extras, node.attributes)
+
+ def visit_CEnumDefNode(self, node):
+ self.visit_container_node(node, u"cdef enum", None, node.items)
+
+ def visit_CEnumDefItemNode(self, node):
+ self.startline(node.name)
+ if node.cname:
+ self.put(u' "%s"' % node.cname)
+ if node.value:
self.put(u" = ")
- self.visit(node.rhs)
+ self.visit(node.value)
+ self.endline()
+
+ def visit_CClassDefNode(self, node):
+ assert not node.module_name
+ if node.decorators:
+ for decorator in node.decorators:
+ self.visit(decorator)
+ self.startline(u"cdef class ")
+ self.put(node.class_name)
+ if node.base_class_name:
+ self.put(u"(")
+ if node.base_class_module:
+ self.put(node.base_class_module)
+ self.put(u".")
+ self.put(node.base_class_name)
+ self.put(u")")
+ self.endline(u":")
+ self.indent()
+ self.visit(node.body)
+ self.dedent()
+
+ def visit_CTypeDefNode(self, node):
+ self.startline(u"ctypedef ")
+ self.visit(node.base_type)
+ self.put(u" ")
+ self.visit(node.declarator)
+ self.endline()
+
+ def visit_FuncDefNode(self, node):
+ self.startline(u"def %s(" % node.name)
+ self.comma_separated_list(node.args)
+ self.endline(u"):")
+ self.indent()
+ self.visit(node.body)
+ self.dedent()
+
+ def visit_CArgDeclNode(self, node):
+ if node.base_type.name is not None:
+ self.visit(node.base_type)
+ self.put(u" ")
+ self.visit(node.declarator)
+ if node.default is not None:
+ self.put(u" = ")
+ self.visit(node.default)
+
+ def visit_CImportStatNode(self, node):
+ self.startline(u"cimport ")
+ self.put(node.module_name)
+ if node.as_name:
+ self.put(u" as ")
+ self.put(node.as_name)
+ self.endline()
+
+ def visit_FromCImportStatNode(self, node):
+ self.startline(u"from ")
+ self.put(node.module_name)
+ self.put(u" cimport ")
+ first = True
+ for pos, name, as_name, kind in node.imported_names:
+ assert kind is None
+ if first:
+ first = False
+ else:
+ self.put(u", ")
+ self.put(name)
+ if as_name:
+ self.put(u" as ")
+ self.put(as_name)
self.endline()
def visit_NameNode(self, node):
def visit_IntNode(self, node):
self.put(node.value)
+ def visit_NoneNode(self, node):
+ self.put(u"None")
+
+ def visit_NotNode(self, node):
+ self.put(u"(not ")
+ self.visit(node.operand)
+ self.put(u")")
+
+ def visit_DecoratorNode(self, node):
+ self.startline("@")
+ self.visit(node.decorator)
+ self.endline()
+
+ def visit_BinopNode(self, node):
+ self.visit(node.operand1)
+ self.put(u" %s " % node.operator)
+ self.visit(node.operand2)
+
+ def visit_AttributeNode(self, node):
+ self.visit(node.obj)
+ self.put(u".%s" % node.attribute)
+
+ def visit_BoolNode(self, node):
+ self.put(str(node.value))
+
# FIXME: represent string nodes correctly
def visit_StringNode(self, node):
value = node.value
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.
- self.startline(u"if ")
- self.visit(node.if_clauses[0].condition)
- self.endline(":")
- self.indent()
- self.visit(node.if_clauses[0].body)
- self.dedent()
- for clause in node.if_clauses[1:]:
- self.startline("elif ")
- self.visit(clause.condition)
- self.endline(":")
- self.indent()
- self.visit(clause.body)
- self.dedent()
- if node.else_clause is not None:
- self.line("else:")
- self.indent()
- self.visit(node.else_clause)
- self.dedent()
-
def visit_PassStatNode(self, node):
self.startline(u"pass")
self.endline()
+class CodeWriter(DeclarationWriter):
+
+ def visit_SingleAssignmentNode(self, node):
+ self.startline()
+ self.visit(node.lhs)
+ self.put(u" = ")
+ 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_PrintStatNode(self, node):
self.startline(u"print ")
self.comma_separated_list(node.arg_tuple.args)
self.put(u",")
self.endline()
- def visit_BinopNode(self, node):
- self.visit(node.operand1)
- self.put(u" %s " % node.operator)
- self.visit(node.operand2)
-
- def visit_CVarDefNode(self, node):
- self.startline(u"cdef ")
- self.visit(node.base_type)
- self.put(u" ")
- self.comma_separated_list(node.declarators, output_rhs=True)
- self.endline()
-
def visit_ForInStatNode(self, node):
self.startline(u"for ")
self.visit(node.target)
self.visit(node.else_clause)
self.dedent()
+ def visit_IfStatNode(self, node):
+ # The IfClauseNode is handled directly without a seperate match
+ # for clariy.
+ self.startline(u"if ")
+ self.visit(node.if_clauses[0].condition)
+ self.endline(":")
+ self.indent()
+ self.visit(node.if_clauses[0].body)
+ self.dedent()
+ for clause in node.if_clauses[1:]:
+ self.startline("elif ")
+ self.visit(clause.condition)
+ self.endline(":")
+ self.indent()
+ self.visit(clause.body)
+ self.dedent()
+ if node.else_clause is not None:
+ self.line("else:")
+ self.indent()
+ self.visit(node.else_clause)
+ self.dedent()
+
def visit_SequenceNode(self, node):
self.comma_separated_list(node.args) # Might need to discover whether we need () around tuples...hmm...
self.visit(node.body)
self.dedent()
- def visit_AttributeNode(self, node):
- self.visit(node.obj)
- self.put(u".%s" % node.attribute)
-
- def visit_BoolNode(self, node):
- self.put(str(node.value))
-
def visit_TryFinallyStatNode(self, node):
self.line(u"try:")
self.indent()
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")
- def visit_NoneNode(self, node):
- self.put(u"None")
-
def visit_ImportNode(self, node):
self.put(u"(import %s)" % node.module_name.value)
- def visit_NotNode(self, node):
- self.put(u"(not ")
- self.visit(node.operand)
- self.put(u")")
-
def visit_TempsBlockNode(self, node):
"""
Temporaries are output like $1_1', where the first number is
def visit_TempRefNode(self, node):
self.put(self.tempnames[node.handle])
+
+
+class PxdWriter(DeclarationWriter):
+ def __call__(self, node):
+ print u'\n'.join(self.write(node).lines)
+ return node
+
+ def visit_CFuncDefNode(self, node):
+ if 'inline' in node.modifiers:
+ return
+ if node.overridable:
+ self.startline(u'cpdef ')
+ else:
+ self.startline(u'cdef ')
+ if node.visibility != 'private':
+ self.put(node.visibility)
+ self.put(u' ')
+ if node.api:
+ self.put(u'api ')
+ self.visit(node.declarator)
+
+ def visit_StatNode(self, node):
+ pass
+
+
\ No newline at end of file