1.1 --- a/translator.py Sat Oct 29 20:18:39 2016 +0200
1.2 +++ b/translator.py Sat Oct 29 20:22:30 2016 +0200
1.3 @@ -81,11 +81,6 @@
1.4
1.5 "Return an output representation of the referenced name."
1.6
1.7 - # Use any alias in preference to the origin of the name.
1.8 -
1.9 - name = self.get_name()
1.10 -
1.11 - # Use any static origin in preference to any alias.
1.12 # For sources, any identified static origin will be constant and thus
1.13 # usable directly. For targets, no constant should be assigned and thus
1.14 # the alias (or any plain name) will be used.
1.15 @@ -93,7 +88,12 @@
1.16 ref = self.static()
1.17 origin = ref and self.get_origin()
1.18 static_name = origin and encode_path(origin)
1.19 - dynamic_name = name and encode_path(name) or encode_path(self.name)
1.20 +
1.21 + # Determine whether a qualified name is involved.
1.22 +
1.23 + t = (self.expr and self.get_name() or self.name).rsplit(".", 1)
1.24 + parent = len(t) > 1 and t[0] or None
1.25 + attrname = encode_path(t[-1])
1.26
1.27 # Assignments.
1.28
1.29 @@ -103,8 +103,17 @@
1.30
1.31 if self.static() and isinstance(self.expr, results.ResolvedNameRef) and self.expr.static():
1.32 return ""
1.33 +
1.34 + # Qualified names must be converted into parent-relative assignments.
1.35 +
1.36 + elif parent:
1.37 + return "__store_via_object(&%s, %s, %s)" % (
1.38 + encode_path(parent), encode_symbol("pos", attrname), self.expr)
1.39 +
1.40 + # All other assignments involve the names as they were given.
1.41 +
1.42 else:
1.43 - return "%s = %s" % (dynamic_name, self.expr)
1.44 + return "%s = %s" % (attrname, self.expr)
1.45
1.46 # Expressions.
1.47
1.48 @@ -114,7 +123,7 @@
1.49 return "((__attr) {%s, &%s})" % (context and "&%s" % context or "0", static_name)
1.50
1.51 else:
1.52 - return dynamic_name
1.53 + return attrname
1.54
1.55 class TrConstantValueRef(results.ConstantValueRef, TranslationResult):
1.56
1.57 @@ -721,7 +730,7 @@
1.58
1.59 # Obtain details of the defaults.
1.60
1.61 - defaults = self.process_function_defaults(n, name, self.get_object_path(name))
1.62 + defaults = self.process_function_defaults(n, name, "&%s" % self.get_object_path(name))
1.63 if defaults:
1.64 for default in defaults:
1.65 self.writeline("%s;" % default)
1.66 @@ -776,7 +785,7 @@
1.67 continue
1.68
1.69 if name_ref:
1.70 - defaults.append("__SETDEFAULT(&%s, %s, %s)" % (encode_path(instance_name), i, name_ref))
1.71 + defaults.append("__SETDEFAULT(%s, %s, %s)" % (encode_path(instance_name), i, name_ref))
1.72
1.73 return defaults
1.74
1.75 @@ -818,8 +827,10 @@
1.76 parameters = self.importer.function_parameters.get(objpath)
1.77 if expr.has_kind("<class>"):
1.78 target = encode_instantiator_pointer(objpath)
1.79 + target_structure = encode_initialiser_pointer(objpath)
1.80 elif expr.has_kind("<function>"):
1.81 target = encode_function_pointer(objpath)
1.82 + target_structure = encode_path(objpath)
1.83 else:
1.84 parameters = None
1.85
1.86 @@ -871,11 +882,15 @@
1.87 if function_defaults:
1.88
1.89 # Visit each default and set any missing arguments.
1.90 + # Use the target structure to obtain defaults, as opposed to the
1.91 + # actual function involved.
1.92
1.93 for i, (argname, default) in enumerate(function_defaults):
1.94 argnum = parameters.index(argname)
1.95 if not args[argnum+1]:
1.96 - args[argnum+1] = "__GETDEFAULT(%s, %d)" % (target, i)
1.97 + args[argnum+1] = "__GETDEFAULT(&%s, %d)" % (target_structure, i)
1.98 +
1.99 + # Encode the arguments.
1.100
1.101 argstr = "__ARGS(%s)" % ", ".join(args)
1.102 kwargstr = kwargs and ("__ARGS(%s)" % ", ".join(kwargs)) or "0"
1.103 @@ -941,9 +956,16 @@
1.104 name = self.get_lambda_name()
1.105 function_name = self.get_object_path(name)
1.106
1.107 - defaults = self.process_function_defaults(n, name, "__tmp")
1.108 + defaults = self.process_function_defaults(n, name, "__tmp_result")
1.109 +
1.110 + # Without defaults, produce an attribute referring to the function.
1.111 +
1.112 if not defaults:
1.113 - return make_expression(encode_path(function_name))
1.114 + return make_expression("((__attr) {0, &%s})" % encode_path(function_name))
1.115 +
1.116 + # With defaults, copy the function structure and set the defaults on the
1.117 + # copy.
1.118 +
1.119 else:
1.120 return make_expression("(__COPY(%s, __tmp), %s)" % (encode_path(function_name), ", ".join(defaults)))
1.121
1.122 @@ -1026,11 +1048,9 @@
1.123
1.124 "Process the given operator node 'n'."
1.125
1.126 - # NOTE: This needs to evaluate whether the operand is true or false
1.127 - # NOTE: according to Python rules.
1.128 -
1.129 return make_expression("(__BOOL(%s) ? %s : %s)" %
1.130 - (n.expr, PredefinedConstantRef("False"), PredefinedConstantRef("True")))
1.131 + (self.process_structure_node(n.expr), PredefinedConstantRef("False"),
1.132 + PredefinedConstantRef("True")))
1.133
1.134 def process_raise_node(self, n):
1.135
1.136 @@ -1240,6 +1260,7 @@
1.137 print >>self.out, "void __main_%s()" % encode_path(self.name)
1.138 print >>self.out, "{"
1.139 self.indent += 1
1.140 + self.write_temporaries()
1.141
1.142 def end_module(self):
1.143 self.indent -= 1
1.144 @@ -1249,9 +1270,7 @@
1.145 print >>self.out, "__attr %s(__attr __args[])" % encode_function_pointer(name)
1.146 print >>self.out, "{"
1.147 self.indent += 1
1.148 - self.writeline("__ref __tmp_context, __tmp_value;")
1.149 - self.writeline("__attr __tmp_target, __tmp_result;")
1.150 - self.writeline("__exc __tmp_exc;")
1.151 + self.write_temporaries()
1.152
1.153 # Obtain local names from parameters.
1.154
1.155 @@ -1283,6 +1302,11 @@
1.156 print >>self.out, "}"
1.157 print >>self.out
1.158
1.159 + def write_temporaries(self):
1.160 + self.writeline("__ref __tmp_context, __tmp_value;")
1.161 + self.writeline("__attr __tmp_target, __tmp_result;")
1.162 + self.writeline("__exc __tmp_exc;")
1.163 +
1.164 def write_parameters(self, name, define=True):
1.165 parameters = self.importer.function_parameters[name]
1.166
1.167 @@ -1303,10 +1327,6 @@
1.168 self.writeline("#undef %s" % encode_path(parameter))
1.169
1.170 def start_if(self, first, test_ref):
1.171 -
1.172 - # NOTE: This needs to evaluate whether the operand is true or false
1.173 - # NOTE: according to Python rules.
1.174 -
1.175 self.writestmt("%sif (__BOOL(%s))" % (not first and "else " or "", test_ref))
1.176 self.writeline("{")
1.177 self.indent += 1