Commit e157b663 authored by Stefan Behnel's avatar Stefan Behnel

optimise 'int_val in string_literal' into a switch statement when x is an...

optimise 'int_val in string_literal' into a switch statement when x is an arbitrary expression, not only a name
parent 3ed85507
...@@ -702,28 +702,25 @@ class SwitchTransform(Visitor.VisitorTransform): ...@@ -702,28 +702,25 @@ class SwitchTransform(Visitor.VisitorTransform):
break break
if isinstance(cond, ExprNodes.PrimaryCmpNode): if isinstance(cond, ExprNodes.PrimaryCmpNode):
if cond.cascade is None and not cond.is_python_comparison(): if cond.cascade is not None:
return self.NO_MATCH
elif cond.is_c_string_contains() and \
isinstance(cond.operand2, (ExprNodes.UnicodeNode, ExprNodes.BytesNode)):
not_in = cond.operator == 'not_in'
if not_in and not allow_not_in:
return self.NO_MATCH
if isinstance(cond.operand2, ExprNodes.UnicodeNode) and \
cond.operand2.contains_surrogates():
# dealing with surrogates leads to different
# behaviour on wide and narrow Unicode
# platforms => refuse to optimise this case
return self.NO_MATCH
return not_in, cond.operand1, self.extract_in_string_conditions(cond.operand2)
elif not cond.is_python_comparison():
if cond.operator == '==': if cond.operator == '==':
not_in = False not_in = False
elif allow_not_in and cond.operator == '!=': elif allow_not_in and cond.operator == '!=':
not_in = True not_in = True
elif cond.is_c_string_contains() and \
isinstance(cond.operand2, (ExprNodes.UnicodeNode, ExprNodes.BytesNode)):
not_in = cond.operator == 'not_in'
if not_in and not allow_not_in:
return self.NO_MATCH
if isinstance(cond.operand2, ExprNodes.UnicodeNode) and \
cond.operand2.contains_surrogates():
# dealing with surrogates leads to different
# behaviour on wide and narrow Unicode
# platforms => refuse to optimise this case
return self.NO_MATCH
# this looks somewhat silly, but it does the right
# checks for NameNode and AttributeNode
if is_common_value(cond.operand1, cond.operand1):
return not_in, cond.operand1, self.extract_in_string_conditions(cond.operand2)
else:
return self.NO_MATCH
else: else:
return self.NO_MATCH return self.NO_MATCH
# this looks somewhat silly, but it does the right # this looks somewhat silly, but it does the right
......
...@@ -162,3 +162,36 @@ def count_lower_case_characters(unicode ustring): ...@@ -162,3 +162,36 @@ def count_lower_case_characters(unicode ustring):
if uchar.islower(): if uchar.islower():
count += 1 count += 1
return count return count
@cython.test_assert_path_exists('//SwitchStatNode',
'//ForFromStatNode')
@cython.test_fail_if_path_exists('//ForInStatNode')
def iter_and_in():
"""
>>> iter_and_in()
a
b
e
f
h
"""
for c in u'abcdefgh':
if c in u'abCDefGh':
print c
@cython.test_assert_path_exists('//SwitchStatNode',
'//ForFromStatNode')
@cython.test_fail_if_path_exists('//ForInStatNode')
def index_and_in():
"""
>>> index_and_in()
1
3
4
7
8
"""
cdef int i
for i in range(1,9):
if u'abcdefgh'[-i] in u'abCDefGh':
print i
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