2.1 --- a/translator.py Sat Oct 29 20:18:39 2016 +0200
2.2 +++ b/translator.py Sat Oct 29 20:22:30 2016 +0200
2.3 @@ -81,11 +81,6 @@
2.4
2.5 "Return an output representation of the referenced name."
2.6
2.7 - # Use any alias in preference to the origin of the name.
2.8 -
2.9 - name = self.get_name()
2.10 -
2.11 - # Use any static origin in preference to any alias.
2.12 # For sources, any identified static origin will be constant and thus
2.13 # usable directly. For targets, no constant should be assigned and thus
2.14 # the alias (or any plain name) will be used.
2.15 @@ -93,7 +88,12 @@
2.16 ref = self.static()
2.17 origin = ref and self.get_origin()
2.18 static_name = origin and encode_path(origin)
2.19 - dynamic_name = name and encode_path(name) or encode_path(self.name)
2.20 +
2.21 + # Determine whether a qualified name is involved.
2.22 +
2.23 + t = (self.expr and self.get_name() or self.name).rsplit(".", 1)
2.24 + parent = len(t) > 1 and t[0] or None
2.25 + attrname = encode_path(t[-1])
2.26
2.27 # Assignments.
2.28
2.29 @@ -103,8 +103,17 @@
2.30
2.31 if self.static() and isinstance(self.expr, results.ResolvedNameRef) and self.expr.static():
2.32 return ""
2.33 +
2.34 + # Qualified names must be converted into parent-relative assignments.
2.35 +
2.36 + elif parent:
2.37 + return "__store_via_object(&%s, %s, %s)" % (
2.38 + encode_path(parent), encode_symbol("pos", attrname), self.expr)
2.39 +
2.40 + # All other assignments involve the names as they were given.
2.41 +
2.42 else:
2.43 - return "%s = %s" % (dynamic_name, self.expr)
2.44 + return "%s = %s" % (attrname, self.expr)
2.45
2.46 # Expressions.
2.47
2.48 @@ -114,7 +123,7 @@
2.49 return "((__attr) {%s, &%s})" % (context and "&%s" % context or "0", static_name)
2.50
2.51 else:
2.52 - return dynamic_name
2.53 + return attrname
2.54
2.55 class TrConstantValueRef(results.ConstantValueRef, TranslationResult):
2.56
2.57 @@ -721,7 +730,7 @@
2.58
2.59 # Obtain details of the defaults.
2.60
2.61 - defaults = self.process_function_defaults(n, name, self.get_object_path(name))
2.62 + defaults = self.process_function_defaults(n, name, "&%s" % self.get_object_path(name))
2.63 if defaults:
2.64 for default in defaults:
2.65 self.writeline("%s;" % default)
2.66 @@ -776,7 +785,7 @@
2.67 continue
2.68
2.69 if name_ref:
2.70 - defaults.append("__SETDEFAULT(&%s, %s, %s)" % (encode_path(instance_name), i, name_ref))
2.71 + defaults.append("__SETDEFAULT(%s, %s, %s)" % (encode_path(instance_name), i, name_ref))
2.72
2.73 return defaults
2.74
2.75 @@ -818,8 +827,10 @@
2.76 parameters = self.importer.function_parameters.get(objpath)
2.77 if expr.has_kind("<class>"):
2.78 target = encode_instantiator_pointer(objpath)
2.79 + target_structure = encode_initialiser_pointer(objpath)
2.80 elif expr.has_kind("<function>"):
2.81 target = encode_function_pointer(objpath)
2.82 + target_structure = encode_path(objpath)
2.83 else:
2.84 parameters = None
2.85
2.86 @@ -871,11 +882,15 @@
2.87 if function_defaults:
2.88
2.89 # Visit each default and set any missing arguments.
2.90 + # Use the target structure to obtain defaults, as opposed to the
2.91 + # actual function involved.
2.92
2.93 for i, (argname, default) in enumerate(function_defaults):
2.94 argnum = parameters.index(argname)
2.95 if not args[argnum+1]:
2.96 - args[argnum+1] = "__GETDEFAULT(%s, %d)" % (target, i)
2.97 + args[argnum+1] = "__GETDEFAULT(&%s, %d)" % (target_structure, i)
2.98 +
2.99 + # Encode the arguments.
2.100
2.101 argstr = "__ARGS(%s)" % ", ".join(args)
2.102 kwargstr = kwargs and ("__ARGS(%s)" % ", ".join(kwargs)) or "0"
2.103 @@ -941,9 +956,16 @@
2.104 name = self.get_lambda_name()
2.105 function_name = self.get_object_path(name)
2.106
2.107 - defaults = self.process_function_defaults(n, name, "__tmp")
2.108 + defaults = self.process_function_defaults(n, name, "__tmp_result")
2.109 +
2.110 + # Without defaults, produce an attribute referring to the function.
2.111 +
2.112 if not defaults:
2.113 - return make_expression(encode_path(function_name))
2.114 + return make_expression("((__attr) {0, &%s})" % encode_path(function_name))
2.115 +
2.116 + # With defaults, copy the function structure and set the defaults on the
2.117 + # copy.
2.118 +
2.119 else:
2.120 return make_expression("(__COPY(%s, __tmp), %s)" % (encode_path(function_name), ", ".join(defaults)))
2.121
2.122 @@ -1026,11 +1048,9 @@
2.123
2.124 "Process the given operator node 'n'."
2.125
2.126 - # NOTE: This needs to evaluate whether the operand is true or false
2.127 - # NOTE: according to Python rules.
2.128 -
2.129 return make_expression("(__BOOL(%s) ? %s : %s)" %
2.130 - (n.expr, PredefinedConstantRef("False"), PredefinedConstantRef("True")))
2.131 + (self.process_structure_node(n.expr), PredefinedConstantRef("False"),
2.132 + PredefinedConstantRef("True")))
2.133
2.134 def process_raise_node(self, n):
2.135
2.136 @@ -1240,6 +1260,7 @@
2.137 print >>self.out, "void __main_%s()" % encode_path(self.name)
2.138 print >>self.out, "{"
2.139 self.indent += 1
2.140 + self.write_temporaries()
2.141
2.142 def end_module(self):
2.143 self.indent -= 1
2.144 @@ -1249,9 +1270,7 @@
2.145 print >>self.out, "__attr %s(__attr __args[])" % encode_function_pointer(name)
2.146 print >>self.out, "{"
2.147 self.indent += 1
2.148 - self.writeline("__ref __tmp_context, __tmp_value;")
2.149 - self.writeline("__attr __tmp_target, __tmp_result;")
2.150 - self.writeline("__exc __tmp_exc;")
2.151 + self.write_temporaries()
2.152
2.153 # Obtain local names from parameters.
2.154
2.155 @@ -1283,6 +1302,11 @@
2.156 print >>self.out, "}"
2.157 print >>self.out
2.158
2.159 + def write_temporaries(self):
2.160 + self.writeline("__ref __tmp_context, __tmp_value;")
2.161 + self.writeline("__attr __tmp_target, __tmp_result;")
2.162 + self.writeline("__exc __tmp_exc;")
2.163 +
2.164 def write_parameters(self, name, define=True):
2.165 parameters = self.importer.function_parameters[name]
2.166
2.167 @@ -1303,10 +1327,6 @@
2.168 self.writeline("#undef %s" % encode_path(parameter))
2.169
2.170 def start_if(self, first, test_ref):
2.171 -
2.172 - # NOTE: This needs to evaluate whether the operand is true or false
2.173 - # NOTE: according to Python rules.
2.174 -
2.175 self.writestmt("%sif (__BOOL(%s))" % (not first and "else " or "", test_ref))
2.176 self.writeline("{")
2.177 self.indent += 1