Commit ee6bbddb authored by Stefan Behnel's avatar Stefan Behnel

generate expected code when for-looping over type-declared list or tuple

parent 6d083814
...@@ -1340,6 +1340,12 @@ class IteratorNode(ExprNode): ...@@ -1340,6 +1340,12 @@ class IteratorNode(ExprNode):
self.counter.release_temp(env) self.counter.release_temp(env)
def generate_result_code(self, code): def generate_result_code(self, code):
is_builtin_sequence = self.sequence.type is list_type or \
self.sequence.type is tuple_type
if is_builtin_sequence:
code.putln(
"if (likely(%s != Py_None)) {" % self.sequence.py_result())
else:
code.putln( code.putln(
"if (PyList_CheckExact(%s) || PyTuple_CheckExact(%s)) {" % ( "if (PyList_CheckExact(%s) || PyTuple_CheckExact(%s)) {" % (
self.sequence.py_result(), self.sequence.py_result(),
...@@ -1351,6 +1357,11 @@ class IteratorNode(ExprNode): ...@@ -1351,6 +1357,11 @@ class IteratorNode(ExprNode):
self.sequence.py_result(), self.sequence.py_result(),
self.result())) self.result()))
code.putln("} else {") code.putln("} else {")
if is_builtin_sequence:
code.putln(
'PyErr_SetString(PyExc_TypeError, "\'NoneType\' object is not iterable"); %s' %
code.error_goto(self.pos))
else:
code.putln("%s = -1; %s = PyObject_GetIter(%s); %s" % ( code.putln("%s = -1; %s = PyObject_GetIter(%s); %s" % (
self.counter.result(), self.counter.result(),
self.result(), self.result(),
...@@ -1374,23 +1385,35 @@ class NextNode(AtomicExprNode): ...@@ -1374,23 +1385,35 @@ class NextNode(AtomicExprNode):
self.is_temp = 1 self.is_temp = 1
def generate_result_code(self, code): def generate_result_code(self, code):
for py_type in ["List", "Tuple"]: if self.iterator.sequence.type is list_type:
type_checks = [(list_type, "List")]
elif self.iterator.sequence.type is tuple_type:
type_checks = [(tuple_type, "Tuple")]
else:
type_checks = [(list_type, "List"), (tuple_type, "Tuple")]
for py_type, prefix in type_checks:
if len(type_checks) > 1:
code.putln( code.putln(
"if (likely(Py%s_CheckExact(%s))) {" % (py_type, self.iterator.py_result())) "if (likely(Py%s_CheckExact(%s))) {" % (
prefix, self.iterator.py_result()))
code.putln( code.putln(
"if (%s >= Py%s_GET_SIZE(%s)) break;" % ( "if (%s >= Py%s_GET_SIZE(%s)) break;" % (
self.iterator.counter.result(), self.iterator.counter.result(),
py_type, prefix,
self.iterator.py_result())) self.iterator.py_result()))
code.putln( code.putln(
"%s = Py%s_GET_ITEM(%s, %s); Py_INCREF(%s); %s++;" % ( "%s = Py%s_GET_ITEM(%s, %s); Py_INCREF(%s); %s++;" % (
self.result(), self.result(),
py_type, prefix,
self.iterator.py_result(), self.iterator.py_result(),
self.iterator.counter.result(), self.iterator.counter.result(),
self.result(), self.result(),
self.iterator.counter.result())) self.iterator.counter.result()))
if len(type_checks) > 1:
code.put("} else ") code.put("} else ")
if len(type_checks) == 1:
return
code.putln("{") code.putln("{")
code.putln( code.putln(
"%s = PyIter_Next(%s);" % ( "%s = PyIter_Next(%s);" % (
......
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