Commit 879a240d authored by Robert Bradshaw's avatar Robert Bradshaw

Type inference: assignment marker visitor.

parent f1f99b51
......@@ -87,6 +87,7 @@ class Context(object):
from ParseTreeTransforms import AnalyseDeclarationsTransform, AnalyseExpressionsTransform
from ParseTreeTransforms import CreateClosureClasses, MarkClosureVisitor, DecoratorTransform
from ParseTreeTransforms import InterpretCompilerDirectives, TransformBuiltinMethods
from TypeInference import MarkAssignments
from ParseTreeTransforms import AlignFunctionDefinitions, GilCheck
from AnalysedTreeTransforms import AutoTestDictTransform
from AutoDocTransforms import EmbedSignature
......@@ -129,6 +130,7 @@ class Context(object):
AnalyseDeclarationsTransform(self),
AutoTestDictTransform(self),
EmbedSignature(self),
MarkAssignments(self),
TransformBuiltinMethods(self),
IntroduceBufferAuxiliaryVars(self),
_check_c_declarations,
......
......@@ -3197,6 +3197,10 @@ class InPlaceAssignmentNode(AssignmentNode):
self.lhs.annotate(code)
self.rhs.annotate(code)
self.dup.annotate(code)
def create_binop_node(self):
import ExprNodes
return ExprNodes.binop_node(self.pos, self.op, self.lhs, self.rhs)
class PrintStatNode(StatNode):
......
......@@ -68,6 +68,7 @@ option_defaults = {
'c99_complex' : False, # Don't use macro wrappers for complex arith, not sure what to name this...
'callspec' : "",
'profile': False,
'infer_types': True,
'autotestdict': True,
# test support
......
......@@ -114,9 +114,10 @@ class Entry(object):
# api boolean Generate C API for C class or function
# utility_code string Utility code needed when this entry is used
#
# buffer_aux BufferAux or None Extra information needed for buffer variables
# buffer_aux BufferAux or None Extra information needed for buffer variables
# inline_func_in_pxd boolean Hacky special case for inline function in pxd file.
# Ideally this should not be necesarry.
# assignments [ExprNode] List of expressions that get assigned to this entry.
inline_func_in_pxd = False
borrowed = 0
......@@ -171,6 +172,7 @@ class Entry(object):
self.type = type
self.pos = pos
self.init = init
self.assignments = []
def redeclared(self, pos):
error(pos, "'%s' does not match previous declaration" % self.name)
......
import ExprNodes
import PyrexTypes
from Visitor import CythonTransform
class TypedExprNode(ExprNodes.ExprNode):
# Used for declaring assignments of a specified type whithout a known entry.
def __init__(self, type):
self.type = type
object_expr = TypedExprNode(PyrexTypes.py_object_type)
class MarkAssignments(CythonTransform):
def mark_assignment(self, lhs, rhs):
print lhs.pos[1:]
if isinstance(lhs, ExprNodes.NameNode):
lhs.entry.assignments.append(rhs)
print lhs.name, rhs
elif isinstance(lhs, ExprNodes.SequenceNode):
for arg in lhs.args:
self.mark_assignment(arg, object_expr)
else:
# Could use this info to infer cdef class attributes...
pass
def visit_SingleAssignmentNode(self, node):
self.mark_assignment(node.lhs, node.rhs)
self.visitchildren(node)
return node
def visit_CascadedAssignmentNode(self, node):
for lhs in node.lhs_list:
self.mark_assignment(lhs, node.rhs)
self.visitchildren(node)
return node
def visit_InPlaceAssignmentNode(self, node):
self.mark_assignment(node.lhs, node.create_binop_node())
self.visitchildren(node)
return node
def visit_ForInStatNode(self, node):
# TODO: Figure out how this interacts with the range optimization...
self.mark_assignment(node.target, object_expr)
self.visitchildren(node)
return node
def visit_ForFromStatNode(self, node):
self.mark_assignment(node.target, node.bound1)
if node.step is not None:
self.mark_assignment(node.target, ExprNodes.binop_node(self.pos, '+', node.bound1, node.step))
self.visitchildren(node)
return node
def visit_ExceptClauseNode(self, node):
if node.target is not None:
self.mark_assignment(node.target, object_expr)
self.visitchildren(node)
return node
def visit_FromCImportStatNode(self, node):
raise NotImplementedError # Can't occur in local scopes anyways...
def visit_FromImportStatNode(self, node):
for name, target in node.items:
if name != "*":
self.mark_assignment(target, object_expr)
self.visitchildren(node)
return node
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