Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit ed4749e

Browse files
author
whitequark
committedJul 22, 2015
Add bool coercion support.
1 parent de181e0 commit ed4749e

File tree

5 files changed

+53
-9
lines changed

5 files changed

+53
-9
lines changed
 

Diff for: ‎artiq/compiler/transforms/artiq_ir_generator.py

+27-6
Original file line numberDiff line numberDiff line change
@@ -284,8 +284,29 @@ def visit_AugAssign(self, node):
284284
finally:
285285
self.current_assign = None
286286

287+
def coerce_to_bool(self, insn, block=None):
288+
if builtins.is_bool(insn.type):
289+
return insn
290+
elif builtins.is_int(insn.type):
291+
return self.append(ir.Compare(ast.NotEq(loc=None), insn, ir.Constant(0, insn.type)),
292+
block=block)
293+
elif builtins.is_float(insn.type):
294+
return self.append(ir.Compare(ast.NotEq(loc=None), insn, ir.Constant(0, insn.type)),
295+
block=block)
296+
elif builtins.is_iterable(insn.type):
297+
length = self.iterable_len(insn)
298+
return self.append(ir.Compare(ast.NotEq(loc=None), length, ir.Constant(0, length.type)),
299+
block=block)
300+
else:
301+
diag = diagnostic.Diagnostic("warning",
302+
"this expression, which is always truthful, is coerced to bool", {},
303+
insn.loc)
304+
self.engine.process(diag)
305+
return ir.Constant(True, builtins.TBool())
306+
287307
def visit_If(self, node):
288308
cond = self.visit(node.test)
309+
cond = self.coerce_to_bool(cond)
289310
head = self.current_block
290311

291312
if_true = self.add_block()
@@ -838,17 +859,19 @@ def visit_BoolOpT(self, node):
838859
zip(blocks, [(h,t) for (v,h,t) in blocks[1:]] + [(tail, tail)]):
839860
phi.add_incoming(value, value_tail)
840861
if next_value_head != tail:
862+
cond = self.coerce_to_bool(value, block=value_tail)
841863
if isinstance(node.op, ast.And):
842-
value_tail.append(ir.BranchIf(value, next_value_head, tail))
864+
value_tail.append(ir.BranchIf(cond, next_value_head, tail))
843865
else:
844-
value_tail.append(ir.BranchIf(value, tail, next_value_head))
866+
value_tail.append(ir.BranchIf(cond, tail, next_value_head))
845867
else:
846868
value_tail.append(ir.Branch(tail))
847869
return phi
848870

849871
def visit_UnaryOpT(self, node):
850872
if isinstance(node.op, ast.Not):
851-
return self.append(ir.Select(self.visit(node.operand),
873+
cond = self.coerce_to_bool(self.visit(node.operand))
874+
return self.append(ir.Select(cond,
852875
ir.Constant(False, builtins.TBool()),
853876
ir.Constant(True, builtins.TBool())))
854877
elif isinstance(node.op, ast.USub):
@@ -1116,9 +1139,7 @@ def visit_builtin_call(self, node):
11161139
return ir.Constant(False, builtins.TBool())
11171140
elif len(node.args) == 1 and len(node.keywords) == 0:
11181141
arg = self.visit(node.args[0])
1119-
return self.append(ir.Select(arg,
1120-
ir.Constant(True, builtins.TBool()),
1121-
ir.Constant(False, builtins.TBool())))
1142+
return self.coerce_to_bool(arg)
11221143
else:
11231144
assert False
11241145
elif types.is_builtin(typ, "int"):

Diff for: ‎artiq/compiler/transforms/llvm_ir_generator.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ def process_Coerce(self, insn):
295295
if builtins.get_int_width(typ) > builtins.get_int_width(value_typ):
296296
return self.llbuilder.sext(self.map(insn.value()), self.llty_of_type(typ),
297297
name=insn.name)
298-
else: # builtins.get_int_width(typ) < builtins.get_int_width(value_typ):
298+
else: # builtins.get_int_width(typ) <= builtins.get_int_width(value_typ):
299299
return self.llbuilder.trunc(self.map(insn.value()), self.llty_of_type(typ),
300300
name=insn.name)
301301
else:

Diff for: ‎lit-test/compiler/codegen/warning_useless_bool.py

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# RUN: %python -m artiq.compiler.testbench.module +diag %s >%t
2+
# RUN: OutputCheck %s --file-to-check=%t
3+
4+
# CHECK-L: ${LINE:+1}: warning: this expression, which is always truthful, is coerced to bool
5+
bool(IndexError())

Diff for: ‎lit-test/compiler/integration/operator.py renamed to ‎lit-test/compiler/integration/arithmetics.py

-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
# RUN: %python -m artiq.compiler.testbench.jit %s
22

3-
assert (not True) == False
4-
assert (not False) == True
53
assert -(-1) == 1
64
assert -(-1.0) == 1.0
75
assert +1 == 1

Diff for: ‎lit-test/compiler/integration/bool.py

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# RUN: %python -m artiq.compiler.testbench.jit %s
2+
3+
assert (not 0) == True
4+
assert (not 1) == False
5+
6+
assert (0 and 0) is 0
7+
assert (1 and 0) is 0
8+
assert (0 and 1) is 0
9+
assert (1 and 2) is 2
10+
11+
assert (0 or 0) is 0
12+
assert (1 or 0) is 1
13+
assert (0 or 1) is 1
14+
assert (1 or 2) is 1
15+
16+
assert bool(False) is False and bool(False) is False
17+
assert bool(0) is False and bool(1) is True
18+
assert bool(0.0) is False and bool(1.0) is True
19+
x = []; assert bool(x) is False; x = [1]; assert bool(x) is True
20+
assert bool(range(0)) is False and bool(range(1)) is True

0 commit comments

Comments
 (0)