1.1 --- a/translator.py Sat Nov 06 17:06:01 2021 +0100
1.2 +++ b/translator.py Sun Nov 07 01:18:51 2021 +0100
1.3 @@ -3,7 +3,7 @@
1.4 """
1.5 Translate programs.
1.6
1.7 -Copyright (C) 2015, 2016, 2017, 2018 Paul Boddie <paul@boddie.org.uk>
1.8 +Copyright (C) 2015-2018, 2021 Paul Boddie <paul@boddie.org.uk>
1.9
1.10 This program is free software; you can redistribute it and/or modify it under
1.11 the terms of the GNU General Public License as published by the Free Software
1.12 @@ -1281,8 +1281,8 @@
1.13 self.record_temp("__tmp_values")
1.14
1.15 # Arguments are presented in a temporary frame array with any context
1.16 - # always being the first argument. Where it would be unused, it may be
1.17 - # set to null.
1.18 + # always being the first argument after the value stack. Where the
1.19 + # context would be unused, it may be set to null.
1.20
1.21 if context_required:
1.22 if have_access_context:
1.23 @@ -1292,7 +1292,10 @@
1.24 else:
1.25 context_arg = "__NULL"
1.26
1.27 - args = [context_arg]
1.28 + # Introduce the value stack and any context.
1.29 +
1.30 + args = ["__stack", context_arg]
1.31 + reserved_args = 2
1.32
1.33 # Complete the array with null values, permitting tests for a complete
1.34 # set of arguments.
1.35 @@ -1337,7 +1340,7 @@
1.36 except ValueError:
1.37 raise TranslateError("Argument %s is not recognised." % arg.name,
1.38 self.get_namespace_path(), n)
1.39 - args[argnum+1] = str(argexpr)
1.40 + args[argnum + reserved_args] = str(argexpr)
1.41
1.42 # Otherwise, store the details in a separate collection.
1.43
1.44 @@ -1351,7 +1354,7 @@
1.45
1.46 else:
1.47 try:
1.48 - args[i+1] = str(argexpr)
1.49 + args[i + reserved_args] = str(argexpr)
1.50 except IndexError:
1.51 raise TranslateError("Too many arguments specified.",
1.52 self.get_namespace_path(), n)
1.53 @@ -1375,8 +1378,8 @@
1.54
1.55 for i, (argname, default) in enumerate(function_defaults):
1.56 argnum = parameters.index(argname)
1.57 - if not args[argnum+1]:
1.58 - args[argnum+1] = "__GETDEFAULT(%s, %d)" % (target_structure, i)
1.59 + if not args[argnum + reserved_args]:
1.60 + args[argnum + reserved_args] = "__GETDEFAULT(%s, %d)" % (target_structure, i)
1.61
1.62 elif known_parameters:
1.63
1.64 @@ -1387,7 +1390,7 @@
1.65 i = len(n.args)
1.66 pos = i - (num_parameters - num_defaults)
1.67 while i < num_parameters:
1.68 - args[i+1] = "__GETDEFAULT(%s.value, %d)" % (target_var, pos)
1.69 + args[i + reserved_args] = "__GETDEFAULT(%s.value, %d)" % (target_var, pos)
1.70 i += 1
1.71 pos += 1
1.72
1.73 @@ -1400,10 +1403,10 @@
1.74 # Encode the arguments.
1.75
1.76 # Where literal instantiation is occurring, add an argument indicating
1.77 - # the number of values. The context is excluded.
1.78 + # the number of values. The stack and context are excluded.
1.79
1.80 if literal_instantiation:
1.81 - argstr = "%d, %s" % (len(args) - 1, ", ".join(args[1:]))
1.82 + argstr = "%d, %s" % (len(args) - reserved_args, ", ".join(args[reserved_args:]))
1.83 else:
1.84 argstr = ", ".join(args)
1.85
1.86 @@ -1738,7 +1741,7 @@
1.87 if isinstance(exc, TrInstanceRef):
1.88 self.writestmt("__Raise(%s);" % exc)
1.89 else:
1.90 - self.writestmt("__Raise(__ensure_instance(%s));" % exc)
1.91 + self.writestmt("__Raise(__ensure_instance(__stack, %s));" % exc)
1.92 else:
1.93 self.writestmt("__Throw(__tmp_exc);")
1.94
1.95 @@ -2049,7 +2052,7 @@
1.96
1.97 "Write the start of each module's main function."
1.98
1.99 - print >>self.out, "void __main_%s()" % encode_path(self.name)
1.100 + print >>self.out, "void __main_%s(__attr __stack)" % encode_path(self.name)
1.101 print >>self.out, "{"
1.102 self.indent += 1
1.103
1.104 @@ -2142,10 +2145,14 @@
1.105 parameters found in the arguments array.
1.106 """
1.107
1.108 + l = []
1.109 +
1.110 + # Generate the parallel value stack reference.
1.111 +
1.112 + l.append("__attr __stack")
1.113 +
1.114 # Generate any self reference.
1.115
1.116 - l = []
1.117 -
1.118 if self.is_method(name):
1.119 l.append("__attr self")
1.120 else: