1.1 --- a/translator.py Mon Feb 27 15:49:05 2017 +0100
1.2 +++ b/translator.py Mon Feb 27 15:50:30 2017 +0100
1.3 @@ -303,6 +303,25 @@
1.4 def __repr__(self):
1.5 return "BooleanResult(%r)" % self.s
1.6
1.7 +class LogicalResult(TranslationResult):
1.8 +
1.9 + "A logical expression result."
1.10 +
1.11 + def __init__(self, expr):
1.12 + self.expr = expr
1.13 +
1.14 + def apply_test(self, negate=False):
1.15 + return "(%s__BOOL(%s))" % (negate and "" or "!", self.expr)
1.16 +
1.17 + def __str__(self):
1.18 + return "(__BOOL(%s) ? %s : %s)" % (
1.19 + self.expr,
1.20 + PredefinedConstantRef("False"),
1.21 + PredefinedConstantRef("True"))
1.22 +
1.23 + def __repr__(self):
1.24 + return "LogicalResult(%r)" % self.expr
1.25 +
1.26 def make_expression(expr):
1.27
1.28 "Make a new expression from the existing 'expr'."
1.29 @@ -1635,9 +1654,7 @@
1.30
1.31 "Process the given operator node 'n'."
1.32
1.33 - return make_expression("(__BOOL(%s) ? %s : %s)" %
1.34 - (self.process_structure_node(n.expr), PredefinedConstantRef("False"),
1.35 - PredefinedConstantRef("True")))
1.36 + return LogicalResult(self.process_structure_node(n.expr))
1.37
1.38 def process_raise_node(self, n):
1.39
1.40 @@ -1847,17 +1864,13 @@
1.41
1.42 if not (isinstance(test, PredefinedConstantRef) and test.value):
1.43
1.44 - # NOTE: This needs to evaluate whether the operand is true or false
1.45 - # NOTE: according to Python rules.
1.46 -
1.47 - self.writeline("if (!__BOOL(%s))" % test)
1.48 - self.writeline("{")
1.49 - self.indent += 1
1.50 + # Emit a negated test of the continuation condition.
1.51 +
1.52 + self.start_if(True, test, True)
1.53 if n.else_:
1.54 self.process_structure_node(n.else_)
1.55 self.writestmt("break;")
1.56 - self.indent -= 1
1.57 - self.writeline("}")
1.58 + self.end_if()
1.59
1.60 in_conditional = self.in_conditional
1.61 self.in_conditional = True
1.62 @@ -2050,8 +2063,16 @@
1.63 for i, parameter in enumerate(parameters):
1.64 self.writeline("__attr * const %s = &__args[%d];" % (encode_path(parameter), i+1))
1.65
1.66 - def start_if(self, first, test_ref):
1.67 - self.writestmt("%sif (__BOOL(%s))" % (not first and "else " or "", test_ref))
1.68 + def start_if(self, first, test_ref, negate=False):
1.69 + statement = "%sif" % (not first and "else " or "")
1.70 +
1.71 + # Consume logical results directly.
1.72 +
1.73 + if isinstance(test_ref, LogicalResult):
1.74 + self.writeline("%s %s" % (statement, test_ref.apply_test(negate)))
1.75 + else:
1.76 + self.writeline("%s (%s__BOOL(%s))" % (statement, negate and "!" or "", test_ref))
1.77 +
1.78 self.writeline("{")
1.79 self.indent += 1
1.80