Commit 12eaff05 authored by scoder's avatar scoder Committed by GitHub

Merge pull request #1954 from nils-braun/pythran-multiple-line-support

Type inference for Pythran expressions
parents 33c4f688 b1d62ad5
......@@ -2284,7 +2284,11 @@ class NameNode(AtomicExprNode):
code.putln('%s = %s;' % (self.result(), result))
else:
result = rhs.result_as(self.ctype())
code.putln('%s = %s;' % (self.result(), result))
if is_pythran_expr(self.type):
code.putln('new (&%s) decltype(%s){%s};' % (self.result(), self.result(), result))
else:
code.putln('%s = %s;' % (self.result(), result))
if debug_disposal_code:
print("NameNode.generate_assignment_code:")
print("...generating post-assignment code for %s" % rhs)
......@@ -3450,6 +3454,10 @@ class IndexNode(_IndexingBaseNode):
if index_func is not None:
return index_func.type.return_type
if is_pythran_expr(base_type) and is_pythran_expr(index_type):
index_with_type = (self.index, index_type)
return PythranExpr(pythran_indexing_type(base_type, [index_with_type]))
# may be slicing or indexing, we don't know
if base_type in (unicode_type, str_type):
# these types always returns their own type on Python indexing/slicing
......@@ -4100,7 +4108,8 @@ class BufferIndexNode(_IndexingBaseNode):
def analyse_buffer_index(self, env, getting):
if is_pythran_expr(self.base.type):
self.type = PythranExpr(pythran_indexing_type(self.base.type, self.indices))
index_with_type_list = [(idx, idx.type) for idx in self.indices]
self.type = PythranExpr(pythran_indexing_type(self.base.type, index_with_type_list))
else:
self.base = self.base.coerce_to_simple(env)
self.type = self.base.type.dtype
......@@ -12241,7 +12250,13 @@ class PrimaryCmpNode(ExprNode, CmpNode):
is_memslice_nonecheck = False
def infer_type(self, env):
# TODO: Actually implement this (after merging with -unstable).
type1 = self.operand1.infer_type(env)
type2 = self.operand2.infer_type(env)
if is_pythran_expr(type1) or is_pythran_expr(type2):
if is_pythran_supported_type(type1) and is_pythran_supported_type(type2):
return PythranExpr(pythran_binop_type(self.operator, type1, type2))
return py_object_type
def type_dependencies(self, env):
......
......@@ -1506,6 +1506,15 @@ class PythranExpr(CType):
return True
def __eq__(self, other):
"""Equality operation for PythranExpr using the str representation"""
return str(self) == str(other)
def __hash__(self):
"""Hash function using the str representation"""
return hash(str(self))
class CConstType(BaseType):
is_const = 1
......
......@@ -66,7 +66,8 @@ def _index_access(index_code, indices):
return ('[%s]' if len(indices) == 1 else '(%s)') % indexing
def _index_type_code(idx):
def _index_type_code(index_with_type):
idx, index_type = index_with_type
if idx.is_slice:
if idx.step.is_none:
func = "contiguous_slice"
......@@ -76,11 +77,11 @@ def _index_type_code(idx):
n = 3
return "pythonic::types::%s(%s)" % (
func, ",".join(["0"]*n))
elif idx.type.is_int:
return "std::declval<%s>()" % idx.type.sign_and_name()
elif idx.type.is_pythran_expr:
return "std::declval<%s>()" % idx.type.pythran_type
raise ValueError("unsupported indexing type %s!" % idx.type)
elif index_type.is_int:
return "std::declval<%s>()" % index_type.sign_and_name()
elif index_type.is_pythran_expr:
return "std::declval<%s>()" % index_type.pythran_type
raise ValueError("unsupported indexing type %s!" % index_type)
def _index_code(idx):
......
......@@ -561,6 +561,8 @@ def safe_spanning_type(types, might_overflow, pos, scope):
# find_spanning_type() only returns 'bint' for clean boolean
# operations without other int types, so this is safe, too
return result_type
elif result_type.is_pythran_expr:
return result_type
elif result_type.is_ptr:
# Any pointer except (signed|unsigned|) char* can't implicitly
# become a PyObject, and inferring char* is now accepted, too.
......
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