1
1
import unittest
2
2
3
- from typing import List
3
+ from typing import List , Optional
4
4
5
5
from mypy .ordered_dict import OrderedDict
6
6
24
24
from mypyc .codegen .emitfunc import generate_native_function , FunctionEmitterVisitor
25
25
from mypyc .primitives .registry import binary_ops
26
26
from mypyc .primitives .misc_ops import none_object_op
27
- from mypyc .primitives .list_ops import (
28
- list_get_item_op , list_set_item_op , list_append_op
29
- )
27
+ from mypyc .primitives .list_ops import list_get_item_op , list_set_item_op , list_append_op
30
28
from mypyc .primitives .dict_ops import (
31
29
dict_new_op , dict_update_op , dict_get_item_op , dict_set_item_op
32
30
)
36
34
37
35
38
36
class TestFunctionEmitterVisitor (unittest .TestCase ):
37
+ """Test generation of fragments of C from individual IR ops."""
38
+
39
39
def setUp (self ) -> None :
40
40
self .registers = [] # type: List[Register]
41
41
@@ -75,6 +75,10 @@ def test_goto(self) -> None:
75
75
self .assert_emit (Goto (BasicBlock (2 )),
76
76
"goto CPyL2;" )
77
77
78
+ def test_goto_next_block (self ) -> None :
79
+ next_block = BasicBlock (2 )
80
+ self .assert_emit (Goto (next_block ), "" , next_block = next_block )
81
+
78
82
def test_return (self ) -> None :
79
83
self .assert_emit (Return (self .m ),
80
84
"return cpy_r_m;" )
@@ -128,6 +132,61 @@ def test_branch(self) -> None:
128
132
goto CPyL9;
129
133
""" )
130
134
135
+ def test_branch_no_else (self ) -> None :
136
+ next_block = BasicBlock (9 )
137
+ b = Branch (self .b , BasicBlock (8 ), next_block , Branch .BOOL )
138
+ self .assert_emit (b ,
139
+ """if (cpy_r_b) goto CPyL8;""" ,
140
+ next_block = next_block )
141
+ next_block = BasicBlock (9 )
142
+ b = Branch (self .b , BasicBlock (8 ), next_block , Branch .BOOL )
143
+ b .negated = True
144
+ self .assert_emit (b ,
145
+ """if (!cpy_r_b) goto CPyL8;""" ,
146
+ next_block = next_block )
147
+
148
+ def test_branch_no_else_negated (self ) -> None :
149
+ next_block = BasicBlock (1 )
150
+ b = Branch (self .b , next_block , BasicBlock (2 ), Branch .BOOL )
151
+ self .assert_emit (b ,
152
+ """if (!cpy_r_b) goto CPyL2;""" ,
153
+ next_block = next_block )
154
+ next_block = BasicBlock (1 )
155
+ b = Branch (self .b , next_block , BasicBlock (2 ), Branch .BOOL )
156
+ b .negated = True
157
+ self .assert_emit (b ,
158
+ """if (cpy_r_b) goto CPyL2;""" ,
159
+ next_block = next_block )
160
+
161
+ def test_branch_is_error (self ) -> None :
162
+ b = Branch (self .b , BasicBlock (8 ), BasicBlock (9 ), Branch .IS_ERROR )
163
+ self .assert_emit (b ,
164
+ """if (cpy_r_b == 2) {
165
+ goto CPyL8;
166
+ } else
167
+ goto CPyL9;
168
+ """ )
169
+ b = Branch (self .b , BasicBlock (8 ), BasicBlock (9 ), Branch .IS_ERROR )
170
+ b .negated = True
171
+ self .assert_emit (b ,
172
+ """if (cpy_r_b != 2) {
173
+ goto CPyL8;
174
+ } else
175
+ goto CPyL9;
176
+ """ )
177
+
178
+ def test_branch_is_error_next_block (self ) -> None :
179
+ next_block = BasicBlock (8 )
180
+ b = Branch (self .b , next_block , BasicBlock (9 ), Branch .IS_ERROR )
181
+ self .assert_emit (b ,
182
+ """if (cpy_r_b != 2) goto CPyL9;""" ,
183
+ next_block = next_block )
184
+ b = Branch (self .b , next_block , BasicBlock (9 ), Branch .IS_ERROR )
185
+ b .negated = True
186
+ self .assert_emit (b ,
187
+ """if (cpy_r_b == 2) goto CPyL9;""" ,
188
+ next_block = next_block )
189
+
131
190
def test_call (self ) -> None :
132
191
decl = FuncDecl ('myfn' , None , 'mod' ,
133
192
FuncSignature ([RuntimeArg ('m' , int_rprimitive )], int_rprimitive ))
@@ -318,7 +377,7 @@ def test_long_unsigned(self) -> None:
318
377
self .assert_emit (Assign (a , Integer ((1 << 31 ) - 1 , int64_rprimitive )),
319
378
"""cpy_r_a = 2147483647;""" )
320
379
321
- def assert_emit (self , op : Op , expected : str ) -> None :
380
+ def assert_emit (self , op : Op , expected : str , next_block : Optional [ BasicBlock ] = None ) -> None :
322
381
block = BasicBlock (0 )
323
382
block .ops .append (op )
324
383
value_names = generate_names_for_ir (self .registers , [block ])
@@ -328,13 +387,17 @@ def assert_emit(self, op: Op, expected: str) -> None:
328
387
declarations .fragments = []
329
388
330
389
visitor = FunctionEmitterVisitor (emitter , declarations , 'prog.py' , 'prog' )
390
+ visitor .next_block = next_block
331
391
332
392
op .accept (visitor )
333
393
frags = declarations .fragments + emitter .fragments
334
394
actual_lines = [line .strip (' ' ) for line in frags ]
335
395
assert all (line .endswith ('\n ' ) for line in actual_lines )
336
396
actual_lines = [line .rstrip ('\n ' ) for line in actual_lines ]
337
- expected_lines = expected .rstrip ().split ('\n ' )
397
+ if not expected .strip ():
398
+ expected_lines = []
399
+ else :
400
+ expected_lines = expected .rstrip ().split ('\n ' )
338
401
expected_lines = [line .strip (' ' ) for line in expected_lines ]
339
402
assert_string_arrays_equal (expected_lines , actual_lines ,
340
403
msg = 'Generated code unexpected' )
0 commit comments