1.1 --- a/translator.py Mon Feb 27 23:43:24 2017 +0100
1.2 +++ b/translator.py Tue Feb 28 00:00:09 2017 +0100
1.3 @@ -19,22 +19,26 @@
1.4 this program. If not, see <http://www.gnu.org/licenses/>.
1.5 """
1.6
1.7 -from common import CommonModule, CommonOutput, InstructionSequence, \
1.8 +from common import CommonModule, CommonOutput, \
1.9 first, get_builtin_class, init_item, is_newer, \
1.10 predefined_constants
1.11 from encoders import encode_access_instruction, encode_access_instruction_arg, \
1.12 - encode_function_pointer, encode_literal_constant, \
1.13 - encode_literal_instantiator, encode_instantiator_pointer, \
1.14 - encode_instructions, encode_path, \
1.15 - encode_symbol, encode_type_attribute, \
1.16 - is_type_attribute
1.17 + encode_function_pointer, encode_literal_instantiator, \
1.18 + encode_instantiator_pointer, encode_path, encode_symbol, \
1.19 + encode_type_attribute, is_type_attribute
1.20 from errors import InspectError, TranslateError
1.21 from os.path import exists, join
1.22 from os import makedirs
1.23 from referencing import Reference
1.24 +from results import Result
1.25 +from transresults import TrConstantValueRef, TrInstanceRef, \
1.26 + TrLiteralSequenceRef, TrResolvedNameRef, \
1.27 + AttrResult, Expression, InstantiationResult, \
1.28 + InvocationResult, LogicalOperationResult, \
1.29 + LogicalResult, NegationResult, PredefinedConstantRef, \
1.30 + ReturnRef
1.31 from StringIO import StringIO
1.32 import compiler
1.33 -import results
1.34 import sys
1.35
1.36 class Translator(CommonOutput):
1.37 @@ -76,310 +80,13 @@
1.38 tm = TranslatedModule(module.name, self.importer, self.deducer, self.optimiser)
1.39 tm.translate(module.filename, output_filename)
1.40
1.41 -# Classes representing intermediate translation results.
1.42 -
1.43 -class ReturnRef:
1.44 -
1.45 - "Indicates usage of a return statement."
1.46 -
1.47 - pass
1.48 -
1.49 -class Expression(results.Result):
1.50 -
1.51 - "A general expression."
1.52 -
1.53 - def __init__(self, s):
1.54 - self.s = s
1.55 - def __str__(self):
1.56 - return self.s
1.57 - def __repr__(self):
1.58 - return "Expression(%r)" % self.s
1.59 -
1.60 -class TrResolvedNameRef(results.ResolvedNameRef):
1.61 -
1.62 - "A reference to a name in the translation."
1.63 -
1.64 - def __init__(self, name, ref, expr=None, is_global=False, parameter=None, location=None):
1.65 - results.ResolvedNameRef.__init__(self, name, ref, expr, is_global)
1.66 - self.parameter = parameter
1.67 - self.location = location
1.68 -
1.69 - def access_location(self):
1.70 - return self.location
1.71 -
1.72 - def __str__(self):
1.73 -
1.74 - "Return an output representation of the referenced name."
1.75 -
1.76 - # For sources, any identified static origin will be constant and thus
1.77 - # usable directly. For targets, no constant should be assigned and thus
1.78 - # the alias (or any plain name) will be used.
1.79 -
1.80 - ref = self.static()
1.81 - origin = ref and self.get_origin()
1.82 - static_name = origin and encode_path(origin)
1.83 -
1.84 - # Determine whether a qualified name is involved.
1.85 -
1.86 - t = (not self.is_constant_alias() and self.get_name() or self.name).rsplit(".", 1)
1.87 - parent = len(t) > 1 and t[0] or None
1.88 - attrname = t[-1] and encode_path(t[-1])
1.89 -
1.90 - # Assignments.
1.91 -
1.92 - if self.expr:
1.93 -
1.94 - # Eliminate assignments between constants.
1.95 -
1.96 - if ref and isinstance(self.expr, results.ResolvedNameRef) and self.expr.static():
1.97 - return ""
1.98 -
1.99 - # Qualified names must be converted into parent-relative assignments.
1.100 -
1.101 - elif parent:
1.102 - return "__store_via_object(&%s, %s, %s)" % (
1.103 - encode_path(parent), attrname, self.expr)
1.104 -
1.105 - # All other assignments involve the names as they were given.
1.106 -
1.107 - else:
1.108 - return "(%s%s) = %s" % (self.parameter and "*" or "", attrname, self.expr)
1.109 -
1.110 - # Expressions.
1.111 -
1.112 - elif static_name:
1.113 - parent = ref.parent()
1.114 - context = ref.has_kind("<function>") and encode_path(parent) or None
1.115 - return "__ATTRVALUE(&%s)" % static_name
1.116 -
1.117 - # Qualified names must be converted into parent-relative accesses.
1.118 -
1.119 - elif parent:
1.120 - return "__load_via_object(&%s, %s)" % (
1.121 - encode_path(parent), attrname)
1.122 -
1.123 - # All other accesses involve the names as they were given.
1.124 -
1.125 - else:
1.126 - return "(%s%s)" % (self.parameter and "*" or "", attrname)
1.127 -
1.128 -class TrConstantValueRef(results.ConstantValueRef):
1.129 -
1.130 - "A constant value reference in the translation."
1.131 -
1.132 - def __str__(self):
1.133 - return encode_literal_constant(self.number)
1.134 -
1.135 -class TrLiteralSequenceRef(results.LiteralSequenceRef):
1.136 -
1.137 - "A reference representing a sequence of values."
1.138 -
1.139 - def __str__(self):
1.140 - return str(self.node)
1.141 -
1.142 -class TrInstanceRef(results.InstanceRef):
1.143 -
1.144 - "A reference representing instantiation of a class."
1.145 -
1.146 - def __init__(self, ref, expr):
1.147 -
1.148 - """
1.149 - Initialise the reference with 'ref' indicating the nature of the
1.150 - reference and 'expr' being an expression used to create the instance.
1.151 - """
1.152 -
1.153 - results.InstanceRef.__init__(self, ref)
1.154 - self.expr = expr
1.155 -
1.156 - def __str__(self):
1.157 - return self.expr
1.158 -
1.159 - def __repr__(self):
1.160 - return "TrResolvedInstanceRef(%r, %r)" % (self.ref, self.expr)
1.161 -
1.162 -class AttrResult(results.Result, InstructionSequence):
1.163 -
1.164 - "A translation result for an attribute access."
1.165 -
1.166 - def __init__(self, instructions, refs, location, context_identity):
1.167 - InstructionSequence.__init__(self, instructions)
1.168 - self.refs = refs
1.169 - self.location = location
1.170 - self.context_identity = context_identity
1.171 -
1.172 - def references(self):
1.173 - return self.refs
1.174 -
1.175 - def access_location(self):
1.176 - return self.location
1.177 -
1.178 - def context(self):
1.179 - return self.context_identity
1.180 -
1.181 - def get_origin(self):
1.182 - return self.refs and len(self.refs) == 1 and first(self.refs).get_origin()
1.183 -
1.184 - def has_kind(self, kinds):
1.185 - if not self.refs:
1.186 - return False
1.187 - for ref in self.refs:
1.188 - if ref.has_kind(kinds):
1.189 - return True
1.190 - return False
1.191 -
1.192 - def __nonzero__(self):
1.193 - return bool(self.instructions)
1.194 -
1.195 - def __str__(self):
1.196 - return encode_instructions(self.instructions)
1.197 -
1.198 - def __repr__(self):
1.199 - return "AttrResult(%r, %r, %r)" % (self.instructions, self.refs, self.location)
1.200 -
1.201 -class InvocationResult(results.Result, InstructionSequence):
1.202 -
1.203 - "A translation result for an invocation."
1.204 -
1.205 - def __str__(self):
1.206 - return encode_instructions(self.instructions)
1.207 -
1.208 - def __repr__(self):
1.209 - return "InvocationResult(%r)" % self.instructions
1.210 -
1.211 -class InstantiationResult(InvocationResult, TrInstanceRef):
1.212 -
1.213 - "An instantiation result acting like an invocation result."
1.214 -
1.215 - def __init__(self, ref, instructions):
1.216 - results.InstanceRef.__init__(self, ref)
1.217 - InvocationResult.__init__(self, instructions)
1.218 -
1.219 - def __repr__(self):
1.220 - return "InstantiationResult(%r, %r)" % (self.ref, self.instructions)
1.221 -
1.222 -class PredefinedConstantRef(results.Result):
1.223 -
1.224 - "A predefined constant reference."
1.225 -
1.226 - def __init__(self, value, expr=None):
1.227 - self.value = value
1.228 - self.expr = expr
1.229 -
1.230 - def __str__(self):
1.231 -
1.232 - # Eliminate predefined constant assignments.
1.233 -
1.234 - if self.expr:
1.235 - return ""
1.236 -
1.237 - # Generate the specific constants.
1.238 -
1.239 - if self.value in ("False", "True"):
1.240 - return encode_path("__builtins__.boolean.%s" % self.value)
1.241 - elif self.value == "None":
1.242 - return encode_path("__builtins__.none.%s" % self.value)
1.243 - elif self.value == "NotImplemented":
1.244 - return encode_path("__builtins__.notimplemented.%s" % self.value)
1.245 - else:
1.246 - return self.value
1.247 -
1.248 - def __repr__(self):
1.249 - return "PredefinedConstantRef(%r)" % self.value
1.250 -
1.251 -class LogicalResult(results.Result):
1.252 -
1.253 - "A logical expression result."
1.254 -
1.255 - def _convert(self, expr):
1.256 -
1.257 - "Return 'expr' converted to a testable value."
1.258 -
1.259 - if isinstance(expr, LogicalResult):
1.260 - return expr.apply_test()
1.261 - else:
1.262 - return "__BOOL(%s)" % expr
1.263 -
1.264 -class NegationResult(LogicalResult):
1.265 -
1.266 - "A negation expression result."
1.267 -
1.268 - def __init__(self, expr):
1.269 - self.expr = expr
1.270 -
1.271 - def apply_test(self):
1.272 -
1.273 - "Return the result in a form suitable for direct testing."
1.274 -
1.275 - expr = self._convert(self.expr)
1.276 - return "(!%s)" % expr
1.277 -
1.278 - def __str__(self):
1.279 - return "(%s ? %s : %s)" % (
1.280 - self._convert(self.expr),
1.281 - PredefinedConstantRef("False"),
1.282 - PredefinedConstantRef("True"))
1.283 -
1.284 - def __repr__(self):
1.285 - return "NegationResult(%r)" % self.expr
1.286 -
1.287 -class LogicalOperationResult(LogicalResult):
1.288 -
1.289 - "A logical operation result."
1.290 -
1.291 - def __init__(self, exprs, conjunction):
1.292 - self.exprs = exprs
1.293 - self.conjunction = conjunction
1.294 -
1.295 - def apply_test(self):
1.296 -
1.297 - """
1.298 - Return the result in a form suitable for direct testing.
1.299 -
1.300 - Convert ... to ...
1.301 -
1.302 - <a> and <b>
1.303 - ((__BOOL(<a>)) && (__BOOL(<b>)))
1.304 -
1.305 - <a> or <b>
1.306 - ((__BOOL(<a>)) || (__BOOL(<b>)))
1.307 - """
1.308 -
1.309 - results = []
1.310 - for expr in self.exprs:
1.311 - results.append(self._convert(expr))
1.312 -
1.313 - if self.conjunction:
1.314 - return "(%s)" % " && ".join(results)
1.315 - else:
1.316 - return "(%s)" % " || ".join(results)
1.317 -
1.318 - def __str__(self):
1.319 -
1.320 - """
1.321 - Convert ... to ...
1.322 -
1.323 - <a> and <b>
1.324 - (__tmp_result = <a>, !__BOOL(__tmp_result)) ? __tmp_result : <b>
1.325 -
1.326 - <a> or <b>
1.327 - (__tmp_result = <a>, __BOOL(__tmp_result)) ? __tmp_result : <b>
1.328 - """
1.329 -
1.330 - results = []
1.331 - for expr in self.exprs[:-1]:
1.332 - results.append("(__tmp_result = %s, %s__BOOL(__tmp_result)) ? __tmp_result : " % (expr, self.conjunction and "!" or ""))
1.333 - results.append(str(self.exprs[-1]))
1.334 -
1.335 - return "(%s)" % "".join(results)
1.336 -
1.337 - def __repr__(self):
1.338 - return "LogicalOperationResult(%r, %r)" % (self.exprs, self.conjunction)
1.339 +
1.340
1.341 def make_expression(expr):
1.342
1.343 "Make a new expression from the existing 'expr'."
1.344
1.345 - if isinstance(expr, results.Result):
1.346 + if isinstance(expr, Result):
1.347 return expr
1.348 else:
1.349 return Expression(str(expr))
1.350 @@ -616,7 +323,7 @@
1.351
1.352 # Handle processing requests on results.
1.353
1.354 - if isinstance(node, results.Result):
1.355 + if isinstance(node, Result):
1.356 return node
1.357
1.358 # Handle processing requests on nodes.