Lichen

Annotated results.py

95:a0f513d3a7b1
2016-10-13 Paul Boddie Fixed instruction plan test operations, optimised the initial accessor to avoid redundant assignments and to use the context where appropriate, introduced accessor and attribute name parameterisation in the generated instructions, introduced a generic expression placeholder in place of any local name.
paul@11 1
#!/usr/bin/env python
paul@11 2
paul@11 3
"""
paul@11 4
Result abstractions.
paul@11 5
paul@11 6
Copyright (C) 2016 Paul Boddie <paul@boddie.org.uk>
paul@11 7
paul@11 8
This program is free software; you can redistribute it and/or modify it under
paul@11 9
the terms of the GNU General Public License as published by the Free Software
paul@11 10
Foundation; either version 3 of the License, or (at your option) any later
paul@11 11
version.
paul@11 12
paul@11 13
This program is distributed in the hope that it will be useful, but WITHOUT
paul@11 14
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
paul@11 15
FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
paul@11 16
details.
paul@11 17
paul@11 18
You should have received a copy of the GNU General Public License along with
paul@11 19
this program.  If not, see <http://www.gnu.org/licenses/>.
paul@11 20
"""
paul@11 21
paul@27 22
from referencing import Reference
paul@27 23
paul@11 24
# Classes representing inspection and translation observations.
paul@11 25
paul@11 26
class Result:
paul@11 27
paul@11 28
    "An abstract expression result."
paul@11 29
paul@11 30
    def is_name(self):
paul@11 31
        return False
paul@11 32
    def get_origin(self):
paul@11 33
        return None
paul@11 34
paul@11 35
class AccessRef(Result):
paul@11 36
paul@11 37
    """
paul@11 38
    A reference to an attribute access that is generally only returned from a
paul@11 39
    processed access for possible initialiser resolution for assignments.
paul@11 40
    """
paul@11 41
paul@11 42
    def __init__(self, original_name, attrnames, number):
paul@11 43
        self.original_name = original_name
paul@11 44
        self.attrnames = attrnames
paul@11 45
        self.number = number
paul@11 46
paul@11 47
    def reference(self):
paul@11 48
        return None
paul@11 49
paul@11 50
    def __repr__(self):
paul@11 51
        return "AccessRef(%r, %r, %r)" % (self.original_name, self.attrnames, self.number)
paul@11 52
paul@11 53
class InvocationRef(Result):
paul@11 54
paul@11 55
    "An invocation of a name reference."
paul@11 56
paul@11 57
    def __init__(self, name_ref):
paul@11 58
        self.name_ref = name_ref
paul@11 59
paul@27 60
    def reference(self):
paul@27 61
        origin = self.name_ref.get_origin()
paul@27 62
        if origin:
paul@27 63
            return Reference("<invoke>", origin)
paul@27 64
        else:
paul@27 65
            return Reference("<var>")
paul@27 66
paul@11 67
    def __repr__(self):
paul@11 68
        return "InvocationRef(%r)" % self.name_ref
paul@11 69
paul@11 70
class NameRef(Result):
paul@11 71
paul@11 72
    "A reference to a name."
paul@11 73
paul@11 74
    def __init__(self, name, expr=None):
paul@11 75
        self.name = name
paul@11 76
        self.expr = expr
paul@11 77
paul@11 78
    def is_name(self):
paul@11 79
        return True
paul@11 80
paul@11 81
    def reference(self):
paul@11 82
        return None
paul@11 83
paul@11 84
    def final(self):
paul@11 85
        return None
paul@11 86
paul@11 87
    def __repr__(self):
paul@11 88
        return "NameRef(%r, %r)" % (self.name, self.expr)
paul@11 89
paul@11 90
class LocalNameRef(NameRef):
paul@11 91
paul@11 92
    "A reference to a local name."
paul@11 93
paul@11 94
    def __init__(self, name, number):
paul@11 95
        NameRef.__init__(self, name)
paul@11 96
        self.number = number
paul@11 97
paul@11 98
    def __repr__(self):
paul@11 99
        return "LocalNameRef(%r, %r)" % (self.name, self.number)
paul@11 100
paul@11 101
class ResolvedNameRef(NameRef):
paul@11 102
paul@11 103
    "A resolved name-based reference."
paul@11 104
paul@11 105
    def __init__(self, name, ref, expr=None):
paul@11 106
        NameRef.__init__(self, name, expr)
paul@11 107
        self.ref = ref
paul@11 108
paul@11 109
    def reference(self):
paul@11 110
        return self.ref
paul@11 111
paul@11 112
    def get_name(self):
paul@11 113
        return self.ref and self.ref.get_name() or None
paul@11 114
paul@11 115
    def get_origin(self):
paul@11 116
        return self.ref and self.ref.get_origin() or None
paul@11 117
paul@11 118
    def static(self):
paul@11 119
        return self.ref and self.ref.static() or None
paul@11 120
paul@11 121
    def final(self):
paul@11 122
        return self.ref and self.ref.final() or None
paul@11 123
paul@11 124
    def has_kind(self, kinds):
paul@11 125
        return self.ref and self.ref.has_kind(kinds)
paul@11 126
paul@11 127
    def __repr__(self):
paul@11 128
        return "ResolvedNameRef(%r, %r, %r)" % (self.name, self.ref, self.expr)
paul@11 129
paul@11 130
class ConstantValueRef(ResolvedNameRef):
paul@11 131
paul@11 132
    "A constant reference representing a single literal value."
paul@11 133
paul@11 134
    def __init__(self, name, ref, value, number=None):
paul@11 135
        ResolvedNameRef.__init__(self, name, ref)
paul@11 136
        self.value = value
paul@11 137
        self.number = number
paul@11 138
paul@11 139
    def __repr__(self):
paul@11 140
        return "ConstantValueRef(%r, %r, %r, %r)" % (self.name, self.ref, self.value, self.number)
paul@11 141
paul@11 142
class InstanceRef(Result):
paul@11 143
paul@11 144
    "An instance reference."
paul@11 145
paul@11 146
    def __init__(self, ref):
paul@11 147
        self.ref = ref
paul@11 148
paul@11 149
    def reference(self):
paul@11 150
        return self.ref
paul@11 151
paul@11 152
    def __repr__(self):
paul@11 153
        return "InstanceRef(%r)" % self.ref
paul@11 154
paul@11 155
class LiteralSequenceRef(ResolvedNameRef):
paul@11 156
paul@11 157
    "A reference representing a sequence of values."
paul@11 158
paul@11 159
    def __init__(self, name, ref, node, items=None):
paul@11 160
        ResolvedNameRef.__init__(self, name, ref)
paul@11 161
        self.node = node
paul@11 162
        self.items = items
paul@11 163
paul@11 164
    def __repr__(self):
paul@11 165
        return "LiteralSequenceRef(%r, %r, %r, %r)" % (self.name, self.ref, self.node, self.items)
paul@11 166
paul@11 167
# vim: tabstop=4 expandtab shiftwidth=4