py2llvm: support BoolOp

This commit is contained in:
Sebastien Bourdeauducq 2014-10-13 23:54:56 +08:00
parent 6b173d0a9a
commit d26a9d031b
2 changed files with 56 additions and 3 deletions

View File

@ -100,6 +100,57 @@ class Visitor:
self.visit_expression(node.right), self.visit_expression(node.right),
self.builder) self.builder)
def _visit_expr_BoolOp(self, node):
if self.builder is not None:
initial_block = self.builder.basic_block
function = initial_block.function
merge_block = function.append_basic_block("b_merge")
test_blocks = []
test_values = []
for i, value in enumerate(node.values):
if self.builder is not None:
test_block = function.append_basic_block("b_{}_test".format(i))
test_blocks.append(test_block)
self.builder.position_at_end(test_block)
test_values.append(self.visit_expression(value))
result = test_values[0].new()
for value in test_values[1:]:
result.merge(value)
if self.builder is not None:
self.builder.position_at_end(initial_block)
result.alloca(self.builder, "b_result")
self.builder.branch(test_blocks[0])
next_test_blocks = test_blocks[1:]
next_test_blocks.append(None)
for block, next_block, value in zip(test_blocks,
next_test_blocks,
test_values):
self.builder.position_at_end(block)
bval = value.o_bool(self.builder)
result.auto_store(self.builder,
value.auto_load(self.builder))
if next_block is None:
self.builder.branch(merge_block)
else:
if isinstance(node.op, ast.Or):
self.builder.cbranch(bval.auto_load(self.builder),
merge_block,
next_block)
elif isinstance(node.op, ast.And):
self.builder.cbranch(bval.auto_load(self.builder),
next_block,
merge_block)
else:
raise NotImplementedError
self.builder.position_at_end(merge_block)
return result
def _visit_expr_Compare(self, node): def _visit_expr_Compare(self, node):
comparisons = [] comparisons = []
old_comparator = self.visit_expression(node.left) old_comparator = self.visit_expression(node.left)

View File

@ -15,10 +15,10 @@ def test_base_types(choice):
a = 2 # promoted later to int64 a = 2 # promoted later to int64
b = a + 1 # initially int32, becomes int64 after a is promoted b = a + 1 # initially int32, becomes int64 after a is promoted
c = b//2 # initially int32, becomes int64 after b is promoted c = b//2 # initially int32, becomes int64 after b is promoted
d = 4 # stays int32 d = 4 and 5 # stays int32
x = int64(7) x = int64(7)
a += x # promotes a to int64 a += x # promotes a to int64
foo = True | True foo = True | True or False
bar = None bar = None
myf = 4.5 myf = 4.5
myf2 = myf + x myf2 = myf + x
@ -181,8 +181,10 @@ def array_test():
acc = 0 acc = 0
for i in range(5): for i in range(5):
for j in range(5): for j in range(5):
if i + j == 2: if i + j == 2 or i + j == 1:
continue continue
if i and j and a[i][j]:
acc += 1
acc += a[i][j] acc += a[i][j]
return acc return acc