1.1 --- a/encoders.py Sun Jan 22 01:13:31 2017 +0100
1.2 +++ b/encoders.py Sun Jan 22 01:16:01 2017 +0100
1.3 @@ -3,7 +3,7 @@
1.4 """
1.5 Encoder functions, producing representations of program objects.
1.6
1.7 -Copyright (C) 2016 Paul Boddie <paul@boddie.org.uk>
1.8 +Copyright (C) 2016, 2017 Paul Boddie <paul@boddie.org.uk>
1.9
1.10 This program is free software; you can redistribute it and/or modify it under
1.11 the terms of the GNU General Public License as published by the Free Software
1.12 @@ -19,7 +19,7 @@
1.13 this program. If not, see <http://www.gnu.org/licenses/>.
1.14 """
1.15
1.16 -from common import first
1.17 +from common import first, InstructionSequence
1.18
1.19 # Output encoding and decoding for the summary files.
1.20
1.21 @@ -256,7 +256,18 @@
1.22
1.23 if subs.has_key(op):
1.24 substituted.add(op)
1.25 +
1.26 + # Break accessor initialisation into initialisation and value-yielding
1.27 + # parts:
1.28 +
1.29 + if op == "<set_accessor>" and isinstance(a[0], InstructionSequence):
1.30 + ops = []
1.31 + ops += a[0].get_init_instructions()
1.32 + ops.append("%s(%s)" % (subs[op], a[0].get_value_instruction()))
1.33 + return ", ".join(map(str, ops)), substituted
1.34 +
1.35 op = subs[op]
1.36 +
1.37 elif not args:
1.38 op = "&%s" % encode_path(op)
1.39
2.1 --- a/translator.py Sun Jan 22 01:13:31 2017 +0100
2.2 +++ b/translator.py Sun Jan 22 01:16:01 2017 +0100
2.3 @@ -214,6 +214,30 @@
2.4 def __repr__(self):
2.5 return "AttrResult(%r, %r, %r)" % (self.instructions, self.refs, self.accessor_kinds)
2.6
2.7 +class InvocationResult(Expression, TranslationResult, InstructionSequence):
2.8 +
2.9 + "A translation result for an invocation."
2.10 +
2.11 + def __init__(self, instructions):
2.12 + InstructionSequence.__init__(self, instructions)
2.13 +
2.14 + def __str__(self):
2.15 + return encode_instructions(self.instructions)
2.16 +
2.17 + def __repr__(self):
2.18 + return "InvocationResult(%r)" % self.instructions
2.19 +
2.20 +class InstantiationResult(InvocationResult, TrInstanceRef):
2.21 +
2.22 + "An instantiation result acting like an invocation result."
2.23 +
2.24 + def __init__(self, ref, instructions):
2.25 + results.InstanceRef.__init__(self, ref)
2.26 + InvocationResult.__init__(self, instructions)
2.27 +
2.28 + def __repr__(self):
2.29 + return "InstantiationResult(%r, %r)" % (self.ref, self.instructions)
2.30 +
2.31 class PredefinedConstantRef(Expression, TranslationResult):
2.32
2.33 "A predefined constant reference."
2.34 @@ -1295,24 +1319,23 @@
2.35 # and thereby participate in a guaranteed evaluation order.
2.36
2.37 if target or function:
2.38 - output = "(\n%s(%s))" % (",\n".join(stages), argstr)
2.39 + stages[-1] += "(%s)" % argstr
2.40 + if instantiation:
2.41 + return InstantiationResult(instantiation, stages)
2.42 + else:
2.43 + return InvocationResult(stages)
2.44
2.45 # With unknown targets, the generic invocation function is applied to
2.46 # the callable and argument collections.
2.47
2.48 else:
2.49 self.record_temp("__tmp_targets")
2.50 - output = "(%s, __invoke(\n__tmp_targets[%d],\n%d, %d, %s, %s,\n%d, %s\n))" % (
2.51 - ",\n".join(stages),
2.52 + stages.append("__invoke(\n__tmp_targets[%d],\n%d, %d, %s, %s,\n%d, %s\n)" % (
2.53 self.function_target,
2.54 self.always_callable and 1 or 0,
2.55 len(kwargs), kwcodestr, kwargstr,
2.56 - len(args), argstr)
2.57 -
2.58 - if instantiation:
2.59 - return TrInstanceRef(instantiation, output)
2.60 - else:
2.61 - return make_expression(output)
2.62 + len(args), argstr))
2.63 + return InvocationResult(stages)
2.64
2.65 def always_callable(self, refs):
2.66