Commit cf6abbcf authored by Robert Bradshaw's avatar Robert Bradshaw

Start using unspecified types.

parent 879a240d
......@@ -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)
......
......@@ -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):
......
......@@ -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
......
......@@ -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)
......
......@@ -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:
......
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