# HG changeset patch # User Paul Boddie # Date 1485044161 -3600 # Node ID 37ff992ea25a5e7d44e1d9c313926e8527ee4735 # Parent 72f139b61a165be6b31a423adf58ee981b3992df Exposed invocations as instruction sequences in order to rearrange instructions involving , attempting to avoid sequence point warnings when compiling the generated code. diff -r 72f139b61a16 -r 37ff992ea25a encoders.py --- a/encoders.py Sun Jan 22 01:13:31 2017 +0100 +++ b/encoders.py Sun Jan 22 01:16:01 2017 +0100 @@ -3,7 +3,7 @@ """ Encoder functions, producing representations of program objects. -Copyright (C) 2016 Paul Boddie +Copyright (C) 2016, 2017 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 @@ -19,7 +19,7 @@ this program. If not, see . """ -from common import first +from common import first, InstructionSequence # Output encoding and decoding for the summary files. @@ -256,7 +256,18 @@ if subs.has_key(op): substituted.add(op) + + # Break accessor initialisation into initialisation and value-yielding + # parts: + + if op == "" and isinstance(a[0], InstructionSequence): + ops = [] + ops += a[0].get_init_instructions() + ops.append("%s(%s)" % (subs[op], a[0].get_value_instruction())) + return ", ".join(map(str, ops)), substituted + op = subs[op] + elif not args: op = "&%s" % encode_path(op) diff -r 72f139b61a16 -r 37ff992ea25a translator.py --- a/translator.py Sun Jan 22 01:13:31 2017 +0100 +++ b/translator.py Sun Jan 22 01:16:01 2017 +0100 @@ -214,6 +214,30 @@ def __repr__(self): return "AttrResult(%r, %r, %r)" % (self.instructions, self.refs, self.accessor_kinds) +class InvocationResult(Expression, TranslationResult, InstructionSequence): + + "A translation result for an invocation." + + def __init__(self, instructions): + InstructionSequence.__init__(self, instructions) + + def __str__(self): + return encode_instructions(self.instructions) + + def __repr__(self): + return "InvocationResult(%r)" % self.instructions + +class InstantiationResult(InvocationResult, TrInstanceRef): + + "An instantiation result acting like an invocation result." + + def __init__(self, ref, instructions): + results.InstanceRef.__init__(self, ref) + InvocationResult.__init__(self, instructions) + + def __repr__(self): + return "InstantiationResult(%r, %r)" % (self.ref, self.instructions) + class PredefinedConstantRef(Expression, TranslationResult): "A predefined constant reference." @@ -1295,24 +1319,23 @@ # and thereby participate in a guaranteed evaluation order. if target or function: - output = "(\n%s(%s))" % (",\n".join(stages), argstr) + stages[-1] += "(%s)" % argstr + if instantiation: + return InstantiationResult(instantiation, stages) + else: + return InvocationResult(stages) # With unknown targets, the generic invocation function is applied to # the callable and argument collections. else: self.record_temp("__tmp_targets") - output = "(%s, __invoke(\n__tmp_targets[%d],\n%d, %d, %s, %s,\n%d, %s\n))" % ( - ",\n".join(stages), + stages.append("__invoke(\n__tmp_targets[%d],\n%d, %d, %s, %s,\n%d, %s\n)" % ( self.function_target, self.always_callable and 1 or 0, len(kwargs), kwcodestr, kwargstr, - len(args), argstr) - - if instantiation: - return TrInstanceRef(instantiation, output) - else: - return make_expression(output) + len(args), argstr)) + return InvocationResult(stages) def always_callable(self, refs):