1.1 --- a/common.py Mon Jan 28 21:16:56 2019 +0100
1.2 +++ b/common.py Tue Aug 22 19:36:13 2023 +0200
1.3 @@ -3,8 +3,7 @@
1.4 """
1.5 Common functions.
1.6
1.7 -Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016,
1.8 - 2017, 2018, 2019 Paul Boddie <paul@boddie.org.uk>
1.9 +Copyright (C) 2007-2019, 2021 Paul Boddie <paul@boddie.org.uk>
1.10
1.11 This program is free software; you can redistribute it and/or modify it under
1.12 the terms of the GNU General Public License as published by the Free Software
1.13 @@ -563,6 +562,8 @@
1.14 self.next_temporary()
1.15 t2 = self.get_temporary_name()
1.16 self.next_temporary()
1.17 + t3 = self.get_temporary_name()
1.18 + self.next_temporary()
1.19
1.20 node = compiler.ast.Stmt([
1.21
1.22 @@ -583,9 +584,10 @@
1.23 # try:
1.24 # while True:
1.25 # try:
1.26 - # <var>... = <t2>()
1.27 + # <t3> = <t2>()
1.28 # except StopIteration:
1.29 # raise LoopExit
1.30 + # <var>... = <t3>
1.31 # {n.body}
1.32 # except LoopExit:
1.33 # {n.else_}
1.34 @@ -595,21 +597,47 @@
1.35 [compiler.ast.AssName(t2, "OP_ASSIGN")],
1.36 compiler.ast.Getattr(compiler.ast.Name(t1), "next")),
1.37
1.38 + # try:
1.39 +
1.40 compiler.ast.TryExcept(
1.41 +
1.42 + # while True:
1.43 +
1.44 compiler.ast.While(
1.45 compiler.ast.Name("True"),
1.46 compiler.ast.Stmt([
1.47 +
1.48 + # try:
1.49 +
1.50 compiler.ast.TryExcept(
1.51 +
1.52 + # <t3> = <t2>()
1.53 +
1.54 compiler.ast.Assign(
1.55 - [n.assign],
1.56 + [compiler.ast.AssName(t3, "OP_ASSIGN")],
1.57 compiler.ast.CallFunc(
1.58 compiler.ast.Name(t2),
1.59 [])),
1.60 +
1.61 + # except StopIteration:
1.62 + # raise LoopExit
1.63 +
1.64 [(compiler.ast.Name("StopIteration"), None,
1.65 compiler.ast.Raise(compiler.ast.Name("LoopExit")))],
1.66 None),
1.67 +
1.68 + # <var>... = <t3>
1.69 +
1.70 + compiler.ast.Assign(
1.71 + [n.assign],
1.72 + compiler.ast.Name(t3)),
1.73 n.body]),
1.74 None),
1.75 +
1.76 + # except LoopExit:
1.77 + # {n.else_}
1.78 + # pass
1.79 +
1.80 [(compiler.ast.Name("LoopExit"), None, n.else_ or compiler.ast.Pass())],
1.81 None)
1.82 ])
1.83 @@ -1566,11 +1594,7 @@
1.84
1.85 "Return the module name containing the given type 'name'."
1.86
1.87 - if name == "string":
1.88 - modname = "str"
1.89 - elif name == "utf8string":
1.90 - modname = "unicode"
1.91 - elif name == "NoneType":
1.92 + if name == "NoneType":
1.93 modname = "none"
1.94 else:
1.95 modname = name
1.96 @@ -1581,12 +1605,7 @@
1.97
1.98 "Return the type name provided by the given Python value 'name'."
1.99
1.100 - if name == "str":
1.101 - return "string"
1.102 - elif name == "unicode":
1.103 - return "utf8string"
1.104 - else:
1.105 - return name
1.106 + return name
1.107
1.108 def get_builtin_class(name):
1.109
2.1 --- a/deducer.py Mon Jan 28 21:16:56 2019 +0100
2.2 +++ b/deducer.py Tue Aug 22 19:36:13 2023 +0200
2.3 @@ -2347,6 +2347,10 @@
2.4 remaining = attrnames.split(".")
2.5 attrname = remaining[0]
2.6
2.7 + # Special case for the ubiquitous __class__ attribute.
2.8 +
2.9 + ubiquitous = attrname == "__class__"
2.10 +
2.11 # Obtain reference, provider and provider kind information.
2.12
2.13 attrs = self.reference_all_attrs[location]
2.14 @@ -2375,8 +2379,8 @@
2.15
2.16 # Determine how attributes may be accessed relative to the accessor.
2.17
2.18 - object_relative = class_accessor or module_accessor or provided_by_instance
2.19 - class_relative = instance_accessor and provided_by_class
2.20 + object_relative = ubiquitous or class_accessor or module_accessor or provided_by_instance
2.21 + class_relative = not ubiquitous and instance_accessor and provided_by_class
2.22
2.23 # Identify the last static attribute for context acquisition.
2.24
2.25 @@ -2517,6 +2521,11 @@
2.26 first_method = "relative" + (object_relative and "-object" or "") + \
2.27 (class_relative and "-class" or "")
2.28
2.29 + # Special case for the ubiquitous __class__ attribute.
2.30 +
2.31 + elif ubiquitous:
2.32 + first_method = "relative-object"
2.33 +
2.34 # The fallback case is always run-time testing and access.
2.35
2.36 else:
3.1 --- a/docs/COPYING.txt Mon Jan 28 21:16:56 2019 +0100
3.2 +++ b/docs/COPYING.txt Tue Aug 22 19:36:13 2023 +0200
3.3 @@ -1,8 +1,8 @@
3.4 Licence Agreement
3.5 -----------------
3.6
3.7 -Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013,
3.8 - 2014, 2015, 2016, 2017 Paul Boddie <paul@boddie.org.uk>
3.9 +Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015,
3.10 + 2016, 2017, 2018, 2019 Paul Boddie <paul@boddie.org.uk>
3.11
3.12 This program is free software; you can redistribute it and/or modify it under
3.13 the terms of the GNU General Public License as published by the Free Software
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/docs/tools/make_docs.sh Tue Aug 22 19:36:13 2023 +0200
4.3 @@ -0,0 +1,30 @@
4.4 +#!/bin/sh
4.5 +
4.6 +THISDIR=`dirname "$0"`
4.7 +INDIR="$THISDIR/../wiki"
4.8 +OUTDIR="$THISDIR/../html"
4.9 +
4.10 +ROOT="Lichen"
4.11 +
4.12 +MAPPING='--mapping WikiPedia https://en.wikipedia.org/wiki/'
4.13 +THEME='--theme mercurial'
4.14 +
4.15 +if [ "$1" = '--web' ] ; then
4.16 + DOCINDEX=
4.17 + shift 1
4.18 +else
4.19 + DOCINDEX='--document-index index.html'
4.20 +fi
4.21 +
4.22 +FILENAMES=${*:-'--all'}
4.23 +
4.24 +moinconvert --input-dir "$INDIR" \
4.25 + --input-page-sep '--' \
4.26 + --output-dir "$OUTDIR" \
4.27 + --root "$ROOT" \
4.28 + --format html \
4.29 + --macros \
4.30 + $DOCINDEX \
4.31 + $MAPPING \
4.32 + $THEME \
4.33 + $FILENAMES
5.1 --- a/docs/tools/make_pages.sh Mon Jan 28 21:16:56 2019 +0100
5.2 +++ b/docs/tools/make_pages.sh Tue Aug 22 19:36:13 2023 +0200
5.3 @@ -56,7 +56,7 @@
5.4 BASENAME=`basename "$FILENAME"`
5.5 PAGENAME=`echo "$BASENAME" | sed 's/--/\//g'`
5.6 if [ "$PREFIX" ]; then
5.7 - if [ "$PAGENAME" = "FrontPage" ]; then
5.8 + if [ "$PAGENAME" = "Lichen" ]; then
5.9 PAGENAME="$PREFIX"
5.10 else
5.11 PAGENAME="$PREFIX/$PAGENAME"
6.1 --- a/docs/wiki/Deduction Mon Jan 28 21:16:56 2019 +0100
6.2 +++ b/docs/wiki/Deduction Tue Aug 22 19:36:13 2023 +0200
6.3 @@ -89,7 +89,7 @@
6.4 //format=svg
6.5 //transform=notugly
6.6 digraph indexes {
6.7 - node [shape=box,fontsize="13.0",fontname="Helvetica",tooltip="Indexes"];
6.8 + node [shape=box,fontsize="13.0",fontname="sans-serif",tooltip="Indexes"];
6.9 edge [tooltip="Indexes"];
6.10 rankdir=LR;
6.11
6.12 @@ -142,7 +142,7 @@
6.13 //format=svg
6.14 //transform=notugly
6.15 digraph deduction {
6.16 - node [shape=box,fontsize="13.0",fontname="Helvetica",tooltip="Deduction"];
6.17 + node [shape=box,fontsize="13.0",fontname="sans-serif",tooltip="Deduction"];
6.18 edge [tooltip="Deduction"];
6.19 rankdir=LR;
6.20
6.21 @@ -192,7 +192,7 @@
6.22 //format=svg
6.23 //transform=notugly
6.24 digraph usage_to_types {
6.25 - node [shape=box,fontsize="13.0",fontname="Helvetica",tooltip="Usage to types"];
6.26 + node [shape=box,fontsize="13.0",fontname="sans-serif",tooltip="Usage to types"];
6.27 edge [tooltip="Usage to types"];
6.28 rankdir=LR;
6.29
6.30 @@ -249,7 +249,7 @@
6.31 //format=svg
6.32 //transform=notugly
6.33 digraph instance_providers {
6.34 - node [shape=box,fontsize="13.0",fontname="Helvetica",tooltip="Instance providers"];
6.35 + node [shape=box,fontsize="13.0",fontname="sans-serif",tooltip="Instance providers"];
6.36 edge [tooltip="Instance providers"];
6.37 rankdir=LR;
6.38
6.39 @@ -310,7 +310,7 @@
6.40 //format=svg
6.41 //transform=notugly
6.42 digraph assignments {
6.43 - node [shape=box,fontsize="13.0",fontname="Helvetica",tooltip="Attribute assignments"];
6.44 + node [shape=box,fontsize="13.0",fontname="sans-serif",tooltip="Attribute assignments"];
6.45 edge [tooltip="Attribute assignments"];
6.46 rankdir=LR;
6.47
7.1 --- a/docs/wiki/FrontPage Mon Jan 28 21:16:56 2019 +0100
7.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
7.3 @@ -1,95 +0,0 @@
7.4 -= Lichen =
7.5 -
7.6 -|| [[/Downloads|Downloads]] || [[#Language|Language]] || [[#Toolchain|Toolchain]] || [[#Rationale|Rationale]] || [[#Documents|Documents]] ||
7.7 -
7.8 -Lichen is both a Python-like [[/Design|language]] and a
7.9 -[[/Toolchain|toolchain]] for that language.
7.10 -
7.11 -Some objectives:
7.12 -
7.13 - * Perform analysis on programs to better understand program structure and
7.14 - behaviour
7.15 - * Develop code generation capabilities
7.16 - * Provide a platform for experimentation independent of existing Python
7.17 - language and library implementations
7.18 - * Provide independence from Python language evolution
7.19 - * Learn things about writing compilers
7.20 -
7.21 -Despite building on a long [[/History|history]] of experimentation, Lichen
7.22 -still requires some [[/ToDo|work to be done]] for it to be more widely usable.
7.23 -
7.24 -<<Anchor(Language)>>
7.25 -== Language ==
7.26 -
7.27 -The Lichen language [[/Design|foregoes]] various dynamic aspects of Python to
7.28 -provide a foundation upon which more predictable programs can be built, while
7.29 -preserving essential functionality to make the core of the language seem very
7.30 -much "like Python" (thus yielding the name "Lichen"). The general syntax is
7.31 -largely identical to Python, with only certain syntactic constructs being
7.32 -deliberately unsupported, largely because the associated features are not
7.33 -desired.
7.34 -
7.35 -<<Anchor(Toolchain)>>
7.36 -== Toolchain ==
7.37 -
7.38 -The Lichen [[/Toolchain|toolchain]] employs existing tokeniser and parser
7.39 -software to obtain an abstract syntax tree which is then inspected to provide
7.40 -data to support deductions about the structure and nature of a given program.
7.41 -With the information obtained from these processes, a program is then
7.42 -constructed, consisting of a number of source files in the target compilation
7.43 -language (which is currently the C programming language). This generated
7.44 -program may be compiled and run, hopefully producing the results intended by
7.45 -the source program's authors.
7.46 -
7.47 -Lichen source files use the `.py` suffix since the language syntax is
7.48 -superficially compatible with Python, allowing text editors to provide
7.49 -highlighting and editing support for Lichen programs without the need to
7.50 -reconfigure such tools. However, an alternative, recommended suffix is likely
7.51 -to be introduced in future.
7.52 -
7.53 -<<Anchor(Library)>>
7.54 -== Library ==
7.55 -
7.56 -Unlike other Python compilation efforts, Lichen programs employ a newly-written
7.57 -library that is distinct from the CPython standard library distribution and
7.58 -completely independent from the CPython extension and object libraries on which
7.59 -Python programs being run with CPython must depend. Thus, there is no
7.60 -dependency on any `libpython` for run-time functionality. Since the parts of
7.61 -the Python standard library that are written in Python tend to be rather
7.62 -variable in quality, there has been no real inclination to re-use modules from
7.63 -that particular source, noting that they would need modifying to be compatible
7.64 -with Lichen, anyway. However, rewriting such modules provides opportunities to
7.65 -"do things right": with some functionality being over twenty years old and in
7.66 -bad shape, this is arguably something that should have been done for Python,
7.67 -anyway.
7.68 -
7.69 -<<Anchor(Rationale)>>
7.70 -== Rationale ==
7.71 -
7.72 -Python has proven to be a readable, productive, comfortable-to-use and popular
7.73 -programming language. However, as it has accumulated features, the precise
7.74 -behaviour of programs making use of many of these features has become more
7.75 -difficult to predict. Features added to provide even more convenience to the
7.76 -programmer have often incurred run-time costs, introduced layers of
7.77 -indirection, and have made programs even more inscrutable. Instead of
7.78 -development tools reaching a point of being able to infer information about
7.79 -programs, it has been suggested that programmers annotate their programs in
7.80 -order to help tools understand those programs instead. Beyond superficial code
7.81 -style analysis and providing tooltips in integrated development environments,
7.82 -Python code analysis is often portrayed as a lost cause.
7.83 -
7.84 -By employing a refined language [[/Design|design]], Lichen aims to let each
7.85 -program define its [[/Structure|structure]] conveniently, be readily
7.86 -[[/Inspection|inspected]], and thus support [[/Deduction|deductions]] about the
7.87 -use of the program's objects by the code. The result should be more predictable
7.88 -programs that can be [[/Translation|translated]] to other, more efficient,
7.89 -[[/Representations|representations]]. The Lichen toolchain should be able to
7.90 -tell the programmer useful things about their programs that it may also be able
7.91 -to make use of itself. It not only aims to report information about programs
7.92 -that might be of interest to the developer, but it seeks to produce
7.93 -functioning, translated programs that can actually be run.
7.94 -
7.95 -<<Anchor(Documents)>>
7.96 -== Document Index ==
7.97 -
7.98 -<<FullSearch(title:Lichen/)>>
8.1 --- a/docs/wiki/History Mon Jan 28 21:16:56 2019 +0100
8.2 +++ b/docs/wiki/History Tue Aug 22 19:36:13 2023 +0200
8.3 @@ -71,7 +71,7 @@
8.4 == Current Work ==
8.5
8.6 It was with such realisations that a new project was effectively born.
8.7 -Tentatively called "!PythonLight" but renamed to "Lichen" as the code matured,
8.8 +Tentatively called "PythonLight" but renamed to "Lichen" as the code matured,
8.9 the objectives now involved a simpler processing framework that merely
8.10 attempted to catalogue structure members, to determine the origins of such
8.11 members, and to record data flow within namespaces in order to determine
9.1 --- a/docs/wiki/Imports Mon Jan 28 21:16:56 2019 +0100
9.2 +++ b/docs/wiki/Imports Tue Aug 22 19:36:13 2023 +0200
9.3 @@ -95,7 +95,7 @@
9.4 //format=svg
9.5 //transform=notugly
9.6 digraph mutual {
9.7 - node [shape=box,fontsize="13.0",fontname="Helvetica",tooltip="Mutually-dependent modules"];
9.8 + node [shape=box,fontsize="13.0",fontname="sans-serif",tooltip="Mutually-dependent modules"];
9.9 edge [tooltip="Mutually-dependent modules"];
9.10 rankdir=LR;
9.11
9.12 @@ -209,7 +209,7 @@
9.13 //format=svg
9.14 //transform=notugly
9.15 digraph imports {
9.16 - node [shape=box,fontsize="13.0",fontname="Helvetica",tooltip="Import dependencies"];
9.17 + node [shape=box,fontsize="13.0",fontname="sans-serif",tooltip="Import dependencies"];
9.18 edge [tooltip="Import dependencies"];
9.19 rankdir=LR;
9.20
10.1 --- a/docs/wiki/Inspection Mon Jan 28 21:16:56 2019 +0100
10.2 +++ b/docs/wiki/Inspection Tue Aug 22 19:36:13 2023 +0200
10.3 @@ -179,7 +179,7 @@
10.4 //format=svg
10.5 //transform=notugly
10.6 digraph accesses {
10.7 - node [shape=box,fontsize="13.0",fontname="Helvetica",tooltip="Names and accesses"];
10.8 + node [shape=box,fontsize="13.0",fontname="sans-serif",tooltip="Names and accesses"];
10.9 edge [tooltip="Names and accesses"];
10.10 rankdir=TB;
10.11
10.12 @@ -316,7 +316,7 @@
10.13 //format=svg
10.14 //transform=notugly
10.15 digraph usage {
10.16 - node [shape=box,fontsize="13.0",fontname="Helvetica",tooltip="Name and attribute tracking"];
10.17 + node [shape=box,fontsize="13.0",fontname="sans-serif",tooltip="Name and attribute tracking"];
10.18 edge [tooltip="Name and attribute tracking"];
10.19 rankdir=TB;
10.20
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/docs/wiki/Lichen Tue Aug 22 19:36:13 2023 +0200
11.3 @@ -0,0 +1,95 @@
11.4 += Lichen =
11.5 +
11.6 +|| [[/Downloads|Downloads]] || [[#Language|Language]] || [[#Toolchain|Toolchain]] || [[#Rationale|Rationale]] || [[#Documents|Documents]] ||
11.7 +
11.8 +Lichen is both a Python-like [[/Design|language]] and a
11.9 +[[/Toolchain|toolchain]] for that language.
11.10 +
11.11 +Some objectives:
11.12 +
11.13 + * Perform analysis on programs to better understand program structure and
11.14 + behaviour
11.15 + * Develop code generation capabilities
11.16 + * Provide a platform for experimentation independent of existing Python
11.17 + language and library implementations
11.18 + * Provide independence from Python language evolution
11.19 + * Learn things about writing compilers
11.20 +
11.21 +Despite building on a long [[/History|history]] of experimentation, Lichen
11.22 +still requires some [[/ToDo|work to be done]] for it to be more widely usable.
11.23 +
11.24 +<<Anchor(Language)>>
11.25 +== Language ==
11.26 +
11.27 +The Lichen language [[/Design|foregoes]] various dynamic aspects of Python to
11.28 +provide a foundation upon which more predictable programs can be built, while
11.29 +preserving essential functionality to make the core of the language seem very
11.30 +much "like Python" (thus yielding the name "Lichen"). The general syntax is
11.31 +largely identical to Python, with only certain syntactic constructs being
11.32 +deliberately unsupported, largely because the associated features are not
11.33 +desired.
11.34 +
11.35 +<<Anchor(Toolchain)>>
11.36 +== Toolchain ==
11.37 +
11.38 +The Lichen [[/Toolchain|toolchain]] employs existing tokeniser and parser
11.39 +software to obtain an abstract syntax tree which is then inspected to provide
11.40 +data to support deductions about the structure and nature of a given program.
11.41 +With the information obtained from these processes, a program is then
11.42 +constructed, consisting of a number of source files in the target compilation
11.43 +language (which is currently the C programming language). This generated
11.44 +program may be compiled and run, hopefully producing the results intended by
11.45 +the source program's authors.
11.46 +
11.47 +Lichen source files use the `.py` suffix since the language syntax is
11.48 +superficially compatible with Python, allowing text editors to provide
11.49 +highlighting and editing support for Lichen programs without the need to
11.50 +reconfigure such tools. However, an alternative, recommended suffix is likely
11.51 +to be introduced in future.
11.52 +
11.53 +<<Anchor(Library)>>
11.54 +== Library ==
11.55 +
11.56 +Unlike other Python compilation efforts, Lichen programs employ a newly-written
11.57 +library that is distinct from the CPython standard library distribution and
11.58 +completely independent from the CPython extension and object libraries on which
11.59 +Python programs being run with CPython must depend. Thus, there is no
11.60 +dependency on any `libpython` for run-time functionality. Since the parts of
11.61 +the Python standard library that are written in Python tend to be rather
11.62 +variable in quality, there has been no real inclination to re-use modules from
11.63 +that particular source, noting that they would need modifying to be compatible
11.64 +with Lichen, anyway. However, rewriting such modules provides opportunities to
11.65 +"do things right": with some functionality being over twenty years old and in
11.66 +bad shape, this is arguably something that should have been done for Python,
11.67 +anyway.
11.68 +
11.69 +<<Anchor(Rationale)>>
11.70 +== Rationale ==
11.71 +
11.72 +Python has proven to be a readable, productive, comfortable-to-use and popular
11.73 +programming language. However, as it has accumulated features, the precise
11.74 +behaviour of programs making use of many of these features has become more
11.75 +difficult to predict. Features added to provide even more convenience to the
11.76 +programmer have often incurred run-time costs, introduced layers of
11.77 +indirection, and have made programs even more inscrutable. Instead of
11.78 +development tools reaching a point of being able to infer information about
11.79 +programs, it has been suggested that programmers annotate their programs in
11.80 +order to help tools understand those programs instead. Beyond superficial code
11.81 +style analysis and providing tooltips in integrated development environments,
11.82 +Python code analysis is often portrayed as a lost cause.
11.83 +
11.84 +By employing a refined language [[/Design|design]], Lichen aims to let each
11.85 +program define its [[/Structure|structure]] conveniently, be readily
11.86 +[[/Inspection|inspected]], and thus support [[/Deduction|deductions]] about the
11.87 +use of the program's objects by the code. The result should be more predictable
11.88 +programs that can be [[/Translation|translated]] to other, more efficient,
11.89 +[[/Representations|representations]]. The Lichen toolchain should be able to
11.90 +tell the programmer useful things about their programs that it may also be able
11.91 +to make use of itself. It not only aims to report information about programs
11.92 +that might be of interest to the developer, but it seeks to produce
11.93 +functioning, translated programs that can actually be run.
11.94 +
11.95 +<<Anchor(Documents)>>
11.96 +== Document Index ==
11.97 +
11.98 +<<PageList>>
12.1 --- a/docs/wiki/Representations Mon Jan 28 21:16:56 2019 +0100
12.2 +++ b/docs/wiki/Representations Tue Aug 22 19:36:13 2023 +0200
12.3 @@ -16,8 +16,8 @@
12.4 //format=svg
12.5 //transform=notugly
12.6 digraph attributes {
12.7 - node [shape=box,fontsize="13.0",fontname="Helvetica",tooltip="Attributes"];
12.8 - edge [fontsize="13.0",fontname="Helvetica",tooltip="Attributes"];
12.9 + node [shape=box,fontsize="13.0",fontname="sans-serif",tooltip="Attributes"];
12.10 + edge [fontsize="13.0",fontname="sans-serif",tooltip="Attributes"];
12.11 rankdir=TB;
12.12
12.13 attrA [label="attribute | { value |<value> reference to object }",shape=record];
12.14 @@ -77,8 +77,8 @@
12.15 //format=svg
12.16 //transform=notugly
12.17 digraph wrappers {
12.18 - node [shape=box,fontsize="13.0",fontname="Helvetica",tooltip="Wrappers"];
12.19 - edge [fontsize="13.0",fontname="Helvetica",tooltip="Wrappers"];
12.20 + node [shape=box,fontsize="13.0",fontname="sans-serif",tooltip="Wrappers"];
12.21 + edge [fontsize="13.0",fontname="sans-serif",tooltip="Wrappers"];
12.22 rankdir=TB;
12.23
12.24 inst [label="<main> instance | { attr1 |<attr1> reference to method } | { attr2 | value } | ...",shape=record];
12.25 @@ -104,8 +104,8 @@
12.26 //format=svg
12.27 //transform=notugly
12.28 digraph objects {
12.29 - node [shape=box,fontsize="13.0",fontname="Helvetica",tooltip="Objects"];
12.30 - edge [fontsize="13.0",fontname="Helvetica",tooltip="Objects"];
12.31 + node [shape=box,fontsize="13.0",fontname="sans-serif",tooltip="Objects"];
12.32 + edge [fontsize="13.0",fontname="sans-serif",tooltip="Objects"];
12.33 rankdir=TB;
12.34
12.35 instC [label="<main> instance of C | { 0 | reference to\ninstance table } | { __class__ |<cls> reference\nto C } | { a | value } | { b | value } | ...",shape=record];
13.1 --- a/docs/wiki/Restarted Mon Jan 28 21:16:56 2019 +0100
13.2 +++ b/docs/wiki/Restarted Tue Aug 22 19:36:13 2023 +0200
13.3 @@ -262,8 +262,8 @@
13.4 //format=svg
13.5 //transform=notugly
13.6 digraph structures {
13.7 - node [shape=box,fontsize="13.0",fontname="Helvetica",tooltip="Instance and class structures"];
13.8 - edge [fontsize="13.0",fontname="Helvetica",tooltip="Instance and class structures"];
13.9 + node [shape=box,fontsize="13.0",fontname="sans-serif",tooltip="Instance and class structures"];
13.10 + edge [fontsize="13.0",fontname="sans-serif",tooltip="Instance and class structures"];
13.11 rankdir=TB;
13.12
13.13 instanceC [label="<main> instance of C |{ context of a | value of a }|{context of b | value of b }",shape=record];
13.14 @@ -285,8 +285,8 @@
13.15 //format=svg
13.16 //transform=notugly
13.17 digraph methods {
13.18 - node [shape=box,fontsize="13.0",fontname="Helvetica",tooltip="Method structures"];
13.19 - edge [fontsize="13.0",fontname="Helvetica",tooltip="Method structures"];
13.20 + node [shape=box,fontsize="13.0",fontname="sans-serif",tooltip="Method structures"];
13.21 + edge [fontsize="13.0",fontname="sans-serif",tooltip="Method structures"];
13.22 rankdir=TB;
13.23
13.24 classC [label="<main> class C | { context of m | <mvalue> uncallable for m } | ...",shape=record];
14.1 --- a/docs/wiki/Structure Mon Jan 28 21:16:56 2019 +0100
14.2 +++ b/docs/wiki/Structure Tue Aug 22 19:36:13 2023 +0200
14.3 @@ -29,7 +29,7 @@
14.4 //format=svg
14.5 //transform=notugly
14.6 digraph program {
14.7 - node [shape=box,fontsize="13.0",fontname="Helvetica",tooltip="Program structure"];
14.8 + node [shape=box,fontsize="13.0",fontname="sans-serif",tooltip="Program structure"];
14.9 edge [tooltip="Program structure"];
14.10 rankdir=LR;
14.11
15.1 --- a/docs/wiki/Toolchain Mon Jan 28 21:16:56 2019 +0100
15.2 +++ b/docs/wiki/Toolchain Tue Aug 22 19:36:13 2023 +0200
15.3 @@ -73,12 +73,12 @@
15.4 which the `parser` module effectively is (as would the `ast` module also be if
15.5 it were used here), with it typically being implemented as an extension module
15.6 in a non-Python language (in C for CPython, in Java for Jython, and so on).
15.7 -Fortunately, the !PyPy project implemented their own parsing module,
15.8 -`pyparser`, that is intended to be used within the !PyPy environment together
15.9 -with their own `ast` equivalent, but it has been possible to rework `pyparser`
15.10 -to produce representations that are compatible with the `compiler` package,
15.11 -itself being modified in various ways to achieve compatibility (and also to
15.12 -provide various other conveniences).
15.13 +Fortunately, the [[http://pypy.org/|PyPy]] project implemented their own
15.14 +parsing module, `pyparser`, that is intended to be used within the PyPy
15.15 +environment together with their own `ast` equivalent, but it has been possible
15.16 +to rework `pyparser` to produce representations that are compatible with the
15.17 +`compiler` package, itself being modified in various ways to achieve
15.18 +compatibility (and also to provide various other conveniences).
15.19
15.20 == Program Analysis ==
15.21
16.1 --- a/generator.py Mon Jan 28 21:16:56 2019 +0100
16.2 +++ b/generator.py Tue Aug 22 19:36:13 2023 +0200
16.3 @@ -3,7 +3,7 @@
16.4 """
16.5 Generate C code from object layouts and other deduced information.
16.6
16.7 -Copyright (C) 2015, 2016, 2017, 2018 Paul Boddie <paul@boddie.org.uk>
16.8 +Copyright (C) 2015-2019, 2021 Paul Boddie <paul@boddie.org.uk>
16.9
16.10 This program is free software; you can redistribute it and/or modify it under
16.11 the terms of the GNU General Public License as published by the Free Software
16.12 @@ -48,10 +48,10 @@
16.13 int_type = "__builtins__.int.int"
16.14 list_type = "__builtins__.list.list"
16.15 none_type = "__builtins__.none.NoneType"
16.16 - string_type = "__builtins__.str.string"
16.17 + string_type = "__builtins__.str.str"
16.18 tuple_type = "__builtins__.tuple.tuple"
16.19 type_type = "__builtins__.core.type"
16.20 - unicode_type = "__builtins__.unicode.utf8string"
16.21 + unicode_type = "__builtins__.unicode.unicode"
16.22
16.23 none_value = "__builtins__.none.None"
16.24
16.25 @@ -257,7 +257,7 @@
16.26 self.populate_trailing(Reference(kind, path), attrs, trailing)
16.27
16.28 if kind == "<class>":
16.29 - self.write_instance_structure(f_decls, path, structure_size)
16.30 + self.write_instance_structure(f_decls, path)
16.31
16.32 self.write_structure(f_decls, f_defs, path, table_name,
16.33 structure, trailing, ref)
16.34 @@ -300,7 +300,6 @@
16.35
16.36 cls = self.function_type
16.37 table_name = encode_tablename("<instance>", cls)
16.38 - structure_size = encode_size("<instance>", path)
16.39
16.40 # Set a special callable attribute on the instance.
16.41
16.42 @@ -313,7 +312,7 @@
16.43 # Functions with defaults need to declare instance structures.
16.44
16.45 if self.importer.function_defaults.get(path):
16.46 - self.write_instance_structure(f_decls, path, structure_size)
16.47 + self.write_instance_structure(f_decls, path)
16.48 extra_function_instances.append(path)
16.49
16.50 # Write function declarations.
16.51 @@ -838,13 +837,14 @@
16.52 """ % (table_name, min_parameters, max_parameters, structure_size,
16.53 ",\n ".join(members))
16.54
16.55 - def write_instance_structure(self, f_decls, path, structure_size):
16.56 + def write_instance_structure(self, f_decls, path):
16.57
16.58 """
16.59 - Write a declaration to 'f_decls' for the object having the given 'path'
16.60 - and the given 'structure_size'.
16.61 + Write a declaration to 'f_decls' for the object having the given 'path'.
16.62 """
16.63
16.64 + structure_size = encode_size("<instance>", path)
16.65 +
16.66 # Write an instance-specific type definition for instances of classes.
16.67 # See: templates/types.h
16.68
16.69 @@ -1066,7 +1066,7 @@
16.70 # Special internal size member.
16.71
16.72 elif attrname == "__size__":
16.73 - structure.append("__INTVALUE(%d)" % attr)
16.74 + structure.append("{.sizevalue=%d}" % attr)
16.75 continue
16.76
16.77 # Special internal key member.
16.78 @@ -1263,18 +1263,51 @@
16.79 for name in parameters:
16.80 l.append("__attr %s" % name)
16.81
16.82 - print >>f_code, """\
16.83 + # Special-case the integer type.
16.84 +
16.85 + # Here, the __builtins__.int.new_int function is called with the
16.86 + # initialiser's parameters.
16.87 +
16.88 + if path == self.int_type:
16.89 + print >>f_code, """\
16.90 +__attr %s(__attr __self, __attr number_or_string, __attr base)
16.91 +{
16.92 + return __fn___builtins___int_new_int(__NULL, number_or_string, base);
16.93 +}
16.94 +""" % (
16.95 + encode_instantiator_pointer(path),
16.96 + )
16.97 +
16.98 + # Special-case the string types.
16.99 +
16.100 + # Here, the __builtins__.str.new_str function is called with the
16.101 + # initialiser's parameter.
16.102 +
16.103 + elif path == self.string_type:
16.104 + print >>f_code, """\
16.105 +__attr %s(__attr __self, __attr obj)
16.106 +{
16.107 + return __fn___builtins___str_new_str(__NULL, obj);
16.108 +}
16.109 +""" % (
16.110 + encode_instantiator_pointer(path),
16.111 + )
16.112 +
16.113 + # Generic instantiation support.
16.114 +
16.115 + else:
16.116 + print >>f_code, """\
16.117 __attr %s(__attr __self%s)
16.118 {
16.119 return %s(__NEWINSTANCE(%s)%s);
16.120 }
16.121 """ % (
16.122 - encode_instantiator_pointer(path),
16.123 - l and ", %s" % ",".join(l) or "",
16.124 - encode_function_pointer(initialiser),
16.125 - encode_path(path),
16.126 - parameters and ", %s" % ", ".join(parameters) or ""
16.127 - )
16.128 + encode_instantiator_pointer(path),
16.129 + l and ", %s" % ",".join(l) or "",
16.130 + encode_function_pointer(initialiser),
16.131 + encode_path(path),
16.132 + parameters and ", %s" % ", ".join(parameters) or ""
16.133 + )
16.134
16.135 # Signature: __new_typename(__attr __self, ...)
16.136
16.137 @@ -1332,6 +1365,6 @@
16.138
16.139 return 0;
16.140 }
16.141 -""" % encode_function_pointer("__builtins__.str.str")
16.142 +""" % encode_instantiator_pointer("__builtins__.str.str")
16.143
16.144 # vim: tabstop=4 expandtab shiftwidth=4
17.1 --- a/inspector.py Mon Jan 28 21:16:56 2019 +0100
17.2 +++ b/inspector.py Tue Aug 22 19:36:13 2023 +0200
17.3 @@ -3,8 +3,7 @@
17.4 """
17.5 Inspect and obtain module structure.
17.6
17.7 -Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013,
17.8 - 2014, 2015, 2016, 2017, 2018 Paul Boddie <paul@boddie.org.uk>
17.9 +Copyright (C) 2007-2019, 2021 Paul Boddie <paul@boddie.org.uk>
17.10
17.11 This program is free software; you can redistribute it and/or modify it under
17.12 the terms of the GNU General Public License as published by the Free Software
17.13 @@ -78,13 +77,13 @@
17.14
17.15 ref = self.get_builtin("module")
17.16 self.set_name("__class__", ref)
17.17 - self.set_name("__name__", self.get_constant("string", self.name).reference())
17.18 - self.set_name("__file__", self.get_constant("string", filename).reference())
17.19 + self.set_name("__name__", self.get_constant("str", self.name).reference())
17.20 + self.set_name("__file__", self.get_constant("str", filename).reference())
17.21
17.22 # Reserve a constant for the encoding.
17.23
17.24 if self.encoding:
17.25 - self.get_constant("string", self.encoding)
17.26 + self.get_constant("str", self.encoding)
17.27
17.28 # Get module-level attribute usage details.
17.29
17.30 @@ -531,7 +530,7 @@
17.31 # Provide leafname, parent and context attributes.
17.32
17.33 parent, leafname = class_name.rsplit(".", 1)
17.34 - self.set_name("__name__", self.get_constant("string", leafname).reference())
17.35 + self.set_name("__name__", self.get_constant("str", leafname).reference())
17.36
17.37 if class_name != "__builtins__.core.function":
17.38 self.set_name("__parent__")
17.39 @@ -659,6 +658,9 @@
17.40 self.function_defaults[function_name] = []
17.41
17.42 for argname, default in compiler.ast.get_defaults(n):
17.43 + if argname[0] == ".":
17.44 + argname = argname[1:]
17.45 +
17.46 if default:
17.47
17.48 # Obtain any reference for the default.
17.49 @@ -678,7 +680,7 @@
17.50
17.51 # Define a leafname attribute value for the function instance.
17.52
17.53 - ref = self.get_builtin_class("string")
17.54 + ref = self.get_builtin_class("str")
17.55 self.reserve_constant(function_name, name, ref.get_origin())
17.56
17.57 # Track attribute usage within the namespace.
18.1 --- a/internal_tests/branches.py Mon Jan 28 21:16:56 2019 +0100
18.2 +++ b/internal_tests/branches.py Tue Aug 22 19:36:13 2023 +0200
18.3 @@ -687,4 +687,77 @@
18.4 bt.get_assignment_positions_for_branches("a", ar)
18.5 names.append(bt.assignments["a"])
18.6
18.7 +# This demonstrates why the assignment in a "for" loop construct must appear
18.8 +# outside the inner "try" body: null usage escapes the loop via the exception
18.9 +# handler and the raise statement, even though the assignment would only be
18.10 +# valid otherwise.
18.11 +
18.12 +# Equivalent to...
18.13 +#
18.14 +# try:
18.15 +# while ...:
18.16 +# try:
18.17 +# a = ...
18.18 +# except:
18.19 +# raise ...
18.20 +# a.p
18.21 +# except:
18.22 +# pass
18.23 +
18.24 +bt = branching.BranchTracker()
18.25 +bt.new_branchpoint() # begin (try)
18.26 +bt.new_branchpoint(True) # begin (while)
18.27 +bt.new_branch(True) # while ...
18.28 +bt.new_branchpoint() # begin (try)
18.29 +a = bt.assign_names(["a"])
18.30 +bt.resume_abandoned_branches() # except
18.31 +bt.abandon_branch() # raise
18.32 +bt.shelve_branch()
18.33 +bt.new_branch() # (null)
18.34 +bt.shelve_branch()
18.35 +bt.merge_branches() # end (try)
18.36 +ap = bt.use_attribute("a", "p")
18.37 +bt.resume_continuing_branches()
18.38 +bt.shelve_branch(True)
18.39 +bt.new_branch() # (null)
18.40 +bt.shelve_branch()
18.41 +bt.merge_branches() # end (while)
18.42 +bt.resume_broken_branches()
18.43 +bt.resume_abandoned_branches() # except
18.44 +bt.shelve_branch()
18.45 +bt.new_branch() # (null)
18.46 +bt.shelve_branch()
18.47 +bt.merge_branches() # end (try)
18.48 +
18.49 +print simple_usage(a) == \
18.50 + {'a' : set([('p',), ()])}, simple_usage(a)
18.51 +print bt.get_assignment_positions_for_branches("a", ap) == [0], \
18.52 + bt.get_assignment_positions_for_branches("a", ap)
18.53 +names.append(bt.assignments["a"])
18.54 +
18.55 +# Equivalent to...
18.56 +#
18.57 +# b = ...
18.58 +# while ...:
18.59 +# a = ...
18.60 +# a.p
18.61 +
18.62 +bt = branching.BranchTracker()
18.63 +bt.new_branchpoint(True) # begin
18.64 +b = bt.assign_names(["b"])
18.65 +bt.new_branch(True) # while ...
18.66 +a = bt.assign_names(["a"])
18.67 +ap = bt.use_attribute("a", "p")
18.68 +bt.resume_continuing_branches()
18.69 +bt.shelve_branch(True)
18.70 +bt.new_branch() # (null)
18.71 +bt.shelve_branch()
18.72 +bt.merge_branches() # end
18.73 +
18.74 +print simple_usage(a) == \
18.75 + {'a' : set([('p',)])}, simple_usage(a)
18.76 +print bt.get_assignment_positions_for_branches("a", ap) == [0], \
18.77 + bt.get_assignment_positions_for_branches("a", ap)
18.78 +names.append(bt.assignments["a"])
18.79 +
18.80 # vim: tabstop=4 expandtab shiftwidth=4
19.1 --- a/lib/__builtins__/__init__.py Mon Jan 28 21:16:56 2019 +0100
19.2 +++ b/lib/__builtins__/__init__.py Tue Aug 22 19:36:13 2023 +0200
19.3 @@ -3,7 +3,7 @@
19.4 """
19.5 Simple built-in classes and functions.
19.6
19.7 -Copyright (C) 2015, 2016, 2017, 2019 Paul Boddie <paul@boddie.org.uk>
19.8 +Copyright (C) 2015, 2016, 2017, 2019, 2021 Paul Boddie <paul@boddie.org.uk>
19.9
19.10 This program is free software; you can redistribute it and/or modify it under
19.11 the terms of the GNU General Public License as published by the Free Software
19.12 @@ -68,9 +68,9 @@
19.13 from __builtins__.none import None, NoneType
19.14 from __builtins__.notimplemented import NotImplemented, NotImplementedType
19.15 from __builtins__.set import frozenset, set
19.16 -from __builtins__.str import basestring, str, string
19.17 +from __builtins__.str import basestring, str
19.18 from __builtins__.tuple import tuple
19.19 -from __builtins__.unicode import unicode, utf8string
19.20 +from __builtins__.unicode import unicode
19.21
19.22 # Functions.
19.23
20.1 --- a/lib/__builtins__/buffer.py Mon Jan 28 21:16:56 2019 +0100
20.2 +++ b/lib/__builtins__/buffer.py Tue Aug 22 19:36:13 2023 +0200
20.3 @@ -53,7 +53,7 @@
20.4
20.5 if isinstance(s, buffer):
20.6 list_concat(self, s.__data__)
20.7 - elif isinstance(s, string):
20.8 + elif isinstance(s, str):
20.9 list_append(self, s)
20.10 else:
20.11 list_append(self, str(s))
21.1 --- a/lib/__builtins__/character.py Mon Jan 28 21:16:56 2019 +0100
21.2 +++ b/lib/__builtins__/character.py Tue Aug 22 19:36:13 2023 +0200
21.3 @@ -103,7 +103,7 @@
21.4 check_int(i)
21.5
21.6 if 0 <= i <= 2097151:
21.7 - return utf8string(unicode_unichr(i))
21.8 + return unicode(unicode_unichr(i))
21.9 else:
21.10 raise ValueError, i
21.11
22.1 --- a/lib/__builtins__/exception/base.py Mon Jan 28 21:16:56 2019 +0100
22.2 +++ b/lib/__builtins__/exception/base.py Tue Aug 22 19:36:13 2023 +0200
22.3 @@ -71,7 +71,11 @@
22.4
22.5 "An exception signalling the end of iteration."
22.6
22.7 - pass
22.8 + def __init__(self, .iterator=None):
22.9 +
22.10 + "Initialise the exception with the given 'iterator'."
22.11 +
22.12 + pass
22.13
22.14 class ValueError(Exception):
22.15
23.1 --- a/lib/__builtins__/float.py Mon Jan 28 21:16:56 2019 +0100
23.2 +++ b/lib/__builtins__/float.py Tue Aug 22 19:36:13 2023 +0200
23.3 @@ -3,7 +3,7 @@
23.4 """
23.5 Floating point number objects.
23.6
23.7 -Copyright (C) 2015, 2016, 2018 Paul Boddie <paul@boddie.org.uk>
23.8 +Copyright (C) 2015, 2016, 2018, 2021 Paul Boddie <paul@boddie.org.uk>
23.9
23.10 This program is free software; you can redistribute it and/or modify it under
23.11 the terms of the GNU General Public License as published by the Free Software
23.12 @@ -19,7 +19,7 @@
23.13 this program. If not, see <http://www.gnu.org/licenses/>.
23.14 """
23.15
23.16 -from __builtins__.unicode import utf8string
23.17 +from __builtins__.unicode import unicode
23.18 from native import isinstance as _isinstance, \
23.19 int_float, is_int, \
23.20 float_add, float_div, float_eq, float_ge, float_gt, \
23.21 @@ -194,7 +194,7 @@
23.22
23.23 "Return a string representation."
23.24
23.25 - return utf8string(float_str(self))
23.26 + return unicode(float_str(self))
23.27
23.28 __repr__ = __str__
23.29
24.1 --- a/lib/__builtins__/int.py Mon Jan 28 21:16:56 2019 +0100
24.2 +++ b/lib/__builtins__/int.py Tue Aug 22 19:36:13 2023 +0200
24.3 @@ -3,7 +3,7 @@
24.4 """
24.5 Integer objects.
24.6
24.7 -Copyright (C) 2015, 2016, 2017, 2018 Paul Boddie <paul@boddie.org.uk>
24.8 +Copyright (C) 2015, 2016, 2017, 2018, 2021 Paul Boddie <paul@boddie.org.uk>
24.9
24.10 This program is free software; you can redistribute it and/or modify it under
24.11 the terms of the GNU General Public License as published by the Free Software
24.12 @@ -19,22 +19,55 @@
24.13 this program. If not, see <http://www.gnu.org/licenses/>.
24.14 """
24.15
24.16 -from __builtins__.unicode import utf8string
24.17 +from __builtins__.str import basestring
24.18 +from __builtins__.unicode import unicode
24.19 from native import get_maxint, get_minint, is_int, \
24.20 int_add, int_and, int_div, int_eq, int_ge, int_gt, \
24.21 int_lshift, int_le, int_lt, int_mod, int_mul, int_ne, \
24.22 int_neg, int_not, int_or, int_pow, int_rshift, int_str, \
24.23 int_sub, int_xor
24.24
24.25 +def new_int(number_or_string, base=10):
24.26 +
24.27 + "Initialise the integer with the given 'number_or_string'."
24.28 +
24.29 + if is_int(number_or_string):
24.30 + return number_or_string
24.31 + elif isinstance(number_or_string, basestring):
24.32 + return str_to_int(number_or_string, base)
24.33 + else:
24.34 + raise TypeError
24.35 +
24.36 +def str_to_int(value, base=10):
24.37 +
24.38 + "Decode the string 'value' using the given 'base'."
24.39 +
24.40 + # NOTE: Add support for lower and upper in the string classes.
24.41 +
24.42 + #value = value.lower()
24.43 + len_value = len(value)
24.44 + digits = "0123456789abcdefghijklmnopqrstuvwxyz"
24.45 +
24.46 + result = 0
24.47 + i = 0
24.48 +
24.49 + while i < len_value:
24.50 + c = value[i]
24.51 + d = digits.index(c)
24.52 + result = result * base + d
24.53 + i += 1
24.54 +
24.55 + return result
24.56 +
24.57 class int:
24.58
24.59 "An integer abstraction."
24.60
24.61 - def __init__(self, number_or_string=None):
24.62 + def __init__(self, number_or_string=None, base=10):
24.63
24.64 "Initialise the integer with the given 'number_or_string'."
24.65
24.66 - # NOTE: To be implemented.
24.67 + # Implemented by new_int above, invoked specially by the translator.
24.68
24.69 pass
24.70
24.71 @@ -245,7 +278,7 @@
24.72
24.73 "Return a string representation."
24.74
24.75 - return utf8string(int_str(self))
24.76 + return unicode(int_str(self))
24.77
24.78 __repr__ = __str__
24.79
25.1 --- a/lib/__builtins__/iteration/iterator.py Mon Jan 28 21:16:56 2019 +0100
25.2 +++ b/lib/__builtins__/iteration/iterator.py Tue Aug 22 19:36:13 2023 +0200
25.3 @@ -3,7 +3,7 @@
25.4 """
25.5 Iterator objects.
25.6
25.7 -Copyright (C) 2015, 2016 Paul Boddie <paul@boddie.org.uk>
25.8 +Copyright (C) 2015, 2016, 2019 Paul Boddie <paul@boddie.org.uk>
25.9
25.10 This program is free software; you can redistribute it and/or modify it under
25.11 the terms of the GNU General Public License as published by the Free Software
25.12 @@ -39,6 +39,6 @@
25.13 self.i += 1
25.14 return value
25.15 except IndexError:
25.16 - raise StopIteration()
25.17 + raise StopIteration, self
25.18
25.19 # vim: tabstop=4 expandtab shiftwidth=4
26.1 --- a/lib/__builtins__/set.py Mon Jan 28 21:16:56 2019 +0100
26.2 +++ b/lib/__builtins__/set.py Tue Aug 22 19:36:13 2023 +0200
26.3 @@ -3,7 +3,7 @@
26.4 """
26.5 Set objects.
26.6
26.7 -Copyright (C) 2015, 2016, 2017 Paul Boddie <paul@boddie.org.uk>
26.8 +Copyright (C) 2015, 2016, 2017, 2019 Paul Boddie <paul@boddie.org.uk>
26.9
26.10 This program is free software; you can redistribute it and/or modify it under
26.11 the terms of the GNU General Public License as published by the Free Software
26.12 @@ -323,7 +323,7 @@
26.13 try:
26.14 bucket = self.mapping.buckets[self.index]
26.15 except IndexError:
26.16 - raise StopIteration
26.17 + raise StopIteration, self
26.18
26.19 # Access the current item. If no such item exists, get another
26.20 # bucket.
27.1 --- a/lib/__builtins__/span.py Mon Jan 28 21:16:56 2019 +0100
27.2 +++ b/lib/__builtins__/span.py Tue Aug 22 19:36:13 2023 +0200
27.3 @@ -3,7 +3,7 @@
27.4 """
27.5 Span-related objects.
27.6
27.7 -Copyright (C) 2015, 2016, 2017, 2018 Paul Boddie <paul@boddie.org.uk>
27.8 +Copyright (C) 2015, 2016, 2017, 2018, 2019 Paul Boddie <paul@boddie.org.uk>
27.9
27.10 This program is free software; you can redistribute it and/or modify it under
27.11 the terms of the GNU General Public License as published by the Free Software
27.12 @@ -101,7 +101,7 @@
27.13 "Return the next item or raise a StopIteration exception."
27.14
27.15 if not self.count:
27.16 - raise StopIteration
27.17 + raise StopIteration, self
27.18
27.19 current = self.current
27.20 self.current = self.current.__add__(self.step)
28.1 --- a/lib/__builtins__/str.py Mon Jan 28 21:16:56 2019 +0100
28.2 +++ b/lib/__builtins__/str.py Tue Aug 22 19:36:13 2023 +0200
28.3 @@ -3,7 +3,7 @@
28.4 """
28.5 String objects.
28.6
28.7 -Copyright (C) 2015, 2016, 2017 Paul Boddie <paul@boddie.org.uk>
28.8 +Copyright (C) 2015, 2016, 2017, 2021 Paul Boddie <paul@boddie.org.uk>
28.9
28.10 This program is free software; you can redistribute it and/or modify it under
28.11 the terms of the GNU General Public License as published by the Free Software
28.12 @@ -24,7 +24,7 @@
28.13 from __builtins__.types import check_int
28.14 from native import isinstance as _isinstance, \
28.15 str_add, str_lt, str_gt, str_eq, str_ord, \
28.16 - str_substr
28.17 + str_size, str_substr
28.18
28.19 WHITESPACE = (" ", "\f", "\n", "\r", "\t")
28.20
28.21 @@ -54,7 +54,7 @@
28.22 else:
28.23 self.__data__ = None
28.24 self.__key__ = None
28.25 - self.__size__ = 0
28.26 + self.__size__ = None
28.27
28.28 # Internal methods.
28.29
28.30 @@ -158,7 +158,7 @@
28.31
28.32 "Return the number of bytes in this string."
28.33
28.34 - return self.__size__
28.35 + return str_size(self.__size__)
28.36
28.37 # General type methods.
28.38
28.39 @@ -166,7 +166,7 @@
28.40
28.41 "Return whether the string provides any data."
28.42
28.43 - return self.__size__.__bool__()
28.44 + return str_size(self.__size__).__bool__()
28.45
28.46 def __contains__(self, value):
28.47
28.48 @@ -576,7 +576,7 @@
28.49
28.50 def upper(self): pass
28.51
28.52 -class string(basestring):
28.53 +class str(basestring):
28.54
28.55 "A plain string of bytes."
28.56
28.57 @@ -607,7 +607,7 @@
28.58 l = get_using(basestring.__get_multiple_items__, self)(start, end, step)
28.59 return "".join(l)
28.60
28.61 -def str(obj):
28.62 +def new_str(obj):
28.63
28.64 "Return the string representation of 'obj'."
28.65
29.1 --- a/lib/__builtins__/stream.py Mon Jan 28 21:16:56 2019 +0100
29.2 +++ b/lib/__builtins__/stream.py Tue Aug 22 19:36:13 2023 +0200
29.3 @@ -144,7 +144,7 @@
29.4 # Encode text as bytes if necessary. When the encoding is not set, any
29.5 # original encoding of the text will be applied.
29.6
29.7 - if _isinstance(s, utf8string):
29.8 + if _isinstance(s, unicode):
29.9 s = s.encode(self.encoding)
29.10
29.11 fwrite(self.__data__, s)
30.1 --- a/lib/__builtins__/unicode.py Mon Jan 28 21:16:56 2019 +0100
30.2 +++ b/lib/__builtins__/unicode.py Tue Aug 22 19:36:13 2023 +0200
30.3 @@ -3,7 +3,7 @@
30.4 """
30.5 Unicode objects.
30.6
30.7 -Copyright (C) 2015, 2016, 2017 Paul Boddie <paul@boddie.org.uk>
30.8 +Copyright (C) 2015, 2016, 2017, 2021 Paul Boddie <paul@boddie.org.uk>
30.9
30.10 This program is free software; you can redistribute it and/or modify it under
30.11 the terms of the GNU General Public License as published by the Free Software
30.12 @@ -25,21 +25,58 @@
30.13 from native import str_add, unicode_len, unicode_ord, unicode_substr, \
30.14 isinstance as _isinstance
30.15
30.16 -class utf8string(basestring):
30.17 +class unicode(basestring):
30.18
30.19 "A character string representation based on UTF-8."
30.20
30.21 - def __init__(self, other=None, encoding=None):
30.22 + def __init__(self, s, encoding=None, original=None):
30.23
30.24 """
30.25 - Initialise the string, perhaps from 'other', with any original
30.26 - 'encoding' indicated.
30.27 + Initialise the string from 'other', employing any indicated 'encoding'
30.28 + for the provided string data.
30.29 +
30.30 + If 'original' is indicated, this may be used to override the original
30.31 + encoding. This is useful when the string data is already in UTF-8
30.32 + format, but where the original encoding needs to be communicated.
30.33 """
30.34
30.35 - get_using(basestring.__init__, self)(other)
30.36 - self.encoding = encoding
30.37 self.length = None
30.38
30.39 + # Initialise using another Unicode object.
30.40 +
30.41 + if _isinstance(s, unicode):
30.42 + get_using(basestring.__init__, self)(s)
30.43 + self.encoding = s.encoding
30.44 +
30.45 + # Initialise using suitable string data but with an explicit original
30.46 + # encoding.
30.47 +
30.48 + elif original:
30.49 + get_using(basestring.__init__, self)(s)
30.50 + self.encoding = original
30.51 +
30.52 + # Initialise using string data having either UTF-8 or another encoding,
30.53 + # converting to UTF-8 and retaining the encoding details as the original
30.54 + # encoding.
30.55 +
30.56 + else:
30.57 + # Obtain a string representation.
30.58 +
30.59 + s = s.__str__()
30.60 +
30.61 + # Convert the string to UTF-8. Even if the stated encoding is UTF-8, it
30.62 + # needs to be validated.
30.63 +
30.64 + to_utf8 = Converter(encoding or "UTF-8", "UTF-8")
30.65 +
30.66 + try:
30.67 + to_utf8.feed(s)
30.68 + get_using(basestring.__init__, self)(str(to_utf8))
30.69 + finally:
30.70 + to_utf8.close()
30.71 +
30.72 + self.encoding = encoding
30.73 +
30.74 def _binary_op(self, op, other, sizes=False):
30.75
30.76 "Perform 'op' on this object and 'other' if appropriate."
30.77 @@ -51,7 +88,7 @@
30.78
30.79 # Combining text with bytes.
30.80
30.81 - if not _isinstance(other, utf8string):
30.82 + if not _isinstance(other, unicode):
30.83 s = self.encode()
30.84 else:
30.85 s = self
30.86 @@ -72,7 +109,7 @@
30.87
30.88 # Combining text with bytes.
30.89
30.90 - if not _isinstance(other, utf8string):
30.91 + if not _isinstance(other, unicode):
30.92 s = self.encode()
30.93 else:
30.94 s = self
30.95 @@ -86,8 +123,8 @@
30.96
30.97 "Convert 'result' to a Unicode object if 'other' already is."
30.98
30.99 - if _isinstance(other, utf8string):
30.100 - return utf8string(result, self.encoding)
30.101 + if _isinstance(other, unicode):
30.102 + return unicode(result, None, self.encoding)
30.103 else:
30.104 return result
30.105
30.106 @@ -188,15 +225,14 @@
30.107 elif nonempty:
30.108 b.append(self)
30.109
30.110 - if _isinstance(s, utf8string):
30.111 + if _isinstance(s, unicode):
30.112 encoding = None
30.113
30.114 b.append(s)
30.115
30.116 s = str(b)
30.117 if encoding:
30.118 - s = utf8string(s)
30.119 - s.encoding = encoding
30.120 + s = unicode(s, None, encoding)
30.121 return s
30.122
30.123 # Special implementation methods.
30.124 @@ -204,9 +240,9 @@
30.125 def __get_single_item__(self, index):
30.126
30.127 "Return the item at the normalised (positive) 'index'."
30.128 -
30.129 +
30.130 self._check_index(index)
30.131 - return utf8string(unicode_substr(self.__data__, self.__size__, index, index + 1, 1), self.encoding)
30.132 + return unicode(unicode_substr(self.__data__, self.__size__, index, index + 1, 1), None, self.encoding)
30.133
30.134 def __get_multiple_items__(self, start, end, step):
30.135
30.136 @@ -224,29 +260,6 @@
30.137 raise ValueError(step)
30.138
30.139 l = get_using(basestring.__get_multiple_items__, self)(start, end, step)
30.140 - return utf8string("".join(l), self.encoding)
30.141 -
30.142 -def unicode(s, encoding):
30.143 -
30.144 - "Convert 's' to a Unicode object, interpreting 's' as using 'encoding'."
30.145 -
30.146 - if isinstance(s, utf8string):
30.147 - return s
30.148 -
30.149 - # Obtain a string representation.
30.150 -
30.151 - s = s.__str__()
30.152 -
30.153 - # Convert the string to UTF-8. Even if the stated encoding is UTF-8, it
30.154 - # needs to be validated.
30.155 -
30.156 - to_utf8 = Converter(encoding, "UTF-8")
30.157 -
30.158 - try:
30.159 - to_utf8.feed(s)
30.160 - return utf8string(str(to_utf8), encoding)
30.161 -
30.162 - finally:
30.163 - to_utf8.close()
30.164 + return unicode("".join(l), None, self.encoding)
30.165
30.166 # vim: tabstop=4 expandtab shiftwidth=4
31.1 --- a/lib/native/__init__.py Mon Jan 28 21:16:56 2019 +0100
31.2 +++ b/lib/native/__init__.py Tue Aug 22 19:36:13 2023 +0200
31.3 @@ -3,7 +3,7 @@
31.4 """
31.5 Native library functions.
31.6
31.7 -Copyright (C) 2011, 2015, 2016, 2017, 2018 Paul Boddie <paul@boddie.org.uk>
31.8 +Copyright (C) 2011, 2015-2018, 2021 Paul Boddie <paul@boddie.org.uk>
31.9
31.10 This program is free software; you can redistribute it and/or modify it under
31.11 the terms of the GNU General Public License as published by the Free Software
31.12 @@ -51,7 +51,7 @@
31.13 from native.program import get_using
31.14
31.15 from native.str import str_add, str_chr, str_eq, str_gt, str_lt, \
31.16 - str_ord, str_substr
31.17 + str_ord, str_size, str_substr
31.18
31.19 from native.system import exit, get_argv, get_path
31.20
32.1 --- a/lib/native/str.py Mon Jan 28 21:16:56 2019 +0100
32.2 +++ b/lib/native/str.py Tue Aug 22 19:36:13 2023 +0200
32.3 @@ -8,7 +8,7 @@
32.4 non-core exceptions used by the native functions because they need to be
32.5 identified as being needed by the program.
32.6
32.7 -Copyright (C) 2011, 2015, 2016, 2017 Paul Boddie <paul@boddie.org.uk>
32.8 +Copyright (C) 2011, 2015, 2016, 2017, 2021 Paul Boddie <paul@boddie.org.uk>
32.9
32.10 This program is free software; you can redistribute it and/or modify it under
32.11 the terms of the GNU General Public License as published by the Free Software
32.12 @@ -32,6 +32,7 @@
32.13 def str_gt(data, other_data): return True or False
32.14 def str_lt(data, other_data): return True or False
32.15 def str_ord(data): return 0
32.16 +def str_size(size): return 0
32.17 def str_substr(data, start, end, step): return ""
32.18
32.19 # vim: tabstop=4 expandtab shiftwidth=4
33.1 --- a/lib/operator/binary.py Mon Jan 28 21:16:56 2019 +0100
33.2 +++ b/lib/operator/binary.py Tue Aug 22 19:36:13 2023 +0200
33.3 @@ -25,7 +25,8 @@
33.4 int_lshift, int_rshift, \
33.5 int_and, int_not, int_or, int_xor, \
33.6 is_int, \
33.7 - float_add, float_div, float_mul, float_pow, float_sub
33.8 + float_add, float_div, float_mul, float_pow, float_sub, \
33.9 + int_float
33.10
33.11 # These functions defer method lookup by wrapping the attribute access in
33.12 # lambda functions. Thus, the appropriate methods are defined locally, but no
33.13 @@ -89,8 +90,11 @@
33.14 def pow(a, b):
33.15 if is_int(a) and is_int(b):
33.16 return int_pow(a, b)
33.17 - elif a.__class__ is float and b.__class__ is float:
33.18 - return float_pow(a, b)
33.19 + elif a.__class__ is float:
33.20 + if is_int(b):
33.21 + return float_pow(a, int_float(b))
33.22 + if b.__class__ is float:
33.23 + return float_pow(a, b)
33.24 return binary_op(a, b, lambda a: a.__pow__, lambda b: b.__rpow__)
33.25
33.26 def rshift(a, b):
34.1 --- a/lplc Mon Jan 28 21:16:56 2019 +0100
34.2 +++ b/lplc Tue Aug 22 19:36:13 2023 +0200
34.3 @@ -3,7 +3,7 @@
34.4 """
34.5 Lichen Python-like compiler tool.
34.6
34.7 -Copyright (C) 2016, 2017, 2018 Paul Boddie <paul@boddie.org.uk>
34.8 +Copyright (C) 2016-2018, 2021 Paul Boddie <paul@boddie.org.uk>
34.9
34.10 This program is free software; you can redistribute it and/or modify it under
34.11 the terms of the GNU General Public License as published by the Free Software
34.12 @@ -151,6 +151,7 @@
34.13 Some options may be followed by values, either immediately after the option
34.14 (without any space between) or in the arguments that follow them:
34.15
34.16 +-j Number of processes to be used when compiling
34.17 -o Indicate the output executable name
34.18 -W Show warnings on the topics indicated
34.19
34.20 @@ -190,8 +191,7 @@
34.21 elif "--version" in args or "-V" in args:
34.22 print >>sys.stderr, """\
34.23 lplc %s
34.24 -Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013,
34.25 - 2014, 2015, 2016, 2017 Paul Boddie <paul@boddie.org.uk>
34.26 +Copyright (C) 2006-2018, 2021 Paul Boddie <paul@boddie.org.uk>
34.27 This program is free software; you may redistribute it under the terms of
34.28 the GNU General Public License version 3 or (at your option) a later version.
34.29 This program has absolutely no warranty.
34.30 @@ -206,6 +206,7 @@
34.31 gc_sections = False
34.32 ignore_env = False
34.33 make = True
34.34 + make_processes = []
34.35 make_verbose = True
34.36 outputs = []
34.37 paramnames = []
34.38 @@ -232,6 +233,7 @@
34.39 elif arg in ("-E", "--no-env"): ignore_env = True
34.40 elif arg in ("-g", "--debug"): debug = True
34.41 elif arg in ("-G", "--gc-sections"): gc_sections = True
34.42 + elif arg.startswith("-j"): l, needed = start_arg_list(make_processes, arg, 1)
34.43 # "P" handled below.
34.44 elif arg.startswith("--param-codes"): l, needed = start_arg_list(paramnames, arg, 1)
34.45 elif arg.startswith("--param-locations"): l, needed = start_arg_list(paramlocations, arg, 1)
34.46 @@ -353,7 +355,8 @@
34.47 # Compile the program unless otherwise indicated.
34.48
34.49 if make:
34.50 - make_clean_cmd = ["make", "-C", generated_dir, "clean"]
34.51 + processes = make_processes and ["-j"] + make_processes or []
34.52 + make_clean_cmd = ["make", "-C", generated_dir] + processes + ["clean"]
34.53 make_cmd = make_clean_cmd[:-1]
34.54
34.55 retval = call(make_cmd, make_verbose)
35.1 --- a/templates/native/buffer.c Mon Jan 28 21:16:56 2019 +0100
35.2 +++ b/templates/native/buffer.c Tue Aug 22 19:36:13 2023 +0200
35.3 @@ -1,6 +1,6 @@
35.4 /* Native functions for buffer operations.
35.5
35.6 -Copyright (C) 2016, 2017 Paul Boddie <paul@boddie.org.uk>
35.7 +Copyright (C) 2016, 2017, 2021 Paul Boddie <paul@boddie.org.uk>
35.8
35.9 This program is free software; you can redistribute it and/or modify it under
35.10 the terms of the GNU General Public License as published by the Free Software
35.11 @@ -30,13 +30,13 @@
35.12 {
35.13 /* _data interpreted as buffer.__data__ */
35.14 __fragment *data = _data.seqvalue;
35.15 - unsigned int size = 0, i, j, n;
35.16 + __int size = 0, i, j, n;
35.17 char *s;
35.18 __attr o;
35.19
35.20 /* Calculate the size of the string. */
35.21 for (i = 0; i < data->size; i++)
35.22 - size += __TOINT(__load_via_object(__VALUE(data->attrs[i]), __size__));
35.23 + size += __load_via_object(__VALUE(data->attrs[i]), __size__).sizevalue;
35.24
35.25 /* Reserve space for a new string. */
35.26 s = (char *) __ALLOCATE(size + 1, sizeof(char));
35.27 @@ -45,7 +45,7 @@
35.28 for (i = 0, j = 0; i < data->size; i++)
35.29 {
35.30 o = __load_via_object(__VALUE(data->attrs[i]), __data__);
35.31 - n = __TOINT(__load_via_object(__VALUE(data->attrs[i]), __size__));
35.32 + n = __load_via_object(__VALUE(data->attrs[i]), __size__).sizevalue;
35.33 memcpy(s + j, o.strvalue, n); /* does not null terminate but final byte should be zero */
35.34 j += n;
35.35 }
36.1 --- a/templates/native/common.c Mon Jan 28 21:16:56 2019 +0100
36.2 +++ b/templates/native/common.c Tue Aug 22 19:36:13 2023 +0200
36.3 @@ -1,6 +1,6 @@
36.4 /* Common operations for native functions.
36.5
36.6 -Copyright (C) 2016, 2017, 2018 Paul Boddie <paul@boddie.org.uk>
36.7 +Copyright (C) 2016, 2017, 2018, 2021 Paul Boddie <paul@boddie.org.uk>
36.8
36.9 This program is free software; you can redistribute it and/or modify it under
36.10 the terms of the GNU General Public License as published by the Free Software
36.11 @@ -26,12 +26,12 @@
36.12
36.13 /* Utility functions. */
36.14
36.15 -__attr __new_str(char *s, int size)
36.16 +__attr __new_str(char *s, __int size)
36.17 {
36.18 /* Create a new string and mutate the __data__, __size__ and __key__ attributes. */
36.19 - __attr attr = __NEWINSTANCE(__builtins___str_string);
36.20 + __attr attr = __NEWINSTANCE(__builtins___str_str);
36.21 __store_via_object(__VALUE(attr), __data__, (__attr) {.strvalue=s});
36.22 - __store_via_object(__VALUE(attr), __size__, __INTVALUE(size));
36.23 + __store_via_object(__VALUE(attr), __size__, (__attr) {.sizevalue=size});
36.24 __store_via_object(__VALUE(attr), __key__, __NULL);
36.25 return attr;
36.26 }
36.27 @@ -55,8 +55,8 @@
36.28 __fragment *__fragment_append(__fragment *data, __attr value)
36.29 {
36.30 __fragment *newdata = data;
36.31 - unsigned int size = data->size, capacity = data->capacity;
36.32 - unsigned int n;
36.33 + __int size = data->size, capacity = data->capacity;
36.34 + __int n;
36.35
36.36 /* Re-allocate the fragment if the capacity has been reached. */
36.37 if (size >= capacity)
37.1 --- a/templates/native/common.h Mon Jan 28 21:16:56 2019 +0100
37.2 +++ b/templates/native/common.h Tue Aug 22 19:36:13 2023 +0200
37.3 @@ -1,6 +1,6 @@
37.4 /* Common operations for native functions.
37.5
37.6 -Copyright (C) 2016, 2017, 2018 Paul Boddie <paul@boddie.org.uk>
37.7 +Copyright (C) 2016, 2017, 2018, 2021 Paul Boddie <paul@boddie.org.uk>
37.8
37.9 This program is free software; you can redistribute it and/or modify it under
37.10 the terms of the GNU General Public License as published by the Free Software
37.11 @@ -27,7 +27,7 @@
37.12
37.13 /* Utility functions. */
37.14
37.15 -__attr __new_str(char *s, int size);
37.16 +__attr __new_str(char *s, __int size);
37.17 __attr __new_list(__fragment *f);
37.18 __attr __new_float(double n);
37.19 __fragment *__fragment_append(__fragment *data, __attr value);
38.1 --- a/templates/native/iconv.c Mon Jan 28 21:16:56 2019 +0100
38.2 +++ b/templates/native/iconv.c Tue Aug 22 19:36:13 2023 +0200
38.3 @@ -1,6 +1,6 @@
38.4 /* Native functions for character set conversion.
38.5
38.6 -Copyright (C) 2016, 2017 Paul Boddie <paul@boddie.org.uk>
38.7 +Copyright (C) 2016, 2017, 2021 Paul Boddie <paul@boddie.org.uk>
38.8
38.9 This program is free software; you can redistribute it and/or modify it under
38.10 the terms of the GNU General Public License as published by the Free Software
38.11 @@ -56,8 +56,8 @@
38.12 /* Obtain the string, start position, and remaining bytes from the state. */
38.13
38.14 char *inbuf = __load_via_object(__VALUE(f->attrs[0]), __data__).strvalue;
38.15 - int start = __TOINT(f->attrs[1]);
38.16 - int remaining = __TOINT(f->attrs[2]);
38.17 + __int start = __TOINT(f->attrs[1]);
38.18 + __int remaining = __TOINT(f->attrs[2]);
38.19
38.20 /* Allocate a string for the output buffer using the remaining input size
38.21 as a guide. */
39.1 --- a/templates/native/int.c Mon Jan 28 21:16:56 2019 +0100
39.2 +++ b/templates/native/int.c Tue Aug 22 19:36:13 2023 +0200
39.3 @@ -1,6 +1,6 @@
39.4 /* Native functions for integer operations.
39.5
39.6 -Copyright (C) 2016, 2017, 2018 Paul Boddie <paul@boddie.org.uk>
39.7 +Copyright (C) 2016, 2017, 2018, 2021 Paul Boddie <paul@boddie.org.uk>
39.8
39.9 This program is free software; you can redistribute it and/or modify it under
39.10 the terms of the GNU General Public License as published by the Free Software
39.11 @@ -39,8 +39,8 @@
39.12 __attr __fn_native_int_int_add(__attr __self, __attr self, __attr other)
39.13 {
39.14 /* self and other interpreted as int */
39.15 - int i = __TOINT(self);
39.16 - int j = __TOINT(other);
39.17 + __int i = __TOINT(self);
39.18 + __int j = __TOINT(other);
39.19
39.20 /* Test for overflow. */
39.21 if (((i > 0) && (j > 0) && (i > __MAXINT - j)) ||
39.22 @@ -55,8 +55,8 @@
39.23 __attr __fn_native_int_int_sub(__attr __self, __attr self, __attr other)
39.24 {
39.25 /* self and other interpreted as int */
39.26 - int i = __TOINT(self);
39.27 - int j = __TOINT(other);
39.28 + __int i = __TOINT(self);
39.29 + __int j = __TOINT(other);
39.30
39.31 /* Test for overflow. */
39.32 if (((i < 0) && (j > 0) && (i < __MININT + j)) ||
39.33 @@ -71,8 +71,8 @@
39.34 __attr __fn_native_int_int_mul(__attr __self, __attr self, __attr other)
39.35 {
39.36 /* self and other interpreted as int */
39.37 - int i = __TOINT(self);
39.38 - int j = __TOINT(other);
39.39 + __int i = __TOINT(self);
39.40 + __int j = __TOINT(other);
39.41
39.42 /* Test for overflow. */
39.43 if (((i > 0) && (j > 0) && (i > __MAXINT / j)) ||
39.44 @@ -89,8 +89,8 @@
39.45 __attr __fn_native_int_int_div(__attr __self, __attr self, __attr other)
39.46 {
39.47 /* self and other interpreted as int */
39.48 - int i = __TOINT(self);
39.49 - int j = __TOINT(other);
39.50 + __int i = __TOINT(self);
39.51 + __int j = __TOINT(other);
39.52
39.53 /* Test for division by zero or overflow. */
39.54 if (j == 0)
39.55 @@ -105,8 +105,8 @@
39.56 __attr __fn_native_int_int_mod(__attr __self, __attr self, __attr other)
39.57 {
39.58 /* self and other interpreted as int */
39.59 - int i = __TOINT(self);
39.60 - int j = __TOINT(other);
39.61 + __int i = __TOINT(self);
39.62 + __int j = __TOINT(other);
39.63
39.64 /* Test for division by zero or overflow. */
39.65 if (j == 0)
39.66 @@ -121,7 +121,7 @@
39.67 __attr __fn_native_int_int_neg(__attr __self, __attr self)
39.68 {
39.69 /* self interpreted as int */
39.70 - int i = __TOINT(self);
39.71 + __int i = __TOINT(self);
39.72
39.73 /* Test for overflow. */
39.74 if (i == __MININT)
39.75 @@ -134,8 +134,8 @@
39.76 __attr __fn_native_int_int_pow(__attr __self, __attr self, __attr other)
39.77 {
39.78 /* self and other interpreted as int */
39.79 - int i = __TOINT(self);
39.80 - int j = __TOINT(other);
39.81 + __int i = __TOINT(self);
39.82 + __int j = __TOINT(other);
39.83 int k;
39.84
39.85 errno = 0;
39.86 @@ -157,8 +157,8 @@
39.87 __attr __fn_native_int_int_and(__attr __self, __attr self, __attr other)
39.88 {
39.89 /* self and other interpreted as int */
39.90 - int i = __TOINT(self);
39.91 - int j = __TOINT(other);
39.92 + __int i = __TOINT(self);
39.93 + __int j = __TOINT(other);
39.94
39.95 /* Return the new integer. */
39.96 /* NOTE: No overflow test applied. */
39.97 @@ -168,7 +168,7 @@
39.98 __attr __fn_native_int_int_not(__attr __self, __attr self)
39.99 {
39.100 /* self interpreted as int */
39.101 - int i = __TOINT(self);
39.102 + __int i = __TOINT(self);
39.103
39.104 /* Return the new integer. */
39.105 return __new_int(~i);
39.106 @@ -177,8 +177,8 @@
39.107 __attr __fn_native_int_int_or(__attr __self, __attr self, __attr other)
39.108 {
39.109 /* self and other interpreted as int */
39.110 - int i = __TOINT(self);
39.111 - int j = __TOINT(other);
39.112 + __int i = __TOINT(self);
39.113 + __int j = __TOINT(other);
39.114
39.115 /* Return the new integer. */
39.116 /* NOTE: No overflow test applied. */
39.117 @@ -188,8 +188,8 @@
39.118 __attr __fn_native_int_int_xor(__attr __self, __attr self, __attr other)
39.119 {
39.120 /* self and other interpreted as int */
39.121 - int i = __TOINT(self);
39.122 - int j = __TOINT(other);
39.123 + __int i = __TOINT(self);
39.124 + __int j = __TOINT(other);
39.125
39.126 /* Return the new integer. */
39.127 /* NOTE: No overflow test applied. */
39.128 @@ -199,8 +199,8 @@
39.129 __attr __fn_native_int_int_lshift(__attr __self, __attr self, __attr other)
39.130 {
39.131 /* self and other interpreted as int */
39.132 - int i = __TOINT(self);
39.133 - int j = __TOINT(other);
39.134 + __int i = __TOINT(self);
39.135 + __int j = __TOINT(other);
39.136
39.137 /* Return the new integer. */
39.138 /* NOTE: No overflow test applied. */
39.139 @@ -210,8 +210,8 @@
39.140 __attr __fn_native_int_int_rshift(__attr __self, __attr self, __attr other)
39.141 {
39.142 /* self and other interpreted as int */
39.143 - int i = __TOINT(self);
39.144 - int j = __TOINT(other);
39.145 + __int i = __TOINT(self);
39.146 + __int j = __TOINT(other);
39.147
39.148 /* Return the new integer. */
39.149 /* NOTE: No overflow test applied. */
39.150 @@ -221,8 +221,8 @@
39.151 __attr __fn_native_int_int_le(__attr __self, __attr self, __attr other)
39.152 {
39.153 /* self and other interpreted as int */
39.154 - int i = __TOINT(self);
39.155 - int j = __TOINT(other);
39.156 + __int i = __TOINT(self);
39.157 + __int j = __TOINT(other);
39.158
39.159 /* Return a boolean result. */
39.160 return i <= j ? __builtins___boolean_True : __builtins___boolean_False;
39.161 @@ -231,8 +231,8 @@
39.162 __attr __fn_native_int_int_lt(__attr __self, __attr self, __attr other)
39.163 {
39.164 /* self and other interpreted as int */
39.165 - int i = __TOINT(self);
39.166 - int j = __TOINT(other);
39.167 + __int i = __TOINT(self);
39.168 + __int j = __TOINT(other);
39.169
39.170 /* Return a boolean result. */
39.171 return i < j ? __builtins___boolean_True : __builtins___boolean_False;
39.172 @@ -241,8 +241,8 @@
39.173 __attr __fn_native_int_int_ge(__attr __self, __attr self, __attr other)
39.174 {
39.175 /* self and other interpreted as int */
39.176 - int i = __TOINT(self);
39.177 - int j = __TOINT(other);
39.178 + __int i = __TOINT(self);
39.179 + __int j = __TOINT(other);
39.180
39.181 /* Return a boolean result. */
39.182 return i >= j ? __builtins___boolean_True : __builtins___boolean_False;
39.183 @@ -251,8 +251,8 @@
39.184 __attr __fn_native_int_int_gt(__attr __self, __attr self, __attr other)
39.185 {
39.186 /* self and other interpreted as int */
39.187 - int i = __TOINT(self);
39.188 - int j = __TOINT(other);
39.189 + __int i = __TOINT(self);
39.190 + __int j = __TOINT(other);
39.191
39.192 /* Return a boolean result. */
39.193 return i > j ? __builtins___boolean_True : __builtins___boolean_False;
39.194 @@ -261,8 +261,8 @@
39.195 __attr __fn_native_int_int_eq(__attr __self, __attr self, __attr other)
39.196 {
39.197 /* self and other interpreted as int */
39.198 - int i = __TOINT(self);
39.199 - int j = __TOINT(other);
39.200 + __int i = __TOINT(self);
39.201 + __int j = __TOINT(other);
39.202
39.203 /* Return a boolean result. */
39.204 return i == j ? __builtins___boolean_True : __builtins___boolean_False;
39.205 @@ -271,8 +271,8 @@
39.206 __attr __fn_native_int_int_ne(__attr __self, __attr self, __attr other)
39.207 {
39.208 /* self and other interpreted as int */
39.209 - int i = __TOINT(self);
39.210 - int j = __TOINT(other);
39.211 + __int i = __TOINT(self);
39.212 + __int j = __TOINT(other);
39.213
39.214 /* Return a boolean result. */
39.215 return i != j ? __builtins___boolean_True : __builtins___boolean_False;
39.216 @@ -281,14 +281,14 @@
39.217 __attr __fn_native_int_int_str(__attr __self, __attr self)
39.218 {
39.219 /* self interpreted as int */
39.220 - int i = __TOINT(self);
39.221 + __int i = __TOINT(self);
39.222
39.223 /* Employ a buffer big enough to fit the largest integer plus an extra
39.224 character, a minus sign, and the null terminator. */
39.225 unsigned int n = (int) log10(__MAXINT) + 3;
39.226 char *s = (char *) __ALLOCATE(n, sizeof(char));
39.227
39.228 - snprintf(s, n, "%d", i);
39.229 + snprintf(s, n, "%ld", i);
39.230
39.231 /* Return a new string. */
39.232 return __new_str(s, strlen(s));
40.1 --- a/templates/native/io.c Mon Jan 28 21:16:56 2019 +0100
40.2 +++ b/templates/native/io.c Tue Aug 22 19:36:13 2023 +0200
40.3 @@ -1,6 +1,6 @@
40.4 /* Native functions for input/output.
40.5
40.6 -Copyright (C) 2016, 2017 Paul Boddie <paul@boddie.org.uk>
40.7 +Copyright (C) 2016, 2017, 2021 Paul Boddie <paul@boddie.org.uk>
40.8
40.9 This program is free software; you can redistribute it and/or modify it under
40.10 the terms of the GNU General Public License as published by the Free Software
40.11 @@ -120,7 +120,7 @@
40.12 /* fp interpreted as FILE reference */
40.13 FILE *f = (FILE *) fp.datavalue;
40.14 /* size interpreted as int */
40.15 - int to_read = __TOINT(size);
40.16 + size_t to_read = __TOINT(size);
40.17 char buf[to_read];
40.18 size_t have_read;
40.19 int error;
40.20 @@ -150,7 +150,7 @@
40.21 /* str.__data__ interpreted as string */
40.22 char *s = __load_via_object(__VALUE(str), __data__).strvalue;
40.23 /* str.__size__ interpreted as int */
40.24 - int to_write = __TOINT(__load_via_object(__VALUE(str), __size__));
40.25 + size_t to_write = __load_via_object(__VALUE(str), __size__).sizevalue;
40.26 size_t have_written = fwrite(s, sizeof(char), to_write, f);
40.27 int error;
40.28
40.29 @@ -182,7 +182,7 @@
40.30 /* fd interpreted as int */
40.31 int i = __TOINT(fd);
40.32 /* n interpreted as int */
40.33 - int to_read = __TOINT(n);
40.34 + size_t to_read = __TOINT(n);
40.35 char buf[to_read];
40.36 ssize_t have_read;
40.37 char *s;
40.38 @@ -207,7 +207,7 @@
40.39 /* str.__data__ interpreted as string */
40.40 char *s = __load_via_object(__VALUE(str), __data__).strvalue;
40.41 /* str.__size__ interpreted as int */
40.42 - int size = __TOINT(__load_via_object(__VALUE(str), __size__));
40.43 + size_t size = __load_via_object(__VALUE(str), __size__).sizevalue;
40.44 ssize_t have_written;
40.45
40.46 errno = 0;
41.1 --- a/templates/native/list.c Mon Jan 28 21:16:56 2019 +0100
41.2 +++ b/templates/native/list.c Tue Aug 22 19:36:13 2023 +0200
41.3 @@ -1,6 +1,6 @@
41.4 /* Native functions for list operations.
41.5
41.6 -Copyright (C) 2016, 2017 Paul Boddie <paul@boddie.org.uk>
41.7 +Copyright (C) 2016, 2017, 2021 Paul Boddie <paul@boddie.org.uk>
41.8
41.9 This program is free software; you can redistribute it and/or modify it under
41.10 the terms of the GNU General Public License as published by the Free Software
41.11 @@ -30,7 +30,7 @@
41.12 __attr __fn_native_list_list_init(__attr __self, __attr size)
41.13 {
41.14 /* size interpreted as int */
41.15 - unsigned int n = __TOINT(size);
41.16 + __int n = __TOINT(size);
41.17 __attr attr = {.seqvalue=__new_fragment(n)};
41.18
41.19 /* Return the __data__ attribute. */
41.20 @@ -42,7 +42,7 @@
41.21 /* _data interpreted as list.__data__ */
41.22 __fragment *data = _data.seqvalue;
41.23 /* size interpreted as int */
41.24 - unsigned int n = __TOINT(size);
41.25 + __int n = __TOINT(size);
41.26
41.27 data->size = n;
41.28 return __builtins___none_None;
41.29 @@ -66,9 +66,9 @@
41.30 __fragment *data = __load_via_object(__VALUE(self), __data__).seqvalue;
41.31 __fragment *other_data = other.seqvalue;
41.32 __fragment *newdata = data;
41.33 - unsigned int size = data->size, capacity = data->capacity;
41.34 - unsigned int other_size = other_data->size;
41.35 - unsigned int i, j, n = size + other_size;
41.36 + __int size = data->size, capacity = data->capacity;
41.37 + __int other_size = other_data->size;
41.38 + __int i, j, n = size + other_size;
41.39
41.40 /* Re-allocate the fragment if the capacity has been reached. */
41.41 if (n >= capacity)
41.42 @@ -91,7 +91,7 @@
41.43 __attr __fn_native_list_list_len(__attr self, __attr _data)
41.44 {
41.45 /* _data interpreted as list.__data__ */
41.46 - unsigned int size = _data.seqvalue->size;
41.47 + __int size = _data.seqvalue->size;
41.48
41.49 /* Return the new integer. */
41.50 return __new_int(size);
41.51 @@ -107,7 +107,7 @@
41.52 /* _data interpreted as list.__data__ */
41.53 __attr *elements = _data.seqvalue->attrs;
41.54 /* index interpreted as int */
41.55 - int i = __TOINT(index);
41.56 + __int i = __TOINT(index);
41.57
41.58 return elements[i];
41.59 }
41.60 @@ -117,7 +117,7 @@
41.61 /* _data interpreted as list.__data__ */
41.62 __attr *elements = _data.seqvalue->attrs;
41.63 /* index interpreted as int */
41.64 - int i = __TOINT(index);
41.65 + __int i = __TOINT(index);
41.66
41.67 /* Set the element. */
41.68 elements[i] = value;
42.1 --- a/templates/native/locale.c Mon Jan 28 21:16:56 2019 +0100
42.2 +++ b/templates/native/locale.c Tue Aug 22 19:36:13 2023 +0200
42.3 @@ -1,6 +1,6 @@
42.4 /* Native functions for locale handling.
42.5
42.6 -Copyright (C) 2016, 2017 Paul Boddie <paul@boddie.org.uk>
42.7 +Copyright (C) 2016, 2017, 2021 Paul Boddie <paul@boddie.org.uk>
42.8
42.9 This program is free software; you can redistribute it and/or modify it under
42.10 the terms of the GNU General Public License as published by the Free Software
42.11 @@ -43,7 +43,7 @@
42.12
42.13 length = strlen(result);
42.14 out = __ALLOCATE(length + 1, sizeof(char));
42.15 - strncpy(out, result, length);
42.16 + strcpy(out, result);
42.17
42.18 return __new_str(result, length);
42.19 }
42.20 @@ -64,7 +64,7 @@
42.21
42.22 length = strlen(result);
42.23 out = __ALLOCATE(length + 1, sizeof(char));
42.24 - strncpy(out, result, length);
42.25 + strcpy(out, result);
42.26
42.27 return __new_str(result, length);
42.28 }
43.1 --- a/templates/native/str.c Mon Jan 28 21:16:56 2019 +0100
43.2 +++ b/templates/native/str.c Tue Aug 22 19:36:13 2023 +0200
43.3 @@ -1,6 +1,6 @@
43.4 /* Native functions for string operations.
43.5
43.6 -Copyright (C) 2016, 2017 Paul Boddie <paul@boddie.org.uk>
43.7 +Copyright (C) 2016, 2017, 2021 Paul Boddie <paul@boddie.org.uk>
43.8
43.9 This program is free software; you can redistribute it and/or modify it under
43.10 the terms of the GNU General Public License as published by the Free Software
43.11 @@ -33,9 +33,9 @@
43.12 /* _data, other interpreted as string.__data__ */
43.13 char *s = _data.strvalue;
43.14 char *o = other.strvalue;
43.15 - /* _size, othersize interpreted as int */
43.16 - int ss = __TOINT(_size), os = __TOINT(othersize);
43.17 - int n = ss + os;
43.18 + /* _size, othersize interpreted as size */
43.19 + __int ss = _size.sizevalue, os = othersize.sizevalue;
43.20 + __int n = ss + os;
43.21 char *r = (char *) __ALLOCATE(n + 1, sizeof(char));
43.22
43.23 memcpy(r, s, ss);
43.24 @@ -90,7 +90,12 @@
43.25 /* _data interpreted as string.__data__ */
43.26 char *s = _data.strvalue;
43.27
43.28 - return __new_int((unsigned int) s[0]);
43.29 + return __new_int((__int) s[0]);
43.30 +}
43.31 +
43.32 +__attr __fn_native_str_str_size(__attr __self, __attr _size)
43.33 +{
43.34 + return __new_int(_size.sizevalue);
43.35 }
43.36
43.37 __attr __fn_native_str_str_substr(__attr __self, __attr _data, __attr start, __attr end, __attr step)
43.38 @@ -98,15 +103,15 @@
43.39 /* _data interpreted as string.__data__ */
43.40 char *s = _data.strvalue, *sub;
43.41 /* start interpreted as int */
43.42 - int istart = __TOINT(start);
43.43 + __int istart = __TOINT(start);
43.44 /* end interpreted as int */
43.45 - int iend = __TOINT(end);
43.46 + __int iend = __TOINT(end);
43.47 /* step interpreted as int */
43.48 - int istep = __TOINT(step);
43.49 + __int istep = __TOINT(step);
43.50
43.51 /* Calculate the size of the substring. */
43.52 size_t resultsize = ((iend - istart - (istep > 0 ? 1 : -1)) / istep) + 1;
43.53 - int to, from;
43.54 + size_t to, from;
43.55
43.56 /* Reserve space for a new string. */
43.57 sub = (char *) __ALLOCATE(resultsize + 1, sizeof(char));
44.1 --- a/templates/native/str.h Mon Jan 28 21:16:56 2019 +0100
44.2 +++ b/templates/native/str.h Tue Aug 22 19:36:13 2023 +0200
44.3 @@ -1,6 +1,6 @@
44.4 /* Native functions for string operations.
44.5
44.6 -Copyright (C) 2016, 2017 Paul Boddie <paul@boddie.org.uk>
44.7 +Copyright (C) 2016, 2017, 2021 Paul Boddie <paul@boddie.org.uk>
44.8
44.9 This program is free software; you can redistribute it and/or modify it under
44.10 the terms of the GNU General Public License as published by the Free Software
44.11 @@ -27,6 +27,7 @@
44.12 __attr __fn_native_str_str_gt(__attr __self, __attr _data, __attr other);
44.13 __attr __fn_native_str_str_eq(__attr __self, __attr _data, __attr other);
44.14 __attr __fn_native_str_str_ord(__attr __self, __attr _data);
44.15 +__attr __fn_native_str_str_size(__attr __self);
44.16 __attr __fn_native_str_str_substr(__attr __self, __attr _data, __attr start, __attr end, __attr step);
44.17
44.18 /* Module initialisation. */
45.1 --- a/templates/native/system.c Mon Jan 28 21:16:56 2019 +0100
45.2 +++ b/templates/native/system.c Tue Aug 22 19:36:13 2023 +0200
45.3 @@ -1,6 +1,6 @@
45.4 /* Native functions for system operations.
45.5
45.6 -Copyright (C) 2016, 2017 Paul Boddie <paul@boddie.org.uk>
45.7 +Copyright (C) 2016, 2017, 2021 Paul Boddie <paul@boddie.org.uk>
45.8
45.9 This program is free software; you can redistribute it and/or modify it under
45.10 the terms of the GNU General Public License as published by the Free Software
46.1 --- a/templates/native/tuple.c Mon Jan 28 21:16:56 2019 +0100
46.2 +++ b/templates/native/tuple.c Tue Aug 22 19:36:13 2023 +0200
46.3 @@ -1,6 +1,6 @@
46.4 /* Native functions for tuple operations.
46.5
46.6 -Copyright (C) 2016, 2017 Paul Boddie <paul@boddie.org.uk>
46.7 +Copyright (C) 2016, 2017, 2021 Paul Boddie <paul@boddie.org.uk>
46.8
46.9 This program is free software; you can redistribute it and/or modify it under
46.10 the terms of the GNU General Public License as published by the Free Software
46.11 @@ -32,7 +32,7 @@
46.12 __attr __fn_native_tuple_tuple_init(__attr __self, __attr size)
46.13 {
46.14 /* size interpreted as int */
46.15 - int n = __TOINT(size);
46.16 + __int n = __TOINT(size);
46.17
46.18 /* Return the __data__ attribute. */
46.19 if (n) return (__attr) {.seqvalue=__new_fragment(n)};
47.1 --- a/templates/native/unicode.c Mon Jan 28 21:16:56 2019 +0100
47.2 +++ b/templates/native/unicode.c Tue Aug 22 19:36:13 2023 +0200
47.3 @@ -1,6 +1,6 @@
47.4 /* Native functions for Unicode operations.
47.5
47.6 -Copyright (C) 2016, 2017 Paul Boddie <paul@boddie.org.uk>
47.7 +Copyright (C) 2016, 2017, 2021 Paul Boddie <paul@boddie.org.uk>
47.8
47.9 This program is free software; you can redistribute it and/or modify it under
47.10 the terms of the GNU General Public License as published by the Free Software
47.11 @@ -39,9 +39,9 @@
47.12 else return 0;
47.13 }
47.14
47.15 -static unsigned int nextpos(char *s, unsigned int size, unsigned int bytestart)
47.16 +static __int nextpos(char *s, __int size, __int bytestart)
47.17 {
47.18 - unsigned int i = bytestart;
47.19 + __int i = bytestart;
47.20
47.21 while (i < size)
47.22 {
47.23 @@ -53,9 +53,9 @@
47.24 return i;
47.25 }
47.26
47.27 -static unsigned int prevpos(char *s, unsigned int bytestart)
47.28 +static __int prevpos(char *s, __int bytestart)
47.29 {
47.30 - unsigned int i = bytestart;
47.31 + __int i = bytestart;
47.32
47.33 while (i > 0)
47.34 {
47.35 @@ -73,9 +73,9 @@
47.36 {
47.37 /* _data interpreted as string.__data__ */
47.38 char *s = _data.strvalue;
47.39 - /* _size interpreted as int */
47.40 - int size = __TOINT(_size);
47.41 - unsigned int i, c = 0;
47.42 + /* _size interpreted as size */
47.43 + __int size = _size.sizevalue;
47.44 + __int i, c = 0;
47.45
47.46 for (i = 0; i < size; i++)
47.47 if (boundary(s[i]))
47.48 @@ -89,9 +89,9 @@
47.49 {
47.50 /* _data interpreted as string.__data__ */
47.51 char *s = _data.strvalue;
47.52 - /* _size interpreted as int */
47.53 - int size = __TOINT(_size);
47.54 - unsigned int i, c = 0, v;
47.55 + /* _size interpreted as size */
47.56 + __int size = _size.sizevalue;
47.57 + __int i, c = 0, v;
47.58
47.59 for (i = 0; i < size; i++)
47.60 {
47.61 @@ -123,21 +123,21 @@
47.62 {
47.63 /* _data interpreted as string.__data__ */
47.64 char *s = _data.strvalue, *sub;
47.65 - /* _size interpreted as int */
47.66 - int ss = __TOINT(_size);
47.67 + /* _size interpreted as size */
47.68 + __int ss = _size.sizevalue;
47.69 /* start interpreted as int */
47.70 - int istart = __TOINT(start);
47.71 + __int istart = __TOINT(start);
47.72 /* end interpreted as int */
47.73 - int iend = __TOINT(end);
47.74 + __int iend = __TOINT(end);
47.75 /* step interpreted as int */
47.76 - int istep = __TOINT(step);
47.77 + __int istep = __TOINT(step);
47.78
47.79 /* Calculate the number of characters. */
47.80 - size_t nchar = ((iend - istart - (istep > 0 ? 1 : -1)) / istep) + 1;
47.81 - unsigned int indexes[nchar];
47.82 + __int nchar = ((iend - istart - (istep > 0 ? 1 : -1)) / istep) + 1;
47.83 + __int indexes[nchar];
47.84
47.85 - unsigned int c, d, i, to, from, lastbyte = 0;
47.86 - int resultsize = 0;
47.87 + __int c, d, i, to, from, lastbyte = 0;
47.88 + __int resultsize = 0;
47.89
47.90 /* Find the indexes of the characters. */
47.91 if (istep > 0)
47.92 @@ -197,7 +197,7 @@
47.93 {
47.94 /* value interpreted as int */
47.95 int i = __TOINT(value);
47.96 - unsigned int resultsize;
47.97 + __int resultsize;
47.98 char *s;
47.99
47.100 if (i < 128) resultsize = 1;
48.1 --- a/templates/ops.c Mon Jan 28 21:16:56 2019 +0100
48.2 +++ b/templates/ops.c Tue Aug 22 19:36:13 2023 +0200
48.3 @@ -401,11 +401,6 @@
48.4 return __test_specific_instance(obj, &__FUNCTION_TYPE);
48.5 }
48.6
48.7 -int __ISNULL(__attr value)
48.8 -{
48.9 - return (value.value == 0); /* __NULL.value */
48.10 -}
48.11 -
48.12 /* Attribute codes and positions for type objects. */
48.13
48.14 unsigned int __TYPECODE(__ref obj)
49.1 --- a/templates/ops.h Mon Jan 28 21:16:56 2019 +0100
49.2 +++ b/templates/ops.h Tue Aug 22 19:36:13 2023 +0200
49.3 @@ -135,7 +135,8 @@
49.4 /* Type testing. */
49.5
49.6 __ref __ISFUNC(__ref obj);
49.7 -int __ISNULL(__attr value);
49.8 +
49.9 +#define __ISNULL(__ATTR) (!__ATTR.value)
49.10
49.11 /* Attribute codes and positions for type objects. */
49.12
50.1 --- a/templates/progops.c Mon Jan 28 21:16:56 2019 +0100
50.2 +++ b/templates/progops.c Tue Aug 22 19:36:13 2023 +0200
50.3 @@ -1,6 +1,6 @@
50.4 /* Operations depending on program specifics.
50.5
50.6 -Copyright (C) 2015, 2016, 2017, 2018, 2019 Paul Boddie <paul@boddie.org.uk>
50.7 +Copyright (C) 2015-2019, 2021 Paul Boddie <paul@boddie.org.uk>
50.8
50.9 This program is free software; you can redistribute it and/or modify it under
50.10 the terms of the GNU General Public License as published by the Free Software
50.11 @@ -49,7 +49,7 @@
50.12
50.13 /* Generic internal data allocation. */
50.14
50.15 -__fragment *__new_fragment(unsigned int n)
50.16 +__fragment *__new_fragment(__int n)
50.17 {
50.18 /* Allocate space for the list. */
50.19
50.20 @@ -62,9 +62,9 @@
50.21 return data;
50.22 }
50.23
50.24 -void __newdata_sequence(unsigned int number, __fragment *data, __attr args[])
50.25 +void __newdata_sequence(__int number, __fragment *data, __attr args[])
50.26 {
50.27 - unsigned int i;
50.28 + __int i;
50.29
50.30 /* Copy the given number of values. */
50.31
50.32 @@ -74,7 +74,7 @@
50.33 data->size = number;
50.34 }
50.35
50.36 -__attr __newdata_list(unsigned int number, __attr args[])
50.37 +__attr __newdata_list(__int number, __attr args[])
50.38 {
50.39 __attr self = __NEWINSTANCE(__builtins___list_list);
50.40 __fragment *data = __new_fragment(number);
50.41 @@ -86,7 +86,7 @@
50.42 return self;
50.43 }
50.44
50.45 -__attr __newdata_tuple(unsigned int number, __attr args[])
50.46 +__attr __newdata_tuple(__int number, __attr args[])
50.47 {
50.48 /* Allocate the tuple and fragment together. */
50.49
50.50 @@ -103,7 +103,7 @@
50.51 }
50.52
50.53 #ifdef __HAVE___builtins___dict_dict
50.54 -__attr __newdata_dict(unsigned int number, __attr args[])
50.55 +__attr __newdata_dict(__int number, __attr args[])
50.56 {
50.57 __attr self = __NEWINSTANCE(__builtins___dict_dict);
50.58
50.59 @@ -171,6 +171,13 @@
50.60 __Raise(__new___builtins___core_UnderflowError(__NULL));
50.61 }
50.62
50.63 +void __raise_value_error(__attr value)
50.64 +{
50.65 +#ifdef __HAVE___builtins___exception_base_ValueError
50.66 + __Raise(__new___builtins___exception_base_ValueError(__NULL, value));
50.67 +#endif /* __HAVE___builtins___exception_base_ValueError */
50.68 +}
50.69 +
50.70 void __raise_zero_division_error()
50.71 {
50.72 __Raise(__new___builtins___core_ZeroDivisionError(__NULL));
50.73 @@ -314,9 +321,18 @@
50.74
50.75 int __BOOL(__attr attr)
50.76 {
50.77 - /* Invoke the bool function with the object and test against True. */
50.78 + __ref value;
50.79 +
50.80 + /* Non-zero integers yield a non-zero result. Since the integer type can be
50.81 + larger than int, a conversion is performed. */
50.82
50.83 - __ref value = __VALUE(attr);
50.84 + if (__INTEGER(attr))
50.85 + return __TOINT(attr) ? 1 : 0;
50.86 +
50.87 + /* Test against True and False explicitly. If necessary, invoke the bool
50.88 + function with the object and test against True. */
50.89 +
50.90 + value = attr.value;
50.91
50.92 return value == (__ref) &__predefined___builtins___boolean_True ? 1 :
50.93 value == (__ref) &__predefined___builtins___boolean_False ? 0 :
51.1 --- a/templates/progops.h Mon Jan 28 21:16:56 2019 +0100
51.2 +++ b/templates/progops.h Tue Aug 22 19:36:13 2023 +0200
51.3 @@ -1,6 +1,6 @@
51.4 /* Operations depending on program specifics.
51.5
51.6 -Copyright (C) 2015, 2016, 2017, 2018, 2019 Paul Boddie <paul@boddie.org.uk>
51.7 +Copyright (C) 2015-2019, 2021 Paul Boddie <paul@boddie.org.uk>
51.8
51.9 This program is free software; you can redistribute it and/or modify it under
51.10 the terms of the GNU General Public License as published by the Free Software
51.11 @@ -31,10 +31,10 @@
51.12
51.13 /* Generic internal data allocation. */
51.14
51.15 -__fragment *__new_fragment(unsigned int n);
51.16 +__fragment *__new_fragment(__int n);
51.17
51.18 -__attr __newdata_list(unsigned int number, __attr args[]);
51.19 -__attr __newdata_tuple(unsigned int number, __attr args[]);
51.20 +__attr __newdata_list(__int number, __attr args[]);
51.21 +__attr __newdata_tuple(__int number, __attr args[]);
51.22
51.23 #define __newliteral___builtins___list_list(NUM, ...) __newdata_list(NUM, __ARGS(__VA_ARGS__))
51.24 #define __newliteral___builtins___tuple_tuple(NUM, ...) __newdata_tuple(NUM, __ARGS(__VA_ARGS__))
51.25 @@ -42,7 +42,7 @@
51.26 /* Potentially superfluous operations. */
51.27
51.28 #ifdef __HAVE___builtins___dict_dict
51.29 -__attr __newdata_dict(unsigned int number, __attr args[]);
51.30 +__attr __newdata_dict(__int number, __attr args[]);
51.31 #define __newliteral___builtins___dict_dict(NUM, ...) __newdata_dict(NUM, __ARGS(__VA_ARGS__))
51.32 #endif
51.33
51.34 @@ -56,6 +56,7 @@
51.35 void __raise_overflow_error();
51.36 void __raise_unbound_method_error();
51.37 void __raise_underflow_error();
51.38 +void __raise_value_error(__attr value);
51.39 void __raise_zero_division_error();
51.40 void __raise_type_error();
51.41
52.1 --- a/templates/types.h Mon Jan 28 21:16:56 2019 +0100
52.2 +++ b/templates/types.h Tue Aug 22 19:36:13 2023 +0200
52.3 @@ -1,6 +1,6 @@
52.4 /* Runtime types.
52.5
52.6 -Copyright (C) 2015, 2016, 2017, 2018, 2019 Paul Boddie <paul@boddie.org.uk>
52.7 +Copyright (C) 2015-2019, 2021 Paul Boddie <paul@boddie.org.uk>
52.8
52.9 This program is free software; you can redistribute it and/or modify it under
52.10 the terms of the GNU General Public License as published by the Free Software
52.11 @@ -23,6 +23,7 @@
52.12 program specifically. */
52.13
52.14 #include <stdint.h>
52.15 +#include <stdlib.h>
52.16
52.17 /* Include the special instance position value. The pos member of __obj refers
52.18 to the special type attribute for classes, indicating which position holds
52.19 @@ -70,12 +71,18 @@
52.20 typedef union __attr __attr;
52.21 typedef __obj * __ref;
52.22
52.23 +/* Introduce an integer type that is interoperable with the size type. */
52.24 +
52.25 +typedef ssize_t __int;
52.26 +
52.27 +/* Attribute value interpretations. */
52.28 +
52.29 typedef union __attr
52.30 {
52.31 /* General attribute members. */
52.32
52.33 __ref value; /* attribute value */
52.34 - int intvalue; /* integer value data (shifted value, tagged) */
52.35 + __int intvalue; /* integer value data (shifted value, tagged) */
52.36
52.37 /* Special case attribute members. */
52.38
52.39 @@ -88,6 +95,7 @@
52.40 char * strvalue; /* string value */
52.41 __fragment * seqvalue; /* sequence data */
52.42 void * datavalue; /* object-specific data */
52.43 + __int sizevalue; /* object-specific size */
52.44 } __attr;
52.45
52.46 typedef struct __obj
52.47 @@ -109,17 +117,18 @@
52.48
52.49 typedef struct __fragment
52.50 {
52.51 - unsigned int size, capacity;
52.52 + __int size, capacity;
52.53 __attr attrs[];
52.54 } __fragment;
52.55
52.56 -#define __FRAGMENT_SIZE(NUMBER) ((NUMBER) * sizeof(__attr) + 2 * sizeof(unsigned int))
52.57 +#define __FRAGMENT_SIZE(NUMBER) ((NUMBER) * sizeof(__attr) + 2 * sizeof(__int))
52.58
52.59 /* Attribute interpretation. */
52.60
52.61 -#define __NUM_TAG_BITS 1
52.62 -#define __TAG_INT 0b1
52.63 -#define __INTEGER(ATTR) ((ATTR).intvalue & __TAG_INT)
52.64 +#define __NUM_TAG_BITS 2
52.65 +#define __TAG_INT 0b01
52.66 +#define __TAG_MASK 0b11
52.67 +#define __INTEGER(ATTR) (((ATTR).intvalue & __TAG_MASK) == __TAG_INT)
52.68
52.69 /* Attribute value setting. */
52.70
52.71 @@ -129,10 +138,10 @@
52.72
52.73 /* Attribute as instance setting. */
52.74
52.75 -#define __INTVALUE(VALUE) ((__attr) {.intvalue=((VALUE) << __NUM_TAG_BITS) | __TAG_INT})
52.76 +#define __INTVALUE(VALUE) ((__attr) {.intvalue=(((__int) VALUE) << __NUM_TAG_BITS) | __TAG_INT})
52.77 #define __TOINT(ATTR) ((ATTR).intvalue >> __NUM_TAG_BITS)
52.78 -#define __MAXINT ((1 << ((sizeof(__attr) * 8) - 1 - __NUM_TAG_BITS)) - 1)
52.79 -#define __MININT (-(1 << ((sizeof(__attr) * 8) - 1 - __NUM_TAG_BITS)))
52.80 +#define __MAXINT ((((__int) 1) << ((sizeof(__int) * 8) - 1 - __NUM_TAG_BITS)) - 1)
52.81 +#define __MININT (-(((__int) 1) << ((sizeof(__int) * 8) - 1 - __NUM_TAG_BITS)))
52.82
52.83 /* Argument lists. */
52.84
53.1 --- a/test_all.sh Mon Jan 28 21:16:56 2019 +0100
53.2 +++ b/test_all.sh Tue Aug 22 19:36:13 2023 +0200
53.3 @@ -3,7 +3,7 @@
53.4 # This tool runs the toolchain for each of the tests, optionally building and
53.5 # running the test programs.
53.6 #
53.7 -# Copyright (C) 2016, 2017 Paul Boddie <paul@boddie.org.uk>
53.8 +# Copyright (C) 2016, 2017, 2021 Paul Boddie <paul@boddie.org.uk>
53.9 #
53.10 # This program is free software; you can redistribute it and/or modify it under
53.11 # the terms of the GNU General Public License as published by the Free Software
53.12 @@ -20,6 +20,8 @@
53.13
53.14 PROGNAME=$0
53.15 OPTION=$1
53.16 +shift 1
53.17 +MAKE_OPTIONS="$*"
53.18
53.19 LPLC="./lplc"
53.20 DATADIR="_main.lplc"
53.21 @@ -53,7 +55,7 @@
53.22
53.23 if [ "$OPTION" = '--help' ] ; then
53.24 cat 1>&2 <<EOF
53.25 -Usage: $0 [ --build | --build-only | --run-built ]
53.26 +Usage: $0 [ --build | --build-only | --run-built ] [ <make options> ]
53.27
53.28 Run the toolchain over all tests in the tests directory.
53.29
53.30 @@ -87,6 +89,11 @@
53.31 Build and output logs are stored in the _results directory with the .build and
53.32 .out suffixes employed respectively, one of each kind for each generated
53.33 program.
53.34 +
53.35 +The make options can be used to specify things like the number of processes
53.36 +employed to perform a build of each program. For example:
53.37 +
53.38 +$PROGNAME --build -j8
53.39 EOF
53.40 exit 1
53.41 fi
53.42 @@ -193,7 +200,7 @@
53.43
53.44 echo " (build)..." 1>&2
53.45 if ! make -C "$DATADIR/_generated" clean > "$BUILDLOG" 2>&1 || \
53.46 - ! make -C "$DATADIR/_generated" > "$BUILDLOG" 2>&1 ; then
53.47 + ! make -C "$DATADIR/_generated" $MAKE_OPTIONS > "$BUILDLOG" 2>&1 ; then
53.48 exit 1
53.49 fi
53.50
54.1 --- a/tests/identity.py Mon Jan 28 21:16:56 2019 +0100
54.2 +++ b/tests/identity.py Tue Aug 22 19:36:13 2023 +0200
54.3 @@ -1,7 +1,7 @@
54.4 -print isinstance("string", string) # True
54.5 +print isinstance("string", str) # True
54.6 print isinstance("string", int) # False
54.7 print isinstance(123, int) # True
54.8 -print isinstance(123, string) # False
54.9 +print isinstance(123, str) # False
54.10 print
54.11
54.12 class A:
55.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
55.2 +++ b/tests/int.py Tue Aug 22 19:36:13 2023 +0200
55.3 @@ -0,0 +1,30 @@
55.4 +i = int(123)
55.5 +j = 123
55.6 +print i, j, i == j # 123 123 True
55.7 +k = 456
55.8 +print i, k, i == k # 123 456 False
55.9 +h = int(789)
55.10 +print i, h, i == h # 123 789 False
55.11 +print j, h, j == h # 123 789 False
55.12 +
55.13 +try:
55.14 + a = int("a") # should raise an exception
55.15 +except ValueError, exc:
55.16 + print 'int("a") failed:', exc.value
55.17 +
55.18 +try:
55.19 + a = int("!") # should raise an exception
55.20 +except ValueError, exc:
55.21 + print 'int("!") failed:', exc.value
55.22 +
55.23 +a = int("a", 16)
55.24 +b = int("123")
55.25 +print a # 10
55.26 +print b, i, b == i # 123, 123, True
55.27 +print b, j, b == j # 123, 123, True
55.28 +
55.29 +a_is_int = isinstance(a, int)
55.30 +j_is_int = isinstance(j, int)
55.31 +
55.32 +print a_is_int # True
55.33 +print j_is_int # True
56.1 --- a/tests/numbers.py Mon Jan 28 21:16:56 2019 +0100
56.2 +++ b/tests/numbers.py Tue Aug 22 19:36:13 2023 +0200
56.3 @@ -18,7 +18,7 @@
56.4 j = -2 ** 29
56.5 print j # -536870912
56.6 print hex(j) # -0x20000000
56.7 -print oct(j) # -05000000000
56.8 +print oct(j) # -04000000000
56.9
56.10 print i + j # 0
56.11
57.1 --- a/tests/unicode.py Mon Jan 28 21:16:56 2019 +0100
57.2 +++ b/tests/unicode.py Tue Aug 22 19:36:13 2023 +0200
57.3 @@ -18,37 +18,37 @@
57.4 s2 = b"\xe6\xf8\xe5"
57.5 print "ISO-8859-15 values:"
57.6 print s2 # זרו
57.7 -print s2.__class__ # __builtins__.str.string
57.8 +print s2.__class__ # __builtins__.str.str
57.9 print len(s2) # 3
57.10
57.11 s3 = "\xe6\xf8\xe5"
57.12 print "ISO-8859-15 values:"
57.13 print s3 # זרו
57.14 -print s3.__class__ # __builtins__.str.string
57.15 +print s3.__class__ # __builtins__.str.str
57.16 print len(s3) # 3
57.17
57.18 s4 = b"\u00e6\u00f8\u00e5"
57.19 print "Untranslated values:"
57.20 print s4 # \u00e6\u00f8\u00e5
57.21 -print s4.__class__ # __builtins__.str.string
57.22 +print s4.__class__ # __builtins__.str.str
57.23 print len(s4) # 18
57.24
57.25 s5 = b"\346\370\345"
57.26 print "ISO-8859-15 values:"
57.27 print s5 # זרו
57.28 -print s5.__class__ # __builtins__.str.string
57.29 +print s5.__class__ # __builtins__.str.str
57.30 print len(s5) # 3
57.31
57.32 s6 = "\346\370\345"
57.33 print "ISO-8859-15 values:"
57.34 print s6 # זרו
57.35 -print s6.__class__ # __builtins__.str.string
57.36 +print s6.__class__ # __builtins__.str.str
57.37 print len(s6) # 3
57.38
57.39 s7 = r"\346\370\345"
57.40 print "Untranslated values:"
57.41 print s7 # \346\370\345
57.42 -print s7.__class__ # __builtins__.unicode.utf8string
57.43 +print s7.__class__ # __builtins__.unicode.unicode
57.44 print len(s7) # 12
57.45
57.46 # Obtain text and print it.
57.47 @@ -58,7 +58,7 @@
57.48 u = unicode(b"זרו", "ISO-8859-15")
57.49 print "Unicode values:"
57.50 print u # זרו
57.51 -print u.__class__ # __builtins__.unicode.utf8string
57.52 +print u.__class__ # __builtins__.unicode.unicode
57.53 print u.encode("ISO-8859-15") # זרו
57.54 print u.encoding # ISO-8859-15
57.55 print len(u) # 3
57.56 @@ -68,7 +68,7 @@
57.57 u2 = u"זרו"
57.58 print "Unicode values:"
57.59 print u2 # זרו
57.60 -print u2.__class__ # __builtins__.unicode.utf8string
57.61 +print u2.__class__ # __builtins__.unicode.unicode
57.62 print u2.encode("ISO-8859-15") # זרו
57.63 print u2.encoding # ISO-8859-15
57.64 print len(u2) # 3
57.65 @@ -78,7 +78,7 @@
57.66 u3 = "זרו"
57.67 print "Unicode values:"
57.68 print u3 # זרו
57.69 -print u3.__class__ # __builtins__.unicode.utf8string
57.70 +print u3.__class__ # __builtins__.unicode.unicode
57.71 print u3.encode("ISO-8859-15") # זרו
57.72 print u3.encoding # ISO-8859-15
57.73 print len(u3) # 3
57.74 @@ -88,7 +88,7 @@
57.75 u4 = unicode("זרו", "ISO-8859-15")
57.76 print "Unicode values:"
57.77 print u4 # זרו
57.78 -print u4.__class__ # __builtins__.unicode.utf8string
57.79 +print u4.__class__ # __builtins__.unicode.unicode
57.80 print u4.encode("ISO-8859-15") # זרו
57.81 print u4.encoding # ISO-8859-15
57.82 print len(u4) # 3
57.83 @@ -98,7 +98,7 @@
57.84 u5 = "\u00e6\u00f8\u00e5"
57.85 print "Unicode values:"
57.86 print u5 # זרו
57.87 -print u5.__class__ # __builtins__.unicode.ut8string
57.88 +print u5.__class__ # __builtins__.unicode.unicode
57.89 print len(u5) # 3
57.90
57.91 # Test some untranslated values.
57.92 @@ -106,7 +106,7 @@
57.93 u6 = "\\u00e6\\u00f8\\u00e5"
57.94 print "Untranslated values:"
57.95 print u6 # \u00e6\u00f8\u00e5
57.96 -print u6.__class__ # __builtins__.unicode.ut8string
57.97 +print u6.__class__ # __builtins__.unicode.unicode
57.98 print len(u6) # 18
57.99
57.100 # Test Unicode values.
57.101 @@ -114,7 +114,7 @@
57.102 u7 = u"\346\370\345"
57.103 print "Unicode values:"
57.104 print u7 # זרו
57.105 -print u7.__class__ # __builtins__.unicode.ut8string
57.106 +print u7.__class__ # __builtins__.unicode.unicode
57.107 print len(u7) # 3
57.108
57.109 # Test Unicode values.
57.110 @@ -122,7 +122,7 @@
57.111 u8 = ur"\346\370\345"
57.112 print "Untranslated values:"
57.113 print u8 # \346\370\345
57.114 -print u8.__class__ # __builtins__.unicode.ut8string
57.115 +print u8.__class__ # __builtins__.unicode.unicode
57.116 print len(u8) # 12
57.117
57.118 # Test invalid sequences.
57.119 @@ -137,7 +137,7 @@
57.120 u10 = "\u00e6\xf8\u00e5"
57.121 print "ISO-8859-15 values:"
57.122 print u10 # \u00e6ר\u00e5
57.123 -print u10.__class__ # __builtins__.str.string
57.124 +print u10.__class__ # __builtins__.str.str
57.125 print len(u10) # 13
57.126
57.127 # Combine bytes and text.
57.128 @@ -146,7 +146,7 @@
57.129 su = s + u
57.130 print "ISO-8859-15 values:"
57.131 print su # ֶ״ֵזרו
57.132 -print su.__class__ # __builtins__.str.string
57.133 +print su.__class__ # __builtins__.str.str
57.134 print len(su) # 6
57.135
57.136 # Combine text and bytes.
57.137 @@ -155,7 +155,7 @@
57.138 us = u + s
57.139 print "ISO-8859-15 values:"
57.140 print us # זרוֶ״ֵ
57.141 -print us.__class__ # __builtins__.str.string
57.142 +print us.__class__ # __builtins__.str.str
57.143 print len(us) # 6
57.144
57.145 # Combine text and text.
57.146 @@ -163,7 +163,7 @@
57.147 uu2 = u + u2
57.148 print "Unicode values:"
57.149 print uu2 # זרוזרו
57.150 -print uu2.__class__ # __builtins__.unicode.utf8string
57.151 +print uu2.__class__ # __builtins__.unicode.unicode
57.152 print uu2.encoding # ISO-8859-15
57.153 print len(uu2) # 6
57.154
57.155 @@ -195,7 +195,7 @@
57.156 # Test character access.
57.157
57.158 u0 = u[0]
57.159 -print u0.__class__ # __builtins__.unicode.utf8string
57.160 +print u0.__class__ # __builtins__.unicode.unicode
57.161 print u0.encoding # ISO-8859-15
57.162 print u0 # ז
57.163 print u[-1] # ו