Commit 6cca314b authored by Robert Bradshaw's avatar Robert Bradshaw

More complete code writing.

parent 830b20b9
...@@ -26,12 +26,12 @@ class LinesResult(object): ...@@ -26,12 +26,12 @@ class LinesResult(object):
self.put(s) self.put(s)
self.newline() self.newline()
class CodeWriter(TreeVisitor): class DeclarationWriter(TreeVisitor):
indent_string = u" " indent_string = u" "
def __init__(self, result = None): def __init__(self, result = None):
super(CodeWriter, self).__init__() super(DeclarationWriter, self).__init__()
if result is None: if result is None:
result = LinesResult() result = LinesResult()
self.result = result self.result = result
...@@ -41,6 +41,7 @@ class CodeWriter(TreeVisitor): ...@@ -41,6 +41,7 @@ class CodeWriter(TreeVisitor):
def write(self, tree): def write(self, tree):
self.visit(tree) self.visit(tree)
return self.result
def indent(self): def indent(self):
self.numindents += 1 self.numindents += 1
...@@ -54,6 +55,9 @@ class CodeWriter(TreeVisitor): ...@@ -54,6 +55,9 @@ class CodeWriter(TreeVisitor):
def put(self, s): def put(self, s):
self.result.put(s) self.result.put(s)
def putline(self, s):
self.result.putline(self.indent_string * self.numindents + s)
def endline(self, s = u""): def endline(self, s = u""):
self.result.putline(s) self.result.putline(s)
...@@ -79,23 +83,45 @@ class CodeWriter(TreeVisitor): ...@@ -79,23 +83,45 @@ class CodeWriter(TreeVisitor):
def visit_StatListNode(self, node): def visit_StatListNode(self, node):
self.visitchildren(node) self.visitchildren(node)
def visit_FuncDefNode(self, node): def visit_CDefExternNode(self, node):
self.startline(u"def %s(" % node.name) if node.include_file is None:
self.comma_separated_list(node.args) file = u'*'
self.endline(u"):") else:
file = u'"%s"' % node.include_file
self.putline(u"cdef extern from %s:" % file)
self.indent() self.indent()
self.visit(node.body) self.visit(node.body)
self.dedent() self.dedent()
def visit_CArgDeclNode(self, node): def visit_CPtrDeclaratorNode(self, node):
if node.base_type.name is not None: self.put('*')
self.visit(node.base_type) self.visit(node.base)
self.put(u" ")
self.visit(node.declarator) def visit_CReferenceDeclaratorNode(self, node):
if node.default is not None: self.put('&')
self.put(u" = ") self.visit(node.base)
self.visit(node.default)
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): def visit_CNameDeclaratorNode(self, node):
self.put(node.name) self.put(node.name)
...@@ -108,22 +134,149 @@ class CodeWriter(TreeVisitor): ...@@ -108,22 +134,149 @@ class CodeWriter(TreeVisitor):
self.put("short " * -node.longness) self.put("short " * -node.longness)
elif node.longness > 0: elif node.longness > 0:
self.put("long " * node.longness) 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) self.put(node.name)
def visit_SingleAssignmentNode(self, node): def visit_TemplatedTypeNode(self, node):
self.startline() self.visit(node.base_type_node)
self.visit(node.lhs) self.put(u'[')
self.put(u" = ") self.comma_separated_list(node.positional_args + node.keyword_args.key_value_pairs)
self.visit(node.rhs) 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() self.endline()
def visit_CascadedAssignmentNode(self, node): def visit_container_node(self, node, decl, extras, attributes):
self.startline() # TODO: visibility
for lhs in node.lhs_list: self.startline(decl)
self.visit(lhs) 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.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() self.endline()
def visit_NameNode(self, node): def visit_NameNode(self, node):
...@@ -132,6 +285,31 @@ class CodeWriter(TreeVisitor): ...@@ -132,6 +285,31 @@ class CodeWriter(TreeVisitor):
def visit_IntNode(self, node): def visit_IntNode(self, node):
self.put(node.value) 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 # FIXME: represent string nodes correctly
def visit_StringNode(self, node): def visit_StringNode(self, node):
value = node.value value = node.value
...@@ -139,32 +317,27 @@ class CodeWriter(TreeVisitor): ...@@ -139,32 +317,27 @@ class CodeWriter(TreeVisitor):
value = value.encode(value.encoding) value = value.encode(value.encoding)
self.put(repr(value)) 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): def visit_PassStatNode(self, node):
self.startline(u"pass") self.startline(u"pass")
self.endline() 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): def visit_PrintStatNode(self, node):
self.startline(u"print ") self.startline(u"print ")
self.comma_separated_list(node.arg_tuple.args) self.comma_separated_list(node.arg_tuple.args)
...@@ -172,18 +345,6 @@ class CodeWriter(TreeVisitor): ...@@ -172,18 +345,6 @@ class CodeWriter(TreeVisitor):
self.put(u",") self.put(u",")
self.endline() 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): def visit_ForInStatNode(self, node):
self.startline(u"for ") self.startline(u"for ")
self.visit(node.target) self.visit(node.target)
...@@ -199,6 +360,28 @@ class CodeWriter(TreeVisitor): ...@@ -199,6 +360,28 @@ class CodeWriter(TreeVisitor):
self.visit(node.else_clause) self.visit(node.else_clause)
self.dedent() 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): def visit_SequenceNode(self, node):
self.comma_separated_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...
...@@ -244,13 +427,6 @@ class CodeWriter(TreeVisitor): ...@@ -244,13 +427,6 @@ class CodeWriter(TreeVisitor):
self.visit(node.body) self.visit(node.body)
self.dedent() 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): def visit_TryFinallyStatNode(self, node):
self.line(u"try:") self.line(u"try:")
self.indent() self.indent()
...@@ -289,25 +465,12 @@ class CodeWriter(TreeVisitor): ...@@ -289,25 +465,12 @@ class CodeWriter(TreeVisitor):
self.visit(node.value) self.visit(node.value)
self.endline() self.endline()
def visit_DecoratorNode(self, node):
self.startline("@")
self.visit(node.decorator)
self.endline()
def visit_ReraiseStatNode(self, node): def visit_ReraiseStatNode(self, node):
self.line("raise") self.line("raise")
def visit_NoneNode(self, node):
self.put(u"None")
def visit_ImportNode(self, node): def visit_ImportNode(self, node):
self.put(u"(import %s)" % node.module_name.value) 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): def visit_TempsBlockNode(self, node):
""" """
Temporaries are output like $1_1', where the first number is Temporaries are output like $1_1', where the first number is
...@@ -323,3 +486,28 @@ class CodeWriter(TreeVisitor): ...@@ -323,3 +486,28 @@ class CodeWriter(TreeVisitor):
def visit_TempRefNode(self, node): def visit_TempRefNode(self, node):
self.put(self.tempnames[node.handle]) 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
...@@ -64,7 +64,6 @@ class SkipDeclarations(object): ...@@ -64,7 +64,6 @@ class SkipDeclarations(object):
def visit_CStructOrUnionDefNode(self, node): def visit_CStructOrUnionDefNode(self, node):
return node return node
class NormalizeTree(CythonTransform): class NormalizeTree(CythonTransform):
""" """
This transform fixes up a few things after parsing This transform fixes up a few things after parsing
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment