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

Type inference testing.

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