1.1 --- a/translator.py Mon Feb 27 14:54:37 2017 +0100
1.2 +++ b/translator.py Mon Feb 27 15:50:58 2017 +0100
1.3 @@ -201,7 +201,7 @@
1.4 def __repr__(self):
1.5 return "TrResolvedInstanceRef(%r, %r)" % (self.ref, self.expr)
1.6
1.7 -class AttrResult(Expression, TranslationResult, InstructionSequence):
1.8 +class AttrResult(Expression, InstructionSequence):
1.9
1.10 "A translation result for an attribute access."
1.11
1.12 @@ -240,7 +240,7 @@
1.13 def __repr__(self):
1.14 return "AttrResult(%r, %r, %r)" % (self.instructions, self.refs, self.location)
1.15
1.16 -class InvocationResult(Expression, TranslationResult, InstructionSequence):
1.17 +class InvocationResult(Expression, InstructionSequence):
1.18
1.19 "A translation result for an invocation."
1.20
1.21 @@ -264,7 +264,7 @@
1.22 def __repr__(self):
1.23 return "InstantiationResult(%r, %r)" % (self.ref, self.instructions)
1.24
1.25 -class PredefinedConstantRef(Expression, TranslationResult):
1.26 +class PredefinedConstantRef(Expression):
1.27
1.28 "A predefined constant reference."
1.29
1.30 @@ -293,7 +293,7 @@
1.31 def __repr__(self):
1.32 return "PredefinedConstantRef(%r)" % self.value
1.33
1.34 -class BooleanResult(Expression, TranslationResult):
1.35 +class BooleanResult(Expression):
1.36
1.37 "A expression producing a boolean result."
1.38
1.39 @@ -303,6 +303,25 @@
1.40 def __repr__(self):
1.41 return "BooleanResult(%r)" % self.s
1.42
1.43 +class LogicalResult(TranslationResult):
1.44 +
1.45 + "A logical expression result."
1.46 +
1.47 + def __init__(self, expr):
1.48 + self.expr = expr
1.49 +
1.50 + def apply_test(self, negate=False):
1.51 + return "(%s__BOOL(%s))" % (negate and "" or "!", self.expr)
1.52 +
1.53 + def __str__(self):
1.54 + return "(__BOOL(%s) ? %s : %s)" % (
1.55 + self.expr,
1.56 + PredefinedConstantRef("False"),
1.57 + PredefinedConstantRef("True"))
1.58 +
1.59 + def __repr__(self):
1.60 + return "LogicalResult(%r)" % self.expr
1.61 +
1.62 def make_expression(expr):
1.63
1.64 "Make a new expression from the existing 'expr'."
1.65 @@ -1633,9 +1652,7 @@
1.66
1.67 "Process the given operator node 'n'."
1.68
1.69 - return make_expression("(__BOOL(%s) ? %s : %s)" %
1.70 - (self.process_structure_node(n.expr), PredefinedConstantRef("False"),
1.71 - PredefinedConstantRef("True")))
1.72 + return LogicalResult(self.process_structure_node(n.expr))
1.73
1.74 def process_raise_node(self, n):
1.75
1.76 @@ -1845,17 +1862,13 @@
1.77
1.78 if not (isinstance(test, PredefinedConstantRef) and test.value):
1.79
1.80 - # NOTE: This needs to evaluate whether the operand is true or false
1.81 - # NOTE: according to Python rules.
1.82 -
1.83 - self.writeline("if (!__BOOL(%s))" % test)
1.84 - self.writeline("{")
1.85 - self.indent += 1
1.86 + # Emit a negated test of the continuation condition.
1.87 +
1.88 + self.start_if(True, test, True)
1.89 if n.else_:
1.90 self.process_structure_node(n.else_)
1.91 self.writestmt("break;")
1.92 - self.indent -= 1
1.93 - self.writeline("}")
1.94 + self.end_if()
1.95
1.96 in_conditional = self.in_conditional
1.97 self.in_conditional = True
1.98 @@ -2048,8 +2061,16 @@
1.99 for i, parameter in enumerate(parameters):
1.100 self.writeline("__attr * const %s = &__args[%d];" % (encode_path(parameter), i+1))
1.101
1.102 - def start_if(self, first, test_ref):
1.103 - self.writestmt("%sif (__BOOL(%s))" % (not first and "else " or "", test_ref))
1.104 + def start_if(self, first, test_ref, negate=False):
1.105 + statement = "%sif" % (not first and "else " or "")
1.106 +
1.107 + # Consume logical results directly.
1.108 +
1.109 + if isinstance(test_ref, LogicalResult):
1.110 + self.writeline("%s %s" % (statement, test_ref.apply_test(negate)))
1.111 + else:
1.112 + self.writeline("%s (%s__BOOL(%s))" % (statement, negate and "!" or "", test_ref))
1.113 +
1.114 self.writeline("{")
1.115 self.indent += 1
1.116