1.1 --- a/common.py Wed Aug 30 01:49:28 2023 +0200
1.2 +++ b/common.py Fri Sep 01 22:46:09 2023 +0200
1.3 @@ -3,7 +3,7 @@
1.4 """
1.5 Common functions.
1.6
1.7 -Copyright (C) 2007-2019, 2021 Paul Boddie <paul@boddie.org.uk>
1.8 +Copyright (C) 2007-2019, 2021, 2023 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 @@ -623,7 +623,7 @@
1.13 # raise LoopExit
1.14
1.15 [(compiler.ast.Name("StopIteration"), None,
1.16 - compiler.ast.Raise(compiler.ast.Name("LoopExit")))],
1.17 + compiler.ast.Raise(compiler.ast.Name("$loop_exit")))],
1.18 None),
1.19
1.20 # <var>... = <t3>
2.1 --- a/docs/tools/sign_releases.sh Wed Aug 30 01:49:28 2023 +0200
2.2 +++ b/docs/tools/sign_releases.sh Fri Sep 01 22:46:09 2023 +0200
2.3 @@ -31,9 +31,18 @@
2.4 fi
2.5
2.6 for FILENAME in "$OUTDIR/"*".tar.bz2" ; do
2.7 +
2.8 + # Handle an absence of archives.
2.9 +
2.10 + if [ ! -e "$FILENAME" ] ; then
2.11 + break
2.12 + fi
2.13 +
2.14 OUTFILE="$FILENAME.asc"
2.15 if [ ! -e "$OUTFILE" ] || [ "$FORCE" ]; then
2.16 gpg --sign -a -b "$FILENAME"
2.17 echo "$OUTFILE"
2.18 fi
2.19 done
2.20 +
2.21 +# vim: tabstop=4 expandtab shiftwidth=4
4.1 --- a/inspector.py Wed Aug 30 01:49:28 2023 +0200
4.2 +++ b/inspector.py Fri Sep 01 22:46:09 2023 +0200
4.3 @@ -907,6 +907,20 @@
4.4 self.set_special(n.name, value)
4.5 return value
4.6
4.7 + # Special case for loops.
4.8 +
4.9 + elif n.name == "$loop_exit":
4.10 +
4.11 + # Attempt to get a reference.
4.12 +
4.13 + ref = self.get_builtin("__loop_exit")
4.14 +
4.15 + # Record the imported name and provide the resolved name reference.
4.16 +
4.17 + value = ResolvedNameRef(n.name, ref)
4.18 + self.set_special(n.name, value)
4.19 + return value
4.20 +
4.21 # Test for self usage, which is only allowed in methods.
4.22
4.23 if n.name == "self" and not (self.in_function and self.in_class):
5.1 --- a/lib/__builtins__/__init__.py Wed Aug 30 01:49:28 2023 +0200
5.2 +++ b/lib/__builtins__/__init__.py Fri Sep 01 22:46:09 2023 +0200
5.3 @@ -3,7 +3,7 @@
5.4 """
5.5 Simple built-in classes and functions.
5.6
5.7 -Copyright (C) 2015, 2016, 2017, 2019, 2021 Paul Boddie <paul@boddie.org.uk>
5.8 +Copyright (C) 2015-2017, 2019, 2021, 2023 Paul Boddie <paul@boddie.org.uk>
5.9
5.10 This program is free software; you can redistribute it and/or modify it under
5.11 the terms of the GNU General Public License as published by the Free Software
5.12 @@ -50,7 +50,8 @@
5.13 UnicodeEncodeError,
5.14 UnicodeError,
5.15 UnicodeTranslateError,
5.16 - ValueError
5.17 + ValueError,
5.18 + __loop_exit
5.19 )
5.20
5.21 # Classes.
6.1 --- a/lib/__builtins__/exception/__init__.py Wed Aug 30 01:49:28 2023 +0200
6.2 +++ b/lib/__builtins__/exception/__init__.py Fri Sep 01 22:46:09 2023 +0200
6.3 @@ -3,7 +3,7 @@
6.4 """
6.5 Exception objects.
6.6
6.7 -Copyright (C) 2015, 2016, 2017, 2019 Paul Boddie <paul@boddie.org.uk>
6.8 +Copyright (C) 2015, 2016, 2017, 2019, 2023 Paul Boddie <paul@boddie.org.uk>
6.9
6.10 This program is free software; you can redistribute it and/or modify it under
6.11 the terms of the GNU General Public License as published by the Free Software
6.12 @@ -30,7 +30,8 @@
6.13 NotImplementedError,
6.14 RuntimeError,
6.15 StopIteration,
6.16 - ValueError
6.17 + ValueError,
6.18 + __loop_exit
6.19 )
6.20
6.21 from __builtins__.exception.io import (
7.1 --- a/lib/__builtins__/exception/base.py Wed Aug 30 01:49:28 2023 +0200
7.2 +++ b/lib/__builtins__/exception/base.py Fri Sep 01 22:46:09 2023 +0200
7.3 @@ -3,7 +3,7 @@
7.4 """
7.5 Base exception objects. See __builtins__.core for the core exceptions.
7.6
7.7 -Copyright (C) 2015, 2016, 2018, 2019 Paul Boddie <paul@boddie.org.uk>
7.8 +Copyright (C) 2015, 2016, 2018, 2019, 2023 Paul Boddie <paul@boddie.org.uk>
7.9
7.10 This program is free software; you can redistribute it and/or modify it under
7.11 the terms of the GNU General Public License as published by the Free Software
7.12 @@ -87,4 +87,8 @@
7.13
7.14 pass
7.15
7.16 +# Common loop exit instance.
7.17 +
7.18 +__loop_exit = LoopExit()
7.19 +
7.20 # vim: tabstop=4 expandtab shiftwidth=4
8.1 --- a/referencing.py Wed Aug 30 01:49:28 2023 +0200
8.2 +++ b/referencing.py Fri Sep 01 22:46:09 2023 +0200
8.3 @@ -3,7 +3,7 @@
8.4 """
8.5 Reference abstractions.
8.6
8.7 -Copyright (C) 2016, 2017 Paul Boddie <paul@boddie.org.uk>
8.8 +Copyright (C) 2016, 2017, 2023 Paul Boddie <paul@boddie.org.uk>
8.9
8.10 This program is free software; you can redistribute it and/or modify it under
8.11 the terms of the GNU General Public License as published by the Free Software
8.12 @@ -222,6 +222,12 @@
8.13 name = self.get_name()
8.14 return name and name.rsplit(".")[-1].startswith("$c")
8.15
8.16 + def is_well_defined_instance(self):
8.17 +
8.18 + "Return whether this reference involves a well-defined instance."
8.19 +
8.20 + return self.get_kind() == "<instance>"
8.21 +
8.22 def is_predefined_value(self):
8.23
8.24 "Return whether this reference identifies a predefined value."
9.1 --- a/resolving.py Wed Aug 30 01:49:28 2023 +0200
9.2 +++ b/resolving.py Fri Sep 01 22:46:09 2023 +0200
9.3 @@ -3,7 +3,7 @@
9.4 """
9.5 Name resolution.
9.6
9.7 -Copyright (C) 2016, 2017 Paul Boddie <paul@boddie.org.uk>
9.8 +Copyright (C) 2016, 2017, 2023 Paul Boddie <paul@boddie.org.uk>
9.9
9.10 This program is free software; you can redistribute it and/or modify it under
9.11 the terms of the GNU General Public License as published by the Free Software
9.12 @@ -73,7 +73,11 @@
9.13
9.14 for name, value in self.special.items():
9.15 ref, paths = value
9.16 - self.special[name] = self.importer.identify(ref.get_origin()), paths
9.17 +
9.18 + # Handle special instances.
9.19 +
9.20 + origin = ref.is_well_defined_instance() and ref.get_name() or ref.get_origin()
9.21 + self.special[name] = self.importer.identify(origin), paths
9.22
9.23 def check_names_used(self):
9.24
10.1 --- a/results.py Wed Aug 30 01:49:28 2023 +0200
10.2 +++ b/results.py Fri Sep 01 22:46:09 2023 +0200
10.3 @@ -3,7 +3,7 @@
10.4 """
10.5 Result abstractions.
10.6
10.7 -Copyright (C) 2016, 2017 Paul Boddie <paul@boddie.org.uk>
10.8 +Copyright (C) 2016, 2017, 2023 Paul Boddie <paul@boddie.org.uk>
10.9
10.10 This program is free software; you can redistribute it and/or modify it under
10.11 the terms of the GNU General Public License as published by the Free Software
10.12 @@ -164,6 +164,9 @@
10.13 def is_constant_alias(self):
10.14 return self.ref and self.ref.is_constant_alias()
10.15
10.16 + def is_well_defined_instance(self):
10.17 + return self.ref and self.ref.is_well_defined_instance()
10.18 +
10.19 class ResolvedNameRef(ResolvedRef, NameRef):
10.20
10.21 "A resolved name-based reference."
11.1 --- a/templates/native/limits.c Wed Aug 30 01:49:28 2023 +0200
11.2 +++ b/templates/native/limits.c Fri Sep 01 22:46:09 2023 +0200
11.3 @@ -1,6 +1,6 @@
11.4 /* Native functions for limit definition.
11.5
11.6 -Copyright (C) 2016, 2017, 2023 Paul Boddie <paul@boddie.org.uk>
11.7 +Copyright (C) 2016, 2017, 2021, 2023 Paul Boddie <paul@boddie.org.uk>
11.8
11.9 This program is free software; you can redistribute it and/or modify it under
11.10 the terms of the GNU General Public License as published by the Free Software
13.1 --- a/templates/native/list.h Wed Aug 30 01:49:28 2023 +0200
13.2 +++ b/templates/native/list.h Fri Sep 01 22:46:09 2023 +0200
13.3 @@ -1,6 +1,6 @@
13.4 /* Native functions for list operations.
13.5
13.6 -Copyright (C) 2016, 2017, 2023 Paul Boddie <paul@boddie.org.uk>
13.7 +Copyright (C) 2016, 2017, 2021, 2023 Paul Boddie <paul@boddie.org.uk>
13.8
13.9 This program is free software; you can redistribute it and/or modify it under
13.10 the terms of the GNU General Public License as published by the Free Software
14.1 --- a/translator.py Wed Aug 30 01:49:28 2023 +0200
14.2 +++ b/translator.py Fri Sep 01 22:46:09 2023 +0200
14.3 @@ -1314,7 +1314,7 @@
14.4 # Start with result target and context arguments for each invocation.
14.5
14.6 args = [result_target, context_arg]
14.7 - argstart = 2
14.8 + reserved_args = 2
14.9
14.10 # Complete the array with null values, permitting tests for a complete
14.11 # set of arguments.
14.12 @@ -1366,7 +1366,7 @@
14.13 except ValueError:
14.14 raise TranslateError("Argument %s is not recognised." % arg.name,
14.15 self.get_namespace_path(), n)
14.16 - args[argnum+argstart] = argexprstr
14.17 + args[argnum + reserved_args] = argexprstr
14.18
14.19 # Otherwise, store the details in a separate collection.
14.20
14.21 @@ -1380,7 +1380,7 @@
14.22
14.23 else:
14.24 try:
14.25 - args[i+argstart] = argexprstr
14.26 + args[i + reserved_args] = argexprstr
14.27 except IndexError:
14.28 raise TranslateError("Too many arguments specified.",
14.29 self.get_namespace_path(), n)
14.30 @@ -1404,8 +1404,8 @@
14.31
14.32 for i, (argname, default) in enumerate(function_defaults):
14.33 argnum = parameters.index(argname)
14.34 - if not args[argnum+argstart]:
14.35 - args[argnum+argstart] = "__GETDEFAULT(%s, %d)" % (target_structure, i)
14.36 + if not args[argnum + reserved_args]:
14.37 + args[argnum + reserved_args] = "__GETDEFAULT(%s, %d)" % (target_structure, i)
14.38
14.39 elif known_parameters:
14.40
14.41 @@ -1416,7 +1416,7 @@
14.42 i = len(n.args)
14.43 pos = i - (num_parameters - num_defaults)
14.44 while i < num_parameters:
14.45 - args[i+argstart] = "__GETDEFAULT(%s.value, %d)" % (target_var, pos)
14.46 + args[i + reserved_args] = "__GETDEFAULT(%s.value, %d)" % (target_var, pos)
14.47 i += 1
14.48 pos += 1
14.49
14.50 @@ -1432,7 +1432,7 @@
14.51 # the number of values. The result target and context are excluded.
14.52
14.53 if literal_instantiation:
14.54 - argstr = "%d, %s" % (len(args) - 2, ", ".join(args[2:]))
14.55 + argstr = "%d, %s" % (len(args) - reserved_args, ", ".join(args[reserved_args:]))
14.56 else:
14.57 argstr = ", ".join(args)
14.58
14.59 @@ -1670,7 +1670,8 @@
14.60 # function names to references.
14.61
14.62 elif n.name.startswith("$L") or n.name.startswith("$op") or \
14.63 - n.name.startswith("$seq") or n.name.startswith("$print"):
14.64 + n.name.startswith("$seq") or n.name.startswith("$print") or \
14.65 + n.name == "$loop_exit":
14.66
14.67 ref, paths = self.importer.get_module(self.name).special[n.name]
14.68 return TrResolvedNameRef(n.name, ref)
14.69 @@ -1800,7 +1801,7 @@
14.70 else:
14.71 exc = self.process_structure_node(n.expr1)
14.72
14.73 - if isinstance(exc, TrInstanceRef):
14.74 + if isinstance(exc, TrInstanceRef) or exc.is_well_defined_instance():
14.75 self.writestmt("__Raise(%s);" % exc)
14.76 else:
14.77 self.writestmt("__Raise(__ensure_instance(%s));" % exc)
15.1 --- a/transresults.py Wed Aug 30 01:49:28 2023 +0200
15.2 +++ b/transresults.py Fri Sep 01 22:46:09 2023 +0200
15.3 @@ -3,7 +3,7 @@
15.4 """
15.5 Translation result abstractions.
15.6
15.7 -Copyright (C) 2016, 2017, 2018, 2023 Paul Boddie <paul@boddie.org.uk>
15.8 +Copyright (C) 2016, 2017, 2018, 2021, 2023 Paul Boddie <paul@boddie.org.uk>
15.9
15.10 This program is free software; you can redistribute it and/or modify it under
15.11 the terms of the GNU General Public License as published by the Free Software
15.12 @@ -68,6 +68,20 @@
15.13 ResolvedNameRef.__init__(self, name, ref, expr, is_global)
15.14 self.location = location
15.15
15.16 + # For sources, any identified static origin will be constant and thus
15.17 + # usable directly. For targets, no constant should be assigned and thus
15.18 + # the alias (or any plain name) will be used.
15.19 +
15.20 + self.static_ref = self.static()
15.21 + origin = self.static_ref and self.get_origin()
15.22 + self.static_name = origin and encode_path(origin)
15.23 +
15.24 + # Determine whether a qualified name is involved.
15.25 +
15.26 + t = (not self.is_constant_alias() and self.get_name() or self.name).rsplit(".", 1)
15.27 + self.parent = len(t) > 1 and t[0] or None
15.28 + self.attrname = t[-1] and encode_path(t[-1])
15.29 +
15.30 def access_location(self):
15.31 return self.location
15.32
15.33 @@ -83,58 +97,42 @@
15.34 else:
15.35 return encode_path(self.name)
15.36
15.37 - # For sources, any identified static origin will be constant and thus
15.38 - # usable directly. For targets, no constant should be assigned and thus
15.39 - # the alias (or any plain name) will be used.
15.40 -
15.41 - ref = self.static()
15.42 - origin = ref and self.get_origin()
15.43 - static_name = origin and encode_path(origin)
15.44 -
15.45 - # Determine whether a qualified name is involved.
15.46 -
15.47 - t = (not self.is_constant_alias() and self.get_name() or self.name).rsplit(".", 1)
15.48 - parent = len(t) > 1 and t[0] or None
15.49 - attrname = t[-1] and encode_path(t[-1])
15.50 -
15.51 # Assignments.
15.52
15.53 if self.expr:
15.54
15.55 # Eliminate assignments between constants.
15.56
15.57 - if ref and self.expr.static():
15.58 + if self.static_ref and self.expr.static():
15.59 return ""
15.60
15.61 # Qualified names must be converted into parent-relative assignments.
15.62
15.63 - elif parent:
15.64 + elif self.parent:
15.65 return "__store_via_object(&%s, %s, %s)" % (
15.66 - encode_path(parent), attrname, self.expr)
15.67 + encode_path(self.parent), self.attrname, self.expr)
15.68
15.69 # All other assignments involve the names as they were given.
15.70 # To support value replacement, a special operation is used.
15.71
15.72 else:
15.73 - return "__set_local(&%s, %s)" % (attrname, self.expr)
15.74 + return "__set_local(&%s, %s)" % (self.attrname, self.expr)
15.75
15.76 # Expressions.
15.77
15.78 - elif static_name:
15.79 - parent = ref.parent()
15.80 - context = ref.has_kind("<function>") and encode_path(parent) or None
15.81 - return "__ATTRVALUE(&%s)" % static_name
15.82 + elif self.static_name:
15.83 + return "__ATTRVALUE(&%s)" % self.static_name
15.84
15.85 # Qualified names must be converted into parent-relative accesses.
15.86
15.87 - elif parent:
15.88 + elif self.parent:
15.89 return "__load_via_object(&%s, %s)" % (
15.90 - encode_path(parent), attrname)
15.91 + encode_path(self.parent), self.attrname)
15.92
15.93 # All other accesses involve the names as they were given.
15.94
15.95 else:
15.96 - return "(%s)" % attrname
15.97 + return "(%s)" % self.attrname
15.98
15.99 class TrConstantValueRef(ConstantValueRef):
15.100