# HG changeset patch # User Paul Boddie # Date 1488207058 -3600 # Node ID 9d6309ccaceb55e2edad197c92f6bb3137f003a0 # Parent 05ad7964265c739b224c2557724572a31d3b6951# Parent c45334be1ad6e81d52866b43d5bb64f2fe725b11 Merged result class changes. diff -r 05ad7964265c -r 9d6309ccaceb translator.py --- a/translator.py Mon Feb 27 14:54:37 2017 +0100 +++ b/translator.py Mon Feb 27 15:50:58 2017 +0100 @@ -201,7 +201,7 @@ def __repr__(self): return "TrResolvedInstanceRef(%r, %r)" % (self.ref, self.expr) -class AttrResult(Expression, TranslationResult, InstructionSequence): +class AttrResult(Expression, InstructionSequence): "A translation result for an attribute access." @@ -240,7 +240,7 @@ def __repr__(self): return "AttrResult(%r, %r, %r)" % (self.instructions, self.refs, self.location) -class InvocationResult(Expression, TranslationResult, InstructionSequence): +class InvocationResult(Expression, InstructionSequence): "A translation result for an invocation." @@ -264,7 +264,7 @@ def __repr__(self): return "InstantiationResult(%r, %r)" % (self.ref, self.instructions) -class PredefinedConstantRef(Expression, TranslationResult): +class PredefinedConstantRef(Expression): "A predefined constant reference." @@ -293,7 +293,7 @@ def __repr__(self): return "PredefinedConstantRef(%r)" % self.value -class BooleanResult(Expression, TranslationResult): +class BooleanResult(Expression): "A expression producing a boolean result." @@ -303,6 +303,25 @@ def __repr__(self): return "BooleanResult(%r)" % self.s +class LogicalResult(TranslationResult): + + "A logical expression result." + + def __init__(self, expr): + self.expr = expr + + def apply_test(self, negate=False): + return "(%s__BOOL(%s))" % (negate and "" or "!", self.expr) + + def __str__(self): + return "(__BOOL(%s) ? %s : %s)" % ( + self.expr, + PredefinedConstantRef("False"), + PredefinedConstantRef("True")) + + def __repr__(self): + return "LogicalResult(%r)" % self.expr + def make_expression(expr): "Make a new expression from the existing 'expr'." @@ -1633,9 +1652,7 @@ "Process the given operator node 'n'." - return make_expression("(__BOOL(%s) ? %s : %s)" % - (self.process_structure_node(n.expr), PredefinedConstantRef("False"), - PredefinedConstantRef("True"))) + return LogicalResult(self.process_structure_node(n.expr)) def process_raise_node(self, n): @@ -1845,17 +1862,13 @@ if not (isinstance(test, PredefinedConstantRef) and test.value): - # NOTE: This needs to evaluate whether the operand is true or false - # NOTE: according to Python rules. - - self.writeline("if (!__BOOL(%s))" % test) - self.writeline("{") - self.indent += 1 + # Emit a negated test of the continuation condition. + + self.start_if(True, test, True) if n.else_: self.process_structure_node(n.else_) self.writestmt("break;") - self.indent -= 1 - self.writeline("}") + self.end_if() in_conditional = self.in_conditional self.in_conditional = True @@ -2048,8 +2061,16 @@ for i, parameter in enumerate(parameters): self.writeline("__attr * const %s = &__args[%d];" % (encode_path(parameter), i+1)) - def start_if(self, first, test_ref): - self.writestmt("%sif (__BOOL(%s))" % (not first and "else " or "", test_ref)) + def start_if(self, first, test_ref, negate=False): + statement = "%sif" % (not first and "else " or "") + + # Consume logical results directly. + + if isinstance(test_ref, LogicalResult): + self.writeline("%s %s" % (statement, test_ref.apply_test(negate))) + else: + self.writeline("%s (%s__BOOL(%s))" % (statement, negate and "!" or "", test_ref)) + self.writeline("{") self.indent += 1