Commit cf6abbcf authored by Robert Bradshaw's avatar Robert Bradshaw

Start using unspecified types.

parent 879a240d
...@@ -12,7 +12,7 @@ import Naming ...@@ -12,7 +12,7 @@ import Naming
import Nodes import Nodes
from Nodes import Node from Nodes import Node
import PyrexTypes 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 from Builtin import list_type, tuple_type, set_type, dict_type, unicode_type, bytes_type
import Builtin import Builtin
import Symtab import Symtab
...@@ -1023,7 +1023,11 @@ class NameNode(AtomicExprNode): ...@@ -1023,7 +1023,11 @@ class NameNode(AtomicExprNode):
if not self.entry: if not self.entry:
self.entry = env.lookup_here(self.name) self.entry = env.lookup_here(self.name)
if not self.entry: 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, 'initalized'), True)
env.control_flow.set_state(self.pos, (self.name, 'source'), 'assignment') env.control_flow.set_state(self.pos, (self.name, 'source'), 'assignment')
if self.entry.is_declared_generic: if self.entry.is_declared_generic:
...@@ -3382,6 +3386,9 @@ class ComprehensionNode(ExprNode): ...@@ -3382,6 +3386,9 @@ class ComprehensionNode(ExprNode):
self.target.analyse_expressions(env) self.target.analyse_expressions(env)
self.type = self.target.type self.type = self.target.type
self.append.target = self # this is a CloneNode used in the PyList_Append in the inner loop 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_declarations(env)
self.loop.analyse_expressions(env) self.loop.analyse_expressions(env)
......
...@@ -3200,7 +3200,7 @@ class InPlaceAssignmentNode(AssignmentNode): ...@@ -3200,7 +3200,7 @@ class InPlaceAssignmentNode(AssignmentNode):
def create_binop_node(self): def create_binop_node(self):
import ExprNodes 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): class PrintStatNode(StatNode):
......
...@@ -785,11 +785,13 @@ property NAME: ...@@ -785,11 +785,13 @@ property NAME:
class AnalyseExpressionsTransform(CythonTransform): class AnalyseExpressionsTransform(CythonTransform):
def visit_ModuleNode(self, node): def visit_ModuleNode(self, node):
node.scope.infer_types()
node.body.analyse_expressions(node.scope) node.body.analyse_expressions(node.scope)
self.visitchildren(node) self.visitchildren(node)
return node return node
def visit_FuncDefNode(self, node): def visit_FuncDefNode(self, node):
node.local_scope.infer_types()
node.body.analyse_expressions(node.local_scope) node.body.analyse_expressions(node.local_scope)
self.visitchildren(node) self.visitchildren(node)
return node return node
......
...@@ -8,7 +8,7 @@ from Errors import warning, error, InternalError ...@@ -8,7 +8,7 @@ from Errors import warning, error, InternalError
from StringEncoding import EncodedString from StringEncoding import EncodedString
import Options, Naming import Options, Naming
import PyrexTypes import PyrexTypes
from PyrexTypes import py_object_type from PyrexTypes import py_object_type, unspecified_type
import TypeSlots import TypeSlots
from TypeSlots import \ from TypeSlots import \
pyfunction_signature, pymethod_signature, \ pyfunction_signature, pymethod_signature, \
...@@ -544,6 +544,12 @@ class Scope(object): ...@@ -544,6 +544,12 @@ class Scope(object):
if name in self.entries: if name in self.entries:
return 1 return 1
return 0 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): class PreImportScope(Scope):
...@@ -816,6 +822,8 @@ class ModuleScope(Scope): ...@@ -816,6 +822,8 @@ class ModuleScope(Scope):
if not visibility in ('private', 'public', 'extern'): if not visibility in ('private', 'public', 'extern'):
error(pos, "Module-level variable cannot be declared %s" % visibility) error(pos, "Module-level variable cannot be declared %s" % visibility)
if not is_cdef: if not is_cdef:
if type is unspecified_type:
type = py_object_type
if not (type.is_pyobject and not type.is_extension_type): if not (type.is_pyobject and not type.is_extension_type):
raise InternalError( raise InternalError(
"Non-cdef global variable is not a generic Python object") "Non-cdef global variable is not a generic Python object")
...@@ -1191,6 +1199,8 @@ class PyClassScope(ClassScope): ...@@ -1191,6 +1199,8 @@ class PyClassScope(ClassScope):
def declare_var(self, name, type, pos, def declare_var(self, name, type, pos,
cname = None, visibility = 'private', is_cdef = 0): cname = None, visibility = 'private', is_cdef = 0):
if type is unspecified_type:
type = py_object_type
# Add an entry for a class attribute. # Add an entry for a class attribute.
entry = Scope.declare_var(self, name, type, pos, entry = Scope.declare_var(self, name, type, pos,
cname, visibility, is_cdef) cname, visibility, is_cdef)
...@@ -1277,6 +1287,8 @@ class CClassScope(ClassScope): ...@@ -1277,6 +1287,8 @@ class CClassScope(ClassScope):
"Non-generic Python attribute cannot be exposed for writing from Python") "Non-generic Python attribute cannot be exposed for writing from Python")
return entry return entry
else: else:
if type is unspecified_type:
type = py_object_type
# Add an entry for a class attribute. # Add an entry for a class attribute.
entry = Scope.declare_var(self, name, type, pos, entry = Scope.declare_var(self, name, type, pos,
cname, visibility, is_cdef) cname, visibility, is_cdef)
......
...@@ -12,10 +12,12 @@ object_expr = TypedExprNode(PyrexTypes.py_object_type) ...@@ -12,10 +12,12 @@ object_expr = TypedExprNode(PyrexTypes.py_object_type)
class MarkAssignments(CythonTransform): class MarkAssignments(CythonTransform):
def mark_assignment(self, lhs, rhs): def mark_assignment(self, lhs, rhs):
print lhs.pos[1:]
if isinstance(lhs, ExprNodes.NameNode): 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) lhs.entry.assignments.append(rhs)
print lhs.name, rhs
elif isinstance(lhs, ExprNodes.SequenceNode): elif isinstance(lhs, ExprNodes.SequenceNode):
for arg in lhs.args: for arg in lhs.args:
self.mark_assignment(arg, object_expr) self.mark_assignment(arg, object_expr)
...@@ -48,7 +50,7 @@ class MarkAssignments(CythonTransform): ...@@ -48,7 +50,7 @@ class MarkAssignments(CythonTransform):
def visit_ForFromStatNode(self, node): def visit_ForFromStatNode(self, node):
self.mark_assignment(node.target, node.bound1) self.mark_assignment(node.target, node.bound1)
if node.step is not None: 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) self.visitchildren(node)
return node return node
...@@ -59,7 +61,7 @@ class MarkAssignments(CythonTransform): ...@@ -59,7 +61,7 @@ class MarkAssignments(CythonTransform):
return node return node
def visit_FromCImportStatNode(self, 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): def visit_FromImportStatNode(self, node):
for name, target in node.items: for name, target in node.items:
......
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