1# coding=utf8
2# mode: run
3# tag: constant_folding
4
5import cython
6
7
8import sys
9IS_PY2 = sys.version_info < (3, 0)
10
11
12def print_big_ints(t):
13    s = repr(t)
14    if IS_PY2:
15        s = s.replace('L', '')
16    print(s)
17
18
19@cython.test_fail_if_path_exists(
20    "//UnaryMinusNode",
21    "//UnaryPlusNode",
22)
23def unop_floats():
24    """
25    >>> unop_floats()
26    (False, 2.0, -2.0, False, 2.0, -2.0, -2.0)
27    """
28    not1   = not 2.0
29    plus1  = + 2.0
30    minus1 = - 2.0
31    not3   = not not not 2.0
32    plus3  = +++ 2.0
33    minus3 = --- 2.0
34    mix    = +-++-- 2.0
35    return not1, plus1, minus1, not3, plus3, minus3, mix
36
37
38@cython.test_fail_if_path_exists(
39    "//UnaryMinusNode",
40    "//UnaryPlusNode",
41    "//CoerceToPyTypeNode",
42)
43def unop_py_floats_tuple():
44    """
45    >>> unop_floats()
46    (False, 2.0, -2.0, False, 2.0, -2.0, -2.0)
47    """
48    return (
49        not 2.0,
50        + 2.0,
51        - 2.0,
52        not not not 2.0,
53        +++ 2.0,
54        --- 2.0,
55        +-++-- 2.0)
56
57
58@cython.test_fail_if_path_exists(
59    "//UnaryMinusNode",
60    "//UnaryPlusNode",
61)
62def unop_ints():
63    """
64    >>> unop_ints()
65    (False, 2, -2, False, 2, -2, -2)
66    """
67    not1   = not 2
68    plus1  = + 2
69    minus1 = - 2
70    not3   = not not not 2
71    plus3  = +++ 2
72    minus3 = --- 2
73    mix    = +-++-- 2
74    return not1, plus1, minus1, not3, plus3, minus3, mix
75
76
77@cython.test_fail_if_path_exists(
78    "//UnaryMinusNode",
79    "//UnaryPlusNode",
80    "//NotNode",
81)
82def unop_bool():
83    """
84    >>> unop_bool()
85    (False, 1, -1, False, 1, -1, -1)
86    """
87    not1   = not True
88    plus1  = + True
89    minus1 = - True
90    not3   = not not not True
91    plus3  = +++ True
92    minus3 = --- True
93    mix    = +-++-- True
94    return not1, plus1, minus1, not3, plus3, minus3, mix
95
96
97@cython.test_fail_if_path_exists(
98    "//AddNode",
99    "//SubNode",
100)
101def binop_bool():
102    """
103    >>> binop_bool()
104    (2, 1, 0, True, True, 1, False, 2, 2, -2, False, True, 1, False)
105    """
106    plus1  = True + True
107    pmix1  = True + 0
108    minus1 = True - True
109    and1   = True & True
110    or1    = True | True
111    ormix1 = True | 0
112    xor1   = True ^ True
113    plus3  = False + True + False + True
114    pmix3  = False + True + 0 + True
115    minus3 = False - True - False - True
116    and3   = False & True & False & True
117    or3    = False | True | False | True
118    ormix3 = False | 0 | False | True
119    xor3   = False ^ True ^ False ^ True
120    return plus1, pmix1, minus1, and1, or1, ormix1, xor1, plus3, pmix3, minus3, and3, or3, ormix3, xor3
121
122
123@cython.test_fail_if_path_exists(
124    "//MulNode",
125    "//PowNode",
126)
127def binop_mul_pow():
128    """
129    >>> print_big_ints(binop_mul_pow())
130    (800, 12193263111263526900, 248832, 12467572902176589255564000298710470656)
131    """
132    mul_int = 20 * 40
133    mul_large_int = 1234567890 * 9876543210
134    pow_int = 12 ** 5
135    pow_large_int = 1234 ** 12
136    return (mul_int, mul_large_int, pow_int, pow_large_int)
137
138
139@cython.test_fail_if_path_exists(
140    "//SliceIndexNode",
141)
142def slicing2():
143    """
144    >>> slicing2()
145    ([1, 2, 3, 4], [3, 4], [1, 2, 3, 4], [3, 4], (1, 2, 3, 4), (3, 4), (1, 2, 3, 4), (3, 4))
146    """
147    lst0 = [1, 2, 3, 4][:]
148    lst1 = [1, 2, 3, 4][2:]
149    lst2 = [1, 2, 3, 4][:4]
150    lst3 = [1, 2, 3, 4][2:4]
151
152    tpl0 = (1, 2, 3, 4)[:]
153    tpl1 = (1, 2, 3, 4)[2:]
154    tpl2 = (1, 2, 3, 4)[:4]
155    tpl3 = (1, 2, 3, 4)[2:4]
156
157    return lst0, lst1, lst2, lst3, tpl0, tpl1, tpl2, tpl3
158
159
160@cython.test_fail_if_path_exists(
161    "//SliceIndexNode",
162)
163def str_slicing2():
164    """
165    >>> a,b,c,d = str_slicing2()
166    >>> a == 'abc\\xE9def'[:]
167    True
168    >>> b == 'abc\\xE9def'[2:]
169    True
170    >>> c == 'abc\\xE9def'[:4]
171    True
172    >>> d == 'abc\\xE9def'[2:4]
173    True
174    """
175    str0 = 'abc\xE9def'[:]
176    str1 = 'abc\xE9def'[2:]
177    str2 = 'abc\xE9def'[:4]
178    str3 = 'abc\xE9def'[2:4]
179
180    return str0, str1, str2, str3
181
182
183@cython.test_fail_if_path_exists(
184    "//IfStatNode",
185)
186def str_in_and_not_in():
187    """
188    >>> str_in_and_not_in()
189    True
190    """
191    if 'a' in 'abc' and 'b' in 'abc' and 'c' in 'abc' and 'd' not in 'abc': return True
192    else: return False
193
194
195@cython.test_fail_if_path_exists(
196    "//WhileStatNode",
197)
198def while_false():
199    """
200    >>> while_false()
201    """
202    while 1 == 0:
203        return False
204
205
206@cython.test_fail_if_path_exists(
207    "//WhileStatNode",
208    )
209def while_false_else():
210    """
211    >>> while_false_else()
212    True
213    """
214    while 1 == 0:
215        return False
216    else:
217        return True
218
219
220@cython.test_fail_if_path_exists(
221    "//WhileStatNode//PrintStatNode",
222    "//WhileStatNode//PrimaryCmpNode",
223    "//WhileStatNode/BoolNode",
224    "//WhileStatNode/IntNode",
225)
226@cython.test_assert_path_exists(
227    "//WhileStatNode",
228)
229def while_true():
230    """
231    >>> while_true()
232    True
233    """
234    while 1 == 1:
235        return True
236    else:
237        print("FAIL")
238
239
240@cython.test_fail_if_path_exists(
241    "//ForInStatNode",
242)
243def for_in_empty():
244    """
245    >>> for_in_empty()
246    """
247    for i in []:
248        print("LOOP")
249
250
251@cython.test_fail_if_path_exists(
252    "//ForInStatNode",
253)
254def for_in_empty_else():
255    """
256    >>> for_in_empty_else()
257    True
258    """
259    for i in []:
260        print("LOOP")
261    else:
262        return True
263
264
265@cython.test_fail_if_path_exists(
266    "//ComprehensionNode",
267    "//ForInStatNode",
268)
269@cython.test_assert_path_exists(
270    "//ListNode",
271)
272def for_in_empty_listcomp():
273    """
274    >>> for_in_empty_listcomp()
275    []
276    """
277    return [i for i in []]
278
279
280@cython.test_fail_if_path_exists(
281    "//ComprehensionNode",
282    "//ForInStatNode",
283)
284@cython.test_assert_path_exists(
285    "//ListNode",
286)
287def for_in_empty_nested_listcomp():
288    """
289    >>> for_in_empty_nested_listcomp()
290    []
291    """
292    return [x for _ in [] for x in [1, 2, 3]]
293
294
295@cython.test_fail_if_path_exists(
296    "//ForInStatNode//ForInStatNode",
297)
298@cython.test_assert_path_exists(
299    "//ForInStatNode",
300    "//ComprehensionNode",
301)
302def for_in_nested_listcomp():
303    """
304    >>> for_in_nested_listcomp()
305    []
306    """
307    return [x for x in [1, 2, 3] for _ in []]
308
309
310@cython.test_fail_if_path_exists(
311    "//MulNode",
312)
313def mult_empty_list():
314    """
315    >>> mult_empty_list()
316    []
317    """
318    return 5 * [] * 100
319
320
321@cython.test_fail_if_path_exists(
322    "//MulNode",
323)
324def mult_list_int_int():
325    """
326    >>> mult_list_int_int()
327    [1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2]
328    """
329    return [1, 2] * 2 * 3
330
331
332@cython.test_fail_if_path_exists(
333    "//MulNode",
334)
335def mult_int_list_int():
336    """
337    >>> mult_int_list_int()
338    [1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2]
339    """
340    return 3 * [1, 2] * 2
341
342
343@cython.test_fail_if_path_exists(
344    "//MulNode",
345    "//ListNode//IntNode",
346)
347def neg_mult_list():
348    """
349    >>> neg_mult_list()
350    []
351    """
352    return -5 * [1, 2] * -100
353
354
355@cython.test_fail_if_path_exists(
356    "//MulNode",
357    "//ListNode//IntNode",
358)
359def zero_mult_list():
360    """
361    >>> zero_mult_list()
362    []
363    """
364    return 0 * [1, 2] * 0
365
366
367@cython.test_assert_path_exists(
368    "//BoolNode",
369)
370@cython.test_fail_if_path_exists(
371    "//PrimaryCmpNode",
372    "//MulNode",
373    "//ListNode//IntNode",
374)
375def in_mult_list():
376    """
377    >>> in_mult_list()
378    False
379    """
380    return 5 in 100 * [1, 2] * 0
381
382
383@cython.test_assert_path_exists(
384    "//BoolNode",
385)
386@cython.test_fail_if_path_exists(
387    "//PrimaryCmpNode",
388    "//MulNode",
389    "//ListNode//IntNode",
390)
391def not_in_mult_list():
392    """
393    >>> not_in_mult_list()
394    True
395    """
396    return 5 not in 100 * [1, 2] * 0
397
398
399@cython.test_assert_path_exists(
400    "//BoolNode",
401)
402@cython.test_fail_if_path_exists(
403    "//PrimaryCmpNode",
404    "//MulNode",
405    "//ListNode//IntNode",
406)
407def combined():
408    """
409    >>> combined()
410    True
411    """
412    return 5 in 100 * [1, 2] * 0  or  5 not in 100 * [] * 10
413
414
415@cython.test_assert_path_exists(
416    '//IntNode[@value = "2"]',
417    '//IntNode[@value = "4"]',
418    '//IntNode[@value = "5"]',
419    '//IntNode[@value = "7"]',
420    '//BoolBinopNode//PrimaryCmpNode',
421    '//BoolBinopNode[.//PrimaryCmpNode//IntNode[@value = "4"] and .//PrimaryCmpNode//IntNode[@value = "5"]]',
422    '//PrimaryCmpNode[.//IntNode[@value = "2"] and .//IntNode[@value = "4"]]',
423    '//PrimaryCmpNode[.//IntNode[@value = "5"] and .//IntNode[@value = "7"]]',
424)
425@cython.test_fail_if_path_exists(
426    '//IntNode[@value = "1"]',
427    '//IntNode[@value = "8"]',
428    '//PrimaryCmpNode[.//IntNode[@value = "4"] and .//IntNode[@value = "5"]]',
429    '//PrimaryCmpNode[.//IntNode[@value = "2"] and .//IntNode[@value = "7"]]',
430    '//BoolNode',
431)
432def cascaded_cmp_with_partial_constants(a, b):
433    """
434    >>> cascaded_cmp_with_partial_constants(3, 6)
435    True
436    >>> cascaded_cmp_with_partial_constants(1, 6)
437    False
438    >>> cascaded_cmp_with_partial_constants(4, 6)
439    False
440    >>> cascaded_cmp_with_partial_constants(3, 7)
441    False
442    >>> cascaded_cmp_with_partial_constants(3, 6)
443    True
444    """
445    return 1 < 2 < a < 4 < 5 < b < 7 < 8
446
447
448@cython.test_assert_path_exists(
449    '//IntNode[@value = "2"]',
450    '//IntNode[@value = "4"]',
451    '//IntNode[@value = "5"]',
452    '//IntNode[@value = "7"]',
453    '//BoolBinopNode',
454    '//SingleAssignmentNode//BoolBinopNode',
455    '//SingleAssignmentNode//BoolBinopNode//NameNode[@name = "a"]',
456    '//SingleAssignmentNode//BoolBinopNode//NameNode[@name = "b"]',
457    '//BoolBinopNode[.//PrimaryCmpNode//IntNode[@value = "4"] and .//PrimaryCmpNode//IntNode[@value = "5"]]',
458    '//BoolNode[@value = False]',
459)
460@cython.test_fail_if_path_exists(
461    '//SingleAssignmentNode//NameNode[@name = "c"]',
462    '//IntNode[@value = "1"]',
463    '//PrimaryCmpNode[.//IntNode[@value = "4"] and .//IntNode[@value = "5"]]',
464    '//PrimaryCmpNode[.//IntNode[@value = "2"] and .//IntNode[@value = "7"]]',
465    '//BoolNode[@value = True]',
466)
467def cascaded_cmp_with_partial_constants_and_false_end(a, b, c):
468    """
469    >>> cascaded_cmp_with_partial_constants_and_false_end(3, 6, 8)
470    False
471    >>> cascaded_cmp_with_partial_constants_and_false_end(1, 6, 8)
472    False
473    >>> cascaded_cmp_with_partial_constants_and_false_end(4, 6, 8)
474    False
475    >>> cascaded_cmp_with_partial_constants_and_false_end(3, 7, 8)
476    False
477    """
478    x = 1 < 2 < a < 4 < 5 < b < 7 < 7 < c
479    return x
480
481
482@cython.test_assert_path_exists(
483    '//PrimaryCmpNode',
484    '//PrimaryCmpNode//IntNode',
485    '//PrimaryCmpNode//IntNode[@value = "0"]',
486    '//PrimaryCmpNode//IntNode[@value = "4294967296"]',
487)
488@cython.test_fail_if_path_exists(
489    '//PrimaryCmpNode//IntBinopNode',
490    '//PrimaryCmpNode//IntNode[@value = "1"]',
491    '//PrimaryCmpNode//IntNode[@value = "32"]',
492)
493def const_in_binop(v):
494    """
495    >>> const_in_binop(-1)
496    1
497    >>> const_in_binop(0)
498    0
499    >>> const_in_binop(1 << 32)
500    1
501    >>> const_in_binop(1 << 32 - 1)
502    0
503    """
504    if v < 0 or v >= (1 << 32):
505        return 1
506    else:
507        return 0
508