# HG changeset patch # User Paul Boddie # Date 1485033064 -3600 # Node ID de5b7fb29457eceb2763d7457b25d61b22c62ffd # Parent 5a82b12d3f7b4ddaf847adc7c5c921651a3d1ac3 Exposed result objects to the attribute access instruction encoding mechanism. diff -r 5a82b12d3f7b -r de5b7fb29457 common.py --- a/common.py Sat Jan 21 18:22:20 2017 +0100 +++ b/common.py Sat Jan 21 22:11:04 2017 +0100 @@ -795,6 +795,21 @@ l.append(arg) return l +# Result classes. + +class InstructionSequence: + + "A generic sequence of instructions." + + def __init__(self, instructions): + self.instructions = instructions + + def get_value_instruction(self): + return self.instructions[-1] + + def get_init_instructions(self): + return self.instructions[:-1] + # Dictionary utilities. def init_item(d, key, fn): diff -r 5a82b12d3f7b -r de5b7fb29457 encoders.py --- a/encoders.py Sat Jan 21 18:22:20 2017 +0100 +++ b/encoders.py Sat Jan 21 22:11:04 2017 +0100 @@ -249,7 +249,7 @@ a[0] = "&%s" % a[0] a[1] = "&%s" % a[1] - argstr = "(%s)" % ", ".join(a) + argstr = "(%s)" % ", ".join(map(str, a)) # Substitute the first element of the instruction, which may not be an # operation at all. @@ -319,6 +319,15 @@ return "__new_%s" % encode_path(path) +def encode_instructions(instructions): + + "Encode 'instructions' as a sequence." + + if len(instructions) == 1: + return instructions[0] + else: + return "(\n%s\n)" % ",\n".join(instructions) + def encode_literal_constant(n): "Encode a name for the literal constant with the number 'n'." diff -r 5a82b12d3f7b -r de5b7fb29457 translator.py --- a/translator.py Sat Jan 21 18:22:20 2017 +0100 +++ b/translator.py Sat Jan 21 22:11:04 2017 +0100 @@ -19,11 +19,13 @@ this program. If not, see . """ -from common import CommonModule, CommonOutput, first, get_builtin_module, \ - get_builtin_type, init_item, predefined_constants +from common import CommonModule, CommonOutput, InstructionSequence, \ + first, get_builtin_module, get_builtin_type, init_item, \ + predefined_constants from encoders import encode_access_instruction, encode_bound_reference, \ encode_function_pointer, encode_literal_constant, \ encode_literal_instantiator, encode_instantiator_pointer, \ + encode_instructions, \ encode_path, encode_symbol, encode_type_attribute, \ is_type_attribute from os.path import exists, join @@ -183,12 +185,12 @@ def __repr__(self): return "TrResolvedInstanceRef(%r, %r)" % (self.ref, self.expr) -class AttrResult(Expression, TranslationResult): +class AttrResult(Expression, TranslationResult, InstructionSequence): "A translation result for an attribute access." - def __init__(self, s, refs, accessor_kinds): - Expression.__init__(self, s) + def __init__(self, instructions, refs, accessor_kinds): + InstructionSequence.__init__(self, instructions) self.refs = refs self.accessor_kinds = accessor_kinds @@ -206,10 +208,13 @@ def get_accessor_kinds(self): return self.accessor_kinds + def __str__(self): + return encode_instructions(self.instructions) + def __repr__(self): - return "AttrResult(%r, %r, %r)" % (self.s, self.refs, self.accessor_kinds) - -class PredefinedConstantRef(AttrResult): + return "AttrResult(%r, %r, %r)" % (self.instructions, self.refs, self.accessor_kinds) + +class PredefinedConstantRef(Expression, TranslationResult): "A predefined constant reference." @@ -701,8 +706,8 @@ # Generate access instructions. subs = { - "" : str(attr_expr), - "" : str(self.in_assignment), + "" : attr_expr, + "" : self.in_assignment, } temp_subs = { @@ -738,15 +743,8 @@ if temp_subs.has_key(sub): self.record_temp(temp_subs[sub]) - # Format the output. - - if len(output) == 1: - out = output[0] - else: - out = "(\n%s\n)" % ",\n".join(output) - del self.attrs[0] - return AttrResult(out, refs, self.get_accessor_kinds(location)) + return AttrResult(output, refs, self.get_accessor_kinds(location)) def get_referenced_attributes(self, location):