# HG changeset patch # User Paul Boddie # Date 1716502464 -7200 # Node ID 62e75f9a08ab63d042201aa737e65c56b2a0ca7c # Parent 8b2774ab25007f0fd104e99168a2fe6b24652297# Parent 9da80803c49accec315b7801f4e98a4650f28c06 Merged changes from the default branch. diff -r 8b2774ab2500 -r 62e75f9a08ab results.py --- a/results.py Tue May 21 19:04:32 2024 +0200 +++ b/results.py Fri May 24 00:14:24 2024 +0200 @@ -3,7 +3,7 @@ """ Result abstractions. -Copyright (C) 2016, 2017, 2023 Paul Boddie +Copyright (C) 2016, 2017, 2023, 2024 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -69,6 +69,20 @@ def has_kind(self, kinds): return False + # Support for formulating expressions for direct testing. + + def yields_integer(self): + return False + + def apply_test(self): + + "Return the result in a form suitable for direct testing." + + if self.yields_integer(): + return "__INTEGER(%s)" % self + else: + return "__BOOL(%s)" % self + class AccessRef(Result): """ diff -r 8b2774ab2500 -r 62e75f9a08ab translator.py --- a/translator.py Tue May 21 19:04:32 2024 +0200 +++ b/translator.py Fri May 24 00:14:24 2024 +0200 @@ -1285,6 +1285,10 @@ if stores_accessor: self.record_temp("__tmp_values") + # NOTE: Special case for optimisation. + + yields_integer = target and objpath == "native.int.is_int" + # Arguments are presented in a temporary frame array with any context # always being the first argument. Where it would be unused, it may be # set to null. @@ -1409,9 +1413,17 @@ # the number of values. The context is excluded. if literal_instantiation: - argstr = "%d, %s" % (len(args) - reserved_args, ", ".join(args[reserved_args:])) + final_args = args[reserved_args:] + argstr = "%d, %s" % (len(final_args), ", ".join(final_args)) else: - argstr = ", ".join(args) + # NOTE: Special case for optimisation. + + if yields_integer: + final_args = args[reserved_args:] + else: + final_args = args + + argstr = ", ".join(final_args) kwargstr = kwargs and ("__ARGS(%s)" % ", ".join(kwargs)) or "0" kwcodestr = kwcodes and ("__KWARGS(%s)" % ", ".join(kwcodes)) or "0" @@ -1485,7 +1497,11 @@ if instantiation: return InstantiationResult(instantiation, stages) else: - return InvocationResult(stages) + # Provide the parameter details for possible optimisation when + # translating the result. + + return InvocationResult(stages, + yields_integer and final_args or None) # With unknown targets, the generic invocation function is applied to # the callable and argument collections. @@ -2227,7 +2243,7 @@ if temps: self.remove_temps(temps) else: - self.writeline("%s (__BOOL(%s))" % (statement, test_ref)) + self.writeline("%s (%s)" % (statement, test_ref.apply_test())) self.writeline("{") self.indent += 1 diff -r 8b2774ab2500 -r 62e75f9a08ab transresults.py --- a/transresults.py Tue May 21 19:04:32 2024 +0200 +++ b/transresults.py Fri May 24 00:14:24 2024 +0200 @@ -3,7 +3,7 @@ """ Translation result abstractions. -Copyright (C) 2016, 2017, 2018, 2021 Paul Boddie +Copyright (C) 2016-2018, 2021, 2023, 2024 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -285,11 +285,21 @@ "A translation result for an invocation." + def __init__(self, instructions, args=None): + InstructionSequence.__init__(self, instructions) + self.args = args + + def yields_integer(self): + return self.args and True or False + def __str__(self): - return encode_instructions(self.instructions) + if self.yields_integer(): + return ", ".join(self.args) + else: + return encode_instructions(self.instructions) def __repr__(self): - return "InvocationResult(%r)" % self.instructions + return "InvocationResult(%r, %r)" % (self.instructions, self.args) class InstantiationResult(InvocationResult, TrInstanceRef): @@ -335,14 +345,7 @@ "A logical expression result." - def _convert(self, expr): - - "Return 'expr' converted to a testable value." - - if isinstance(expr, LogicalResult): - return expr.apply_test() - else: - return "__BOOL(%s)" % expr + pass class NegationResult(LogicalResult): @@ -355,8 +358,7 @@ "Return the result in a form suitable for direct testing." - expr = self._convert(self.expr) - return "(!%s)" % expr + return "(!%s)" % self.expr.apply_test() def discards_temporary(self, test=True): @@ -367,9 +369,12 @@ return None + def yields_integer(self): + return self.expr.yields_integer() + def __str__(self): return "(%s ? %s : %s)" % ( - self._convert(self.expr), + self.expr.apply_test(), PredefinedConstantRef("False"), PredefinedConstantRef("True")) @@ -400,7 +405,7 @@ results = [] for expr in self.exprs: - results.append(self._convert(expr)) + results.append(expr.apply_test()) if self.conjunction: return "(%s)" % " && ".join(results) @@ -426,6 +431,12 @@ return temps + def yields_integer(self): + for expr in self.exprs: + if not expr.yields_integer(): + return False + return True + def __str__(self): """