1.1 --- a/transresults.py Sun Nov 07 01:18:51 2021 +0100
1.2 +++ b/transresults.py Mon Nov 08 00:25:46 2021 +0100
1.3 @@ -59,6 +59,12 @@
1.4 def __repr__(self):
1.5 return "Expression(%r)" % self.s
1.6
1.7 + def as_arg(self):
1.8 +
1.9 + "Return the expression without any mutable tag."
1.10 +
1.11 + return "__TO_IMMUTABLE(%s)" % self.s
1.12 +
1.13 class TrResolvedNameRef(ResolvedNameRef):
1.14
1.15 "A reference to a name in the translation."
1.16 @@ -67,6 +73,20 @@
1.17 ResolvedNameRef.__init__(self, name, ref, expr, is_global)
1.18 self.location = location
1.19
1.20 + # For sources, any identified static origin will be constant and thus
1.21 + # usable directly. For targets, no constant should be assigned and thus
1.22 + # the alias (or any plain name) will be used.
1.23 +
1.24 + self.static_ref = self.static()
1.25 + origin = self.static_ref and self.get_origin()
1.26 + self.static_name = origin and encode_path(origin)
1.27 +
1.28 + # Determine whether a qualified name is involved.
1.29 +
1.30 + t = (not self.is_constant_alias() and self.get_name() or self.name).rsplit(".", 1)
1.31 + self.parent = len(t) > 1 and t[0] or None
1.32 + self.attrname = t[-1] and encode_path(t[-1])
1.33 +
1.34 def access_location(self):
1.35 return self.location
1.36
1.37 @@ -82,55 +102,56 @@
1.38 else:
1.39 return encode_path(self.name)
1.40
1.41 - # For sources, any identified static origin will be constant and thus
1.42 - # usable directly. For targets, no constant should be assigned and thus
1.43 - # the alias (or any plain name) will be used.
1.44 -
1.45 - ref = self.static()
1.46 - origin = ref and self.get_origin()
1.47 - static_name = origin and encode_path(origin)
1.48 -
1.49 - # Determine whether a qualified name is involved.
1.50 -
1.51 - t = (not self.is_constant_alias() and self.get_name() or self.name).rsplit(".", 1)
1.52 - parent = len(t) > 1 and t[0] or None
1.53 - attrname = t[-1] and encode_path(t[-1])
1.54 -
1.55 # Assignments.
1.56
1.57 if self.expr:
1.58
1.59 # Eliminate assignments between constants.
1.60
1.61 - if ref and self.expr.static():
1.62 + if self.static_ref and self.expr.static():
1.63 return ""
1.64
1.65 # Qualified names must be converted into parent-relative assignments.
1.66
1.67 - elif parent:
1.68 + elif self.parent:
1.69 return "__store_via_object(&%s, %s, %s)" % (
1.70 - encode_path(parent), attrname, self.expr)
1.71 + encode_path(self.parent), self.attrname, self.expr)
1.72
1.73 # All other assignments involve the names as they were given.
1.74
1.75 else:
1.76 - return "%s = %s" % (attrname, self.expr)
1.77 + return "%s = %s" % (self.attrname, self.expr)
1.78
1.79 # Expressions.
1.80
1.81 - elif static_name:
1.82 - return "__ATTRVALUE(&%s)" % static_name
1.83 + elif self.static_name:
1.84 + return "__ATTRVALUE(&%s)" % self.static_name
1.85
1.86 # Qualified names must be converted into parent-relative accesses.
1.87
1.88 - elif parent:
1.89 + elif self.parent:
1.90 return "__load_via_object(&%s, %s)" % (
1.91 - encode_path(parent), attrname)
1.92 + encode_path(self.parent), self.attrname)
1.93
1.94 # All other accesses involve the names as they were given.
1.95
1.96 else:
1.97 - return "(%s)" % attrname
1.98 + return "(%s)" % self.attrname
1.99 +
1.100 + def as_arg(self):
1.101 +
1.102 + "Return the expression without any mutable tag."
1.103 +
1.104 + s = self.__str__()
1.105 +
1.106 + # NOTE: This is a superficial test for internal attributes that relies
1.107 + # NOTE: on such attributes being used directly and passed to native
1.108 + # NOTE: code.
1.109 +
1.110 + if self.attrname in ("__data__", "__size__"):
1.111 + return s
1.112 + else:
1.113 + return "__TO_IMMUTABLE(%s)" % s
1.114
1.115 class TrConstantValueRef(ConstantValueRef):
1.116
1.117 @@ -139,6 +160,9 @@
1.118 def __str__(self):
1.119 return encode_literal_constant(self.number)
1.120
1.121 + def as_arg(self):
1.122 + return self.__str__()
1.123 +
1.124 class TrLiteralSequenceRef(LiteralSequenceRef):
1.125
1.126 "A reference representing a sequence of values."
1.127 @@ -146,6 +170,9 @@
1.128 def __str__(self):
1.129 return str(self.node)
1.130
1.131 + def as_arg(self):
1.132 + return self.__str__()
1.133 +
1.134 class TrInstanceRef(InstanceRef):
1.135
1.136 "A reference representing instantiation of a class."
1.137 @@ -166,6 +193,9 @@
1.138 def __repr__(self):
1.139 return "TrResolvedInstanceRef(%r, %r)" % (self.ref, self.expr)
1.140
1.141 + def as_arg(self):
1.142 + return self.__str__()
1.143 +
1.144 class AttrResult(Result, InstructionSequence):
1.145
1.146 "A translation result for an attribute access."
1.147 @@ -222,6 +252,9 @@
1.148 self.context_identity, self.context_identity_verified,
1.149 self.accessor_test, self.accessor_stored)
1.150
1.151 + def as_arg(self):
1.152 + return self.__str__()
1.153 +
1.154 class AliasResult(NameRef, Result):
1.155
1.156 "An alias for other values."
1.157 @@ -275,6 +308,9 @@
1.158 def __repr__(self):
1.159 return "AliasResult(%r, %r)" % (self.name_ref, self.refs)
1.160
1.161 + def as_arg(self):
1.162 + return self.__str__()
1.163 +
1.164 class InvocationResult(Result, InstructionSequence):
1.165
1.166 "A translation result for an invocation."
1.167 @@ -285,6 +321,9 @@
1.168 def __repr__(self):
1.169 return "InvocationResult(%r)" % self.instructions
1.170
1.171 + def as_arg(self):
1.172 + return self.__str__()
1.173 +
1.174 class InstantiationResult(InvocationResult, TrInstanceRef):
1.175
1.176 "An instantiation result acting like an invocation result."
1.177 @@ -325,6 +364,9 @@
1.178 def __repr__(self):
1.179 return "PredefinedConstantRef(%r)" % self.value
1.180
1.181 + def as_arg(self):
1.182 + return self.__str__()
1.183 +
1.184 class LogicalResult(Result):
1.185
1.186 "A logical expression result."
1.187 @@ -370,6 +412,9 @@
1.188 def __repr__(self):
1.189 return "NegationResult(%r)" % self.expr
1.190
1.191 + def as_arg(self):
1.192 + return self.__str__()
1.193 +
1.194 class LogicalOperationResult(LogicalResult):
1.195
1.196 "A logical operation result."
1.197 @@ -442,4 +487,7 @@
1.198 def __repr__(self):
1.199 return "LogicalOperationResult(%r, %r)" % (self.exprs, self.conjunction)
1.200
1.201 + def as_arg(self):
1.202 + return self.__str__()
1.203 +
1.204 # vim: tabstop=4 expandtab shiftwidth=4