Commit 51db01c9 authored by Robert Bradshaw's avatar Robert Bradshaw

Type inference testing.

parent 8da8ec52
......@@ -4245,24 +4245,29 @@ class SizeofVarNode(SizeofNode):
def generate_result_code(self, code):
pass
class TypeofNode(StringNode):
class TypeofNode(ExprNode):
# Compile-time type of an expression, as a string.
#
# operand ExprNode
# literal StringNode # internal
subexprs = ['operand']
literal = None
type = py_object_type
subexprs = ['operand', 'literal']
def analyse_types(self, env):
self.operand.analyse_types(env)
from StringEncoding import EncodedString
self.value = EncodedString(str(self.operand.type))
StringNode.analyse_types(self, env)
def analyse_as_type(self, env):
return None
self.literal = StringNode(self.pos, value=EncodedString(str(self.operand.type)))
self.literal.analyse_types(env)
self.literal = self.literal.coerce_to_pyobject(env)
def generate_evaluation_code(self, code):
self.generate_result_code(code)
self.literal.generate_evaluation_code(code)
def calculate_result_code(self):
return self.literal.calculate_result_code()
#-------------------------------------------------------------------
#
......
......@@ -4,6 +4,12 @@
import sys, os, time, copy
try:
set
except NameError:
# Python 2.3
from sets import Set as set
import Code
import Builtin
from Errors import error, warning, InternalError
......
......@@ -1801,10 +1801,14 @@ def widest_numeric_type(type1, type2):
def spanning_type(type1, type2):
# Return a type assignable from both type1 and type2.
if type1 == type2:
if type1 is py_object_type or type2 is py_object_type:
return py_object_type
elif type1 == type2:
return type1
elif type1.is_numeric and type2.is_numeric:
return widest_numeric_type(type1, type2)
elif type1.is_pyobject ^ type2.is_pyobject:
return py_object_type
elif type1.assignable_from(type2):
return type1
elif type2.assignable_from(type1):
......@@ -1812,7 +1816,6 @@ def spanning_type(type1, type2):
else:
return py_object_type
def simple_c_type(signed, longness, name):
# Find type descriptor for simple type given name and modifiers.
# Returns None if arguments don't make sense.
......
......@@ -50,12 +50,14 @@ class MarkAssignments(CythonTransform):
def visit_ForInStatNode(self, node):
# TODO: Remove redundancy with range optimization...
is_range = False
sequence = node.iterator.sequence
if isinstance(sequence, ExprNodes.SimpleCallNode):
function = sequence.function
if sequence.self is None and \
isinstance(function, ExprNodes.NameNode) and \
function.name in ('range', 'xrange'):
is_range = True
self.mark_assignment(node.target, sequence.args[0])
if len(sequence.args) > 1:
self.mark_assignment(node.target, sequence.args[1])
......@@ -65,7 +67,7 @@ class MarkAssignments(CythonTransform):
'+',
sequence.args[0],
sequence.args[2]))
else:
if not is_range:
self.mark_assignment(node.target, object_expr)
self.visitchildren(node)
return node
......@@ -143,7 +145,7 @@ class SimpleAssignmentTypeInferer:
del dependancies_by_entry[entry]
ready_to_infer.append(entry)
# Try to infer things in order...
while ready_to_infer:
while True:
while ready_to_infer:
entry = ready_to_infer.pop()
types = [expr.infer_type(scope) for expr in entry.assignments]
......@@ -165,6 +167,8 @@ class SimpleAssignmentTypeInferer:
del dependancies_by_entry[entry]
if ready_to_infer:
break
if not ready_to_infer:
break
# We can't figure out the rest with this algorithm, let them be objects.
for entry in dependancies_by_entry:
......
#include "Python.h"
#include "embedded.h"
int main(int argc, char *argv) {
Py_Initialize();
initembedded();
spam();
Py_Finalize();
}
......@@ -2,6 +2,7 @@ cdef void foo():
cdef int i1, i2=0
cdef char c1=0, c2
cdef char *p1, *p2=NULL
cdef object obj1
i1 = i2
i1 = c1
p1 = p2
......
......@@ -5,6 +5,7 @@ __doc__ = u"""
def f():
cdef int bool, int1, int2
cdef object obj1, obj2
int1 = 0
int2 = 0
obj1 = 1
......
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