From: Robert Bradshaw Date: Sun, 4 Oct 2009 05:37:01 +0000 (-0700) Subject: Start using unspecified types. X-Git-Tag: 0.12.alpha0~177^2~11 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=cf6abbcffa9e7aa1e99801e27ad3117cc0f12ffe;p=cython.git Start using unspecified types. --- diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index 0e5ec88a..31f76d48 100644 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -12,7 +12,7 @@ import Naming import Nodes from Nodes import Node import PyrexTypes -from PyrexTypes import py_object_type, c_long_type, typecast, error_type +from PyrexTypes import py_object_type, c_long_type, typecast, error_type, unspecified_type from Builtin import list_type, tuple_type, set_type, dict_type, unicode_type, bytes_type import Builtin import Symtab @@ -1023,7 +1023,11 @@ class NameNode(AtomicExprNode): if not self.entry: self.entry = env.lookup_here(self.name) if not self.entry: - self.entry = env.declare_var(self.name, py_object_type, self.pos) + if env.directives['infer_types']: + type = unspecified_type + else: + type = py_object_type + self.entry = env.declare_var(self.name, type, self.pos) env.control_flow.set_state(self.pos, (self.name, 'initalized'), True) env.control_flow.set_state(self.pos, (self.name, 'source'), 'assignment') if self.entry.is_declared_generic: @@ -3382,6 +3386,9 @@ class ComprehensionNode(ExprNode): self.target.analyse_expressions(env) self.type = self.target.type self.append.target = self # this is a CloneNode used in the PyList_Append in the inner loop + # We are analysing declarations to late. + self.loop.target.analyse_target_declaration(env) + env.infer_types() self.loop.analyse_declarations(env) self.loop.analyse_expressions(env) diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index 882ca421..82e211a4 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -3200,7 +3200,7 @@ class InPlaceAssignmentNode(AssignmentNode): def create_binop_node(self): import ExprNodes - return ExprNodes.binop_node(self.pos, self.op, self.lhs, self.rhs) + return ExprNodes.binop_node(self.pos, self.operator, self.lhs, self.rhs) class PrintStatNode(StatNode): diff --git a/Cython/Compiler/ParseTreeTransforms.py b/Cython/Compiler/ParseTreeTransforms.py index a2b20d53..2836a36e 100644 --- a/Cython/Compiler/ParseTreeTransforms.py +++ b/Cython/Compiler/ParseTreeTransforms.py @@ -785,11 +785,13 @@ property NAME: class AnalyseExpressionsTransform(CythonTransform): def visit_ModuleNode(self, node): + node.scope.infer_types() node.body.analyse_expressions(node.scope) self.visitchildren(node) return node def visit_FuncDefNode(self, node): + node.local_scope.infer_types() node.body.analyse_expressions(node.local_scope) self.visitchildren(node) return node diff --git a/Cython/Compiler/Symtab.py b/Cython/Compiler/Symtab.py index ba0299f8..d19adf85 100644 --- a/Cython/Compiler/Symtab.py +++ b/Cython/Compiler/Symtab.py @@ -8,7 +8,7 @@ from Errors import warning, error, InternalError from StringEncoding import EncodedString import Options, Naming import PyrexTypes -from PyrexTypes import py_object_type +from PyrexTypes import py_object_type, unspecified_type import TypeSlots from TypeSlots import \ pyfunction_signature, pymethod_signature, \ @@ -544,6 +544,12 @@ class Scope(object): if name in self.entries: return 1 return 0 + + def infer_types(self): + for name, entry in self.entries.items(): + if entry.type is unspecified_type: + entry.type = py_object_type + entry.init_to_none = Options.init_local_none # TODO: is there a better place for this? class PreImportScope(Scope): @@ -816,6 +822,8 @@ class ModuleScope(Scope): if not visibility in ('private', 'public', 'extern'): error(pos, "Module-level variable cannot be declared %s" % visibility) if not is_cdef: + if type is unspecified_type: + type = py_object_type if not (type.is_pyobject and not type.is_extension_type): raise InternalError( "Non-cdef global variable is not a generic Python object") @@ -1191,6 +1199,8 @@ class PyClassScope(ClassScope): def declare_var(self, name, type, pos, cname = None, visibility = 'private', is_cdef = 0): + if type is unspecified_type: + type = py_object_type # Add an entry for a class attribute. entry = Scope.declare_var(self, name, type, pos, cname, visibility, is_cdef) @@ -1277,6 +1287,8 @@ class CClassScope(ClassScope): "Non-generic Python attribute cannot be exposed for writing from Python") return entry else: + if type is unspecified_type: + type = py_object_type # Add an entry for a class attribute. entry = Scope.declare_var(self, name, type, pos, cname, visibility, is_cdef) diff --git a/Cython/Compiler/TypeInference.py b/Cython/Compiler/TypeInference.py index 9b020259..a9d7af7d 100644 --- a/Cython/Compiler/TypeInference.py +++ b/Cython/Compiler/TypeInference.py @@ -12,10 +12,12 @@ 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): + if lhs.entry is None: + # TODO: This shouldn't happen... + # It looks like comprehension loop targets are not declared soon enough. + return 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) @@ -48,7 +50,7 @@ class MarkAssignments(CythonTransform): 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.mark_assignment(node.target, ExprNodes.binop_node(node.pos, '+', node.bound1, node.step)) self.visitchildren(node) return node @@ -59,7 +61,7 @@ class MarkAssignments(CythonTransform): return node def visit_FromCImportStatNode(self, node): - raise NotImplementedError # Can't occur in local scopes anyways... + pass # Can't be assigned to... def visit_FromImportStatNode(self, node): for name, target in node.items: