1.1 --- a/README.txt Fri Sep 01 23:41:53 2023 +0200
1.2 +++ b/README.txt Sat Sep 02 01:50:57 2023 +0200
1.3 @@ -24,6 +24,25 @@
1.4 reconfigure such tools. However, an alternative suffix is likely to be
1.5 introduced in future.
1.6
1.7 +A Note about the Documentation
1.8 +------------------------------
1.9 +
1.10 +The original content in docs/wiki aims to be readable as plain text under most
1.11 +circumstances, but the intention is that this content be translated to HTML
1.12 +since it employs a formatting language based on the MoinMoin wiki format
1.13 +syntax.
1.14 +
1.15 +The following command can be used to generate the HTML form of the
1.16 +documentation from the main directory of this distribution:
1.17 +
1.18 +./docs/tools/make_docs.sh
1.19 +
1.20 +Specify the --web option for Web server deployment:
1.21 +
1.22 +./docs/tools/make_docs.sh --web
1.23 +
1.24 +To generate individual documents, specify their names after any options.
1.25 +
1.26 Getting Started
1.27 ===============
1.28
1.29 @@ -107,27 +126,3 @@
1.30
1.31 Copyright and licence information can be found in the docs directory - see
1.32 docs/COPYING.txt and docs/gpl-3.0.txt for more information.
1.33 -
1.34 -Generating the Wiki Pages
1.35 -=========================
1.36 -
1.37 -The docs/tools/make_pages.sh script generates a page package for MoinMoin. The
1.38 -following command will generate a page package called pages.zip using the
1.39 -pages directory for staging, with Lichen as the page prefix:
1.40 -
1.41 -docs/tools/make_pages.sh pages Lichen
1.42 -
1.43 -Make sure to include the page prefix where the pages are being deployed in a
1.44 -wiki with other content at the top level.
1.45 -
1.46 -Currently, the wiki pages require the following extensions:
1.47 -
1.48 -ImprovedTableParser https://moinmo.in/ParserMarket/ImprovedTableParser
1.49 -
1.50 -MoinSupport http://hgweb.boddie.org.uk/MoinSupport
1.51 -
1.52 -GraphvizParser https://moinmo.in/ParserMarket/graphviz
1.53 -
1.54 -The GraphvizParser requires diagram-tools for the notugly.xsl stylesheet,
1.55 -although a copy of the stylesheet is provided in the GraphvizParser
1.56 -distribution for convenience.
2.1 --- a/common.py Fri Sep 01 23:41:53 2023 +0200
2.2 +++ b/common.py Sat Sep 02 01:50:57 2023 +0200
2.3 @@ -362,9 +362,15 @@
2.4
2.5 l = []
2.6 for n in node.getChildNodes():
2.7 - l.append(self.process_structure_node(n))
2.8 + l.append(self.process_statement_node(n))
2.9 return l
2.10
2.11 + def process_statement_node(self, node):
2.12 +
2.13 + "Process the given statement 'node'."
2.14 +
2.15 + return self.process_structure_node(node)
2.16 +
2.17 def process_augassign_node(self, n):
2.18
2.19 "Process the given augmented assignment node 'n'."
3.1 --- a/docs/tools/make_docs.sh Fri Sep 01 23:41:53 2023 +0200
3.2 +++ b/docs/tools/make_docs.sh Sat Sep 02 01:50:57 2023 +0200
3.3 @@ -2,7 +2,6 @@
3.4
3.5 THISDIR=`dirname "$0"`
3.6 INDIR="$THISDIR/../wiki"
3.7 -OUTDIR="$THISDIR/../html"
3.8
3.9 ROOT="Lichen"
3.10
3.11 @@ -16,6 +15,13 @@
3.12 DOCINDEX='--document-index index.html'
3.13 fi
3.14
3.15 +if [ "$1" = '-o' ] ; then
3.16 + OUTDIR="$2"
3.17 + shift 2
3.18 +else
3.19 + OUTDIR="$THISDIR/../html"
3.20 +fi
3.21 +
3.22 FILENAMES=${*:-'--all'}
3.23
3.24 moinconvert --input-dir "$INDIR" \
4.1 --- a/docs/wiki/Prerequisites Fri Sep 01 23:41:53 2023 +0200
4.2 +++ b/docs/wiki/Prerequisites Sat Sep 02 01:50:57 2023 +0200
4.3 @@ -15,3 +15,6 @@
4.4 As Free Software, priority has been given to supporting Lichen on Free Software
4.5 platforms, with Debian GNU/Linux being the development platform. Proprietary
4.6 platforms are neither supported nor recommended.
4.7 +
4.8 +To generate HTML documentation, the [[https://projects.boddie.org.uk/MoinLight|
4.9 +MoinLight]] distribution is required.
5.1 --- a/encoders.py Fri Sep 01 23:41:53 2023 +0200
5.2 +++ b/encoders.py Sat Sep 02 01:50:57 2023 +0200
5.3 @@ -521,6 +521,15 @@
5.4
5.5 return "__constvalue%s" % n
5.6
5.7 +def encode_trailing_area(path):
5.8 +
5.9 + """
5.10 + Encode any reference to trailing data members for instances of the type
5.11 + given by 'path'.
5.12 + """
5.13 +
5.14 + return "__TRAILING_%s" % encode_path(path)
5.15 +
5.16
5.17
5.18 # Track all encoded paths, detecting and avoiding conflicts.
6.1 --- a/generator.py Fri Sep 01 23:41:53 2023 +0200
6.2 +++ b/generator.py Sat Sep 02 01:50:57 2023 +0200
6.3 @@ -29,6 +29,7 @@
6.4 encode_path, encode_pcode, encode_pos, encode_ppos, \
6.5 encode_predefined_reference, encode_size, \
6.6 encode_symbol, encode_tablename, \
6.7 + encode_trailing_area, \
6.8 encode_type_attribute, decode_type_attribute, \
6.9 is_type_attribute
6.10 from os import listdir, mkdir, remove
6.11 @@ -42,6 +43,7 @@
6.12 # NOTE: These must be synchronised with the library.
6.13
6.14 dict_type = "__builtins__.dict.dict"
6.15 + float_type = "__builtins__.float.float"
6.16 function_type = "__builtins__.core.function"
6.17 int_type = "__builtins__.int.int"
6.18 list_type = "__builtins__.list.list"
6.19 @@ -64,6 +66,12 @@
6.20 dict_type, list_type, tuple_type
6.21 )
6.22
6.23 + # Data types with a trailing data member of the given native types.
6.24 +
6.25 + trailing_data_types = {
6.26 + float_type : "double",
6.27 + }
6.28 +
6.29 def __init__(self, importer, optimiser, output):
6.30
6.31 """
6.32 @@ -184,6 +192,7 @@
6.33 #include <string.h>
6.34 #include <stdio.h>
6.35 #include "gc.h"
6.36 +#include "signals.h"
6.37 #include "types.h"
6.38 #include "exceptions.h"
6.39 #include "ops.h"
6.40 @@ -219,6 +228,7 @@
6.41
6.42 if kind != "<instance>":
6.43 structure = []
6.44 + trailing = []
6.45 attrs = self.get_static_attributes(kind, path, attrnames)
6.46
6.47 # Set a special instantiator on the class.
6.48 @@ -244,12 +254,13 @@
6.49 attrs["__args__"] = path
6.50
6.51 self.populate_structure(Reference(kind, path), attrs, kind, structure)
6.52 + self.populate_trailing(Reference(kind, path), attrs, trailing)
6.53
6.54 if kind == "<class>":
6.55 self.write_instance_structure(f_decls, path)
6.56
6.57 - self.write_structure(f_decls, f_defs, path, table_name, structure,
6.58 - kind == "<class>" and path)
6.59 + self.write_structure(f_decls, f_defs, path, table_name,
6.60 + structure, trailing, ref)
6.61
6.62 # Record function instance details for function generation below.
6.63
6.64 @@ -296,7 +307,7 @@
6.65 function_instance_attrs["__args__"] = path
6.66
6.67 structure = self.populate_function(path, function_instance_attrs)
6.68 - self.write_structure(f_decls, f_defs, path, table_name, structure)
6.69 + self.write_structure(f_decls, f_defs, path, table_name, structure, [], Reference("<function>", path))
6.70
6.71 # Functions with defaults need to declare instance structures.
6.72
6.73 @@ -410,6 +421,12 @@
6.74 self.optimiser.locations,
6.75 "code", "pos", encode_code, encode_pos)
6.76
6.77 + # Generate trailing data macros of the form...
6.78 + # #define __TRAILING_typename nativetype trailing;
6.79 +
6.80 + for name, member_type in self.trailing_data_types.items():
6.81 + print >>f_consts, "#define %s %s trailing;" % (encode_symbol("TRAILING", name), member_type)
6.82 +
6.83 # Generate macros for calls.
6.84
6.85 all_max_parameters = list(all_max_parameters)
6.86 @@ -616,7 +633,16 @@
6.87 # Set the data, if provided.
6.88
6.89 if data is not None:
6.90 - attrs["__data__"] = data
6.91 +
6.92 + # Data retained by special attribute.
6.93 +
6.94 + if attrs.has_key("__data__"):
6.95 + attrs["__data__"] = data
6.96 +
6.97 + # Data retained by a trailing data area.
6.98 +
6.99 + elif attrs.has_key("__trailing__"):
6.100 + attrs["__trailing__"] = data
6.101
6.102 # Also set a key for dynamic attribute lookup, if a string.
6.103
6.104 @@ -657,9 +683,12 @@
6.105 # the constant in the program.
6.106
6.107 structure = []
6.108 + trailing = []
6.109 table_name = encode_tablename("<instance>", cls)
6.110 self.populate_structure(ref, attrs, ref.get_kind(), structure)
6.111 - self.write_structure(f_decls, f_defs, structure_name, table_name, structure)
6.112 + self.populate_trailing(ref, attrs, trailing)
6.113 + self.write_structure(f_decls, f_defs, structure_name, table_name,
6.114 + structure, trailing, ref)
6.115
6.116 # Define a macro for the constant.
6.117
6.118 @@ -819,38 +848,51 @@
6.119 # Write an instance-specific type definition for instances of classes.
6.120 # See: templates/types.h
6.121
6.122 + trailing_area = path in self.trailing_data_types and encode_trailing_area(path) or ""
6.123 +
6.124 print >>f_decls, """\
6.125 typedef struct {
6.126 const __table * table;
6.127 __pos pos;
6.128 __attr attrs[%s];
6.129 +%s
6.130 } %s;
6.131 -""" % (structure_size, encode_symbol("obj", path))
6.132 +""" % (structure_size, trailing_area, encode_symbol("obj", path))
6.133
6.134 - def write_structure(self, f_decls, f_defs, structure_name, table_name, structure, path=None):
6.135 + def write_structure(self, f_decls, f_defs, structure_name, table_name,
6.136 + structure, trailing, ref):
6.137
6.138 """
6.139 Write the declarations to 'f_decls' and definitions to 'f_defs' for
6.140 the object having the given 'structure_name', the given 'table_name',
6.141 - and the given 'structure' details used to populate the definition.
6.142 + the given 'structure' details and any 'trailing' member details, used to
6.143 + populate the definition.
6.144 """
6.145
6.146 + origin = ref.get_origin()
6.147 + pos = ref.has_kind("<class>") and encode_pos(encode_type_attribute(origin)) or str(self.instancepos)
6.148 +
6.149 + obj_type = ref.has_kind("<instance>") and encode_symbol("obj", origin) or "__obj"
6.150 + obj_name = encode_path(structure_name)
6.151 +
6.152 if f_decls:
6.153 - print >>f_decls, "extern __obj %s;\n" % encode_path(structure_name)
6.154 -
6.155 - is_class = path and self.importer.get_object(path).has_kind("<class>")
6.156 - pos = is_class and encode_pos(encode_type_attribute(path)) or str(self.instancepos)
6.157 + print >>f_decls, "extern %s %s;\n" % (obj_type, obj_name)
6.158
6.159 print >>f_defs, """\
6.160 -__obj %s = {
6.161 +%s %s = {
6.162 &%s,
6.163 %s,
6.164 {
6.165 %s
6.166 - }};
6.167 + },
6.168 + %s
6.169 + };
6.170 """ % (
6.171 - encode_path(structure_name), table_name, pos,
6.172 - ",\n ".join(structure))
6.173 + obj_type, obj_name,
6.174 + table_name,
6.175 + pos,
6.176 + ",\n ".join(structure),
6.177 + trailing and ",\n ".join(trailing) or "")
6.178
6.179 def get_argument_limits(self, path):
6.180
6.181 @@ -910,6 +952,12 @@
6.182 continue
6.183 const = consts.get(attrname)
6.184 attrs[attrname] = const or Reference("<var>", "%s.%s" % (name, attrname))
6.185 +
6.186 + # Instances with trailing data.
6.187 +
6.188 + if name in self.trailing_data_types:
6.189 + attrs["__trailing__"] = Reference("<var>", "%s.__trailing__" % name)
6.190 +
6.191 return attrs
6.192
6.193 def populate_table(self, path, table):
6.194 @@ -1018,7 +1066,7 @@
6.195 # Special internal size member.
6.196
6.197 elif attrname == "__size__":
6.198 - structure.append("{.sizevalue=%d}" % attr)
6.199 + structure.append("{.intvalue=__FROMINT(%d)}" % attr)
6.200 continue
6.201
6.202 # Special internal key member.
6.203 @@ -1101,6 +1149,21 @@
6.204
6.205 structure.append(self.encode_member(origin, attrname, attr, kind))
6.206
6.207 + def populate_trailing(self, ref, attrs, trailing):
6.208 +
6.209 + """
6.210 + For the structure having the given 'ref', whose members are provided by
6.211 + the 'attrs' mapping, adding entries to the 'trailing' member collection.
6.212 + """
6.213 +
6.214 + structure_ref = self.get_target_structure(ref)
6.215 +
6.216 + # Instances with trailing data.
6.217 +
6.218 + if structure_ref.get_kind() == "<instance>" and \
6.219 + structure_ref.get_origin() in self.trailing_data_types:
6.220 + trailing.append(encode_literal_constant_value(attrs["__trailing__"]))
6.221 +
6.222 def get_target_structure(self, ref):
6.223
6.224 "Return the target structure type and reference for 'ref'."
6.225 @@ -1154,22 +1217,22 @@
6.226
6.227 if kind == "<instance>" and origin == self.none_type:
6.228 attr_path = encode_predefined_reference(self.none_value)
6.229 - return "{.value=&%s} /* %s */" % (attr_path, name)
6.230 + return "{.value=(__ref) &%s} /* %s */" % (attr_path, name)
6.231
6.232 # Predefined constant members.
6.233
6.234 if (path, name) in self.predefined_constant_members:
6.235 attr_path = encode_predefined_reference("%s.%s" % (path, name))
6.236 - return "{.value=&%s} /* %s */" % (attr_path, name)
6.237 + return "{.value=(__ref) &%s} /* %s */" % (attr_path, name)
6.238
6.239 # General undetermined members.
6.240
6.241 if kind in ("<var>", "<instance>"):
6.242 attr_path = encode_predefined_reference(self.none_value)
6.243 - return "{.value=&%s} /* %s */" % (attr_path, name)
6.244 + return "{.value=(__ref) &%s} /* %s */" % (attr_path, name)
6.245
6.246 else:
6.247 - return "{.value=&%s}" % encode_path(origin)
6.248 + return "{.value=(__ref) &%s}" % encode_path(origin)
6.249
6.250 def append_defaults(self, path, structure):
6.251
6.252 @@ -1269,6 +1332,8 @@
6.253
6.254 GC_INIT();
6.255
6.256 + __signals_install_handlers();
6.257 +
6.258 __Try
6.259 {"""
6.260
7.1 --- a/lib/__builtins__/core.py Fri Sep 01 23:41:53 2023 +0200
7.2 +++ b/lib/__builtins__/core.py Sat Sep 02 01:50:57 2023 +0200
7.3 @@ -3,7 +3,7 @@
7.4 """
7.5 Core objects.
7.6
7.7 -Copyright (C) 2015, 2016, 2017 Paul Boddie <paul@boddie.org.uk>
7.8 +Copyright (C) 2015, 2016, 2017, 2018 Paul Boddie <paul@boddie.org.uk>
7.9
7.10 This program is free software; you can redistribute it and/or modify it under
7.11 the terms of the GNU General Public License as published by the Free Software
7.12 @@ -189,6 +189,15 @@
7.13
7.14 pass
7.15
7.16 +class UnderflowError(ArithmeticError):
7.17 +
7.18 + """
7.19 + Indicates that an arithmetic operation produced a result that could not be
7.20 + represented.
7.21 + """
7.22 +
7.23 + pass
7.24 +
7.25 class ZeroDivisionError(ArithmeticError):
7.26
7.27 "An error occurring when an attempt was made to divide an operand by zero."
8.1 --- a/lib/__builtins__/float.py Fri Sep 01 23:41:53 2023 +0200
8.2 +++ b/lib/__builtins__/float.py Sat Sep 02 01:50:57 2023 +0200
8.3 @@ -1,9 +1,9 @@
8.4 #!/usr/bin/env python
8.5
8.6 """
8.7 -Floating point objects.
8.8 +Floating point number objects.
8.9
8.10 -Copyright (C) 2015, 2016 Paul Boddie <paul@boddie.org.uk>
8.11 +Copyright (C) 2015, 2016, 2018, 2021 Paul Boddie <paul@boddie.org.uk>
8.12
8.13 This program is free software; you can redistribute it and/or modify it under
8.14 the terms of the GNU General Public License as published by the Free Software
8.15 @@ -19,36 +19,189 @@
8.16 this program. If not, see <http://www.gnu.org/licenses/>.
8.17 """
8.18
8.19 +from __builtins__.unicode import unicode
8.20 +from native import isinstance as _isinstance, \
8.21 + int_float, is_int, \
8.22 + float_add, float_div, float_eq, float_ge, float_gt, \
8.23 + float_le, float_lt, float_mod, float_mul, float_ne, \
8.24 + float_neg, float_pow, float_str, float_sub,
8.25 +
8.26 class float:
8.27 +
8.28 + "A floating point number abstraction."
8.29 +
8.30 def __init__(self, number_or_string=None):
8.31 - # Note member.
8.32 - self.__data__ = 0.0
8.33 +
8.34 + "Initialise the integer with the given 'number_or_string'."
8.35 +
8.36 + # NOTE: To be implemented.
8.37 +
8.38 + pass
8.39 +
8.40 + def __hash__(self):
8.41 +
8.42 + "Return a value for hashing purposes."
8.43 +
8.44 + return self
8.45 +
8.46 + def _binary_op(self, op, other):
8.47 +
8.48 + "Perform 'op' on this float and 'other' if appropriate."
8.49 +
8.50 + if _isinstance(other, float):
8.51 + return op(self, other)
8.52 + elif is_int(other):
8.53 + return op(self, int_float(other))
8.54 + else:
8.55 + return NotImplemented
8.56 +
8.57 + def _binary_op_rev(self, op, other):
8.58 +
8.59 + "Perform 'op' on 'other' and this float if appropriate."
8.60 +
8.61 + if _isinstance(other, float):
8.62 + return op(other, self)
8.63 + elif is_int(other):
8.64 + return op(int_float(other), self)
8.65 + else:
8.66 + return NotImplemented
8.67 +
8.68 + def __iadd__(self, other):
8.69 +
8.70 + "Return a new float for the addition of this float and 'other'."
8.71
8.72 - def __iadd__(self, other): pass
8.73 - def __isub__(self, other): pass
8.74 - def __add__(self, other): pass
8.75 - def __radd__(self, other): pass
8.76 - def __sub__(self, other): pass
8.77 - def __rsub__(self, other): pass
8.78 - def __mul__(self, other): pass
8.79 - def __rmul__(self, other): pass
8.80 - def __div__(self, other): pass
8.81 - def __rdiv__(self, other): pass
8.82 + return self._binary_op(float_add, other)
8.83 +
8.84 + def __isub__(self, other):
8.85 +
8.86 + "Return a new float for the subtraction from this float of 'other'."
8.87 +
8.88 + return self._binary_op(float_sub, other)
8.89 +
8.90 + def __imul__(self, other):
8.91 +
8.92 + "Return a new float for the multiplication of this float and 'other'."
8.93 +
8.94 + return self._binary_op(float_mul, other)
8.95 +
8.96 + def __idiv__(self, other):
8.97 +
8.98 + "Return a new float for the division of this float by 'other'."
8.99 +
8.100 + return self._binary_op(float_div, other)
8.101 +
8.102 + def __imod__(self, other):
8.103 +
8.104 + "Return a new float for the modulo of this float by 'other'."
8.105 +
8.106 + return self._binary_op(float_mod, other)
8.107 +
8.108 + def __ipow__(self, other):
8.109 +
8.110 + "Return a new float for the exponentiation of this float by 'other'."
8.111 +
8.112 + return self._binary_op(float_pow, other)
8.113 +
8.114 + __add__ = __radd__ = __iadd__
8.115 + __sub__ = __isub__
8.116 +
8.117 + def __rsub__(self, other):
8.118 +
8.119 + "Return a new float for the subtraction of this float from 'other'."
8.120 +
8.121 + return self._binary_op_rev(float_sub, other)
8.122 +
8.123 + __mul__ = __rmul__ = __imul__
8.124 + __div__ = __idiv__
8.125 +
8.126 + def __rdiv__(self, other):
8.127 +
8.128 + "Return a new float for the division of 'other' by this float."
8.129 +
8.130 + return self._binary_op_rev(float_div, other)
8.131 +
8.132 + # NOTE: To be implemented.
8.133 +
8.134 def __floordiv__(self, other): pass
8.135 def __rfloordiv__(self, other): pass
8.136 - def __mod__(self, other): pass
8.137 - def __rmod__(self, other): pass
8.138 - def __pow__(self, other): pass
8.139 - def __rpow__(self, other): pass
8.140 - def __lt__(self, other): pass
8.141 - def __gt__(self, other): pass
8.142 - def __le__(self, other): pass
8.143 - def __ge__(self, other): pass
8.144 - def __eq__(self, other): pass
8.145 - def __ne__(self, other): pass
8.146 - def __neg__(self): pass
8.147 - def __pos__(self): pass
8.148 - def __str__(self): pass
8.149 - def __bool__(self): pass
8.150 + def __ifloordiv__(self, other): pass
8.151 +
8.152 + __mod__ = __imod__
8.153 +
8.154 + def __rmod__(self, other):
8.155 +
8.156 + "Return a new float for the modulo of 'other' by this float."
8.157 +
8.158 + return self._binary_op_rev(float_mod, other)
8.159 +
8.160 + __pow__ = __ipow__
8.161 +
8.162 + def __rpow__(self, other):
8.163 +
8.164 + "Return a new float for the exponentiation of 'other' by this float."
8.165 +
8.166 + return self._binary_op_rev(float_pow, other)
8.167 +
8.168 + def __lt__(self, other):
8.169 +
8.170 + "Return whether this float is less than 'other'."
8.171 +
8.172 + return self._binary_op(float_lt, other)
8.173 +
8.174 + def __gt__(self, other):
8.175 +
8.176 + "Return whether this float is greater than 'other'."
8.177 +
8.178 + return self._binary_op(float_gt, other)
8.179 +
8.180 + def __le__(self, other):
8.181 +
8.182 + "Return whether this float is less than or equal to 'other'."
8.183 +
8.184 + return self._binary_op(float_le, other)
8.185 +
8.186 + def __ge__(self, other):
8.187 +
8.188 + "Return whether this float is greater than or equal to 'other'."
8.189 +
8.190 + return self._binary_op(float_ge, other)
8.191 +
8.192 + def __eq__(self, other):
8.193 +
8.194 + "Return whether this float is equal to 'other'."
8.195 +
8.196 + return self._binary_op(float_eq, other)
8.197 +
8.198 + def __ne__(self, other):
8.199 +
8.200 + "Return whether this float is not equal to 'other'."
8.201 +
8.202 + return self._binary_op(float_ne, other)
8.203 +
8.204 + def __neg__(self):
8.205 +
8.206 + "Apply the unary negation operator."
8.207 +
8.208 + return float_neg(self)
8.209 +
8.210 + def __pos__(self):
8.211 +
8.212 + "Apply the unary positive operator."
8.213 +
8.214 + return self
8.215 +
8.216 + def __str__(self):
8.217 +
8.218 + "Return a string representation."
8.219 +
8.220 + return unicode(float_str(self))
8.221 +
8.222 + __repr__ = __str__
8.223 +
8.224 + def __bool__(self):
8.225 +
8.226 + "Return whether this float is non-zero."
8.227 +
8.228 + return float_ne(self, 0)
8.229
8.230 # vim: tabstop=4 expandtab shiftwidth=4
9.1 --- a/lib/native/__init__.py Fri Sep 01 23:41:53 2023 +0200
9.2 +++ b/lib/native/__init__.py Sat Sep 02 01:50:57 2023 +0200
9.3 @@ -21,13 +21,19 @@
9.4
9.5 from native.buffer import buffer_str
9.6
9.7 +from native.float import float_add, float_div, float_mod, float_mul, \
9.8 + float_neg, float_pow, float_sub, \
9.9 + float_eq, float_ge, float_gt, float_le, float_lt, \
9.10 + float_ne, \
9.11 + float_int, float_str
9.12 +
9.13 from native.identity import is_, is_not
9.14
9.15 from native.int import int_add, int_div, int_mod, int_mul, int_neg, int_pow, \
9.16 int_sub, int_and, int_not, int_or, int_xor, \
9.17 int_lshift, int_rshift, \
9.18 int_eq, int_ge, int_gt, int_le, int_lt, int_ne, \
9.19 - int_str, is_int
9.20 + int_float, int_str, is_int
9.21
9.22 from native.introspection import object_getattr, isinstance, issubclass
9.23
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/lib/native/float.py Sat Sep 02 01:50:57 2023 +0200
10.3 @@ -0,0 +1,45 @@
10.4 +#!/usr/bin/env python
10.5 +
10.6 +"""
10.7 +Native library functions for floating point numbers.
10.8 +
10.9 +None of these are actually defined here. Instead, native implementations are
10.10 +substituted when each program is built. It is, however, important to declare
10.11 +non-core exceptions used by the native functions because they need to be
10.12 +identified as being needed by the program.
10.13 +
10.14 +Copyright (C) 2018 Paul Boddie <paul@boddie.org.uk>
10.15 +
10.16 +This program is free software; you can redistribute it and/or modify it under
10.17 +the terms of the GNU General Public License as published by the Free Software
10.18 +Foundation; either version 3 of the License, or (at your option) any later
10.19 +version.
10.20 +
10.21 +This program is distributed in the hope that it will be useful, but WITHOUT
10.22 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10.23 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
10.24 +details.
10.25 +
10.26 +You should have received a copy of the GNU General Public License along with
10.27 +this program. If not, see <http://www.gnu.org/licenses/>.
10.28 +"""
10.29 +
10.30 +def float_add(self, other): return 0.0
10.31 +def float_div(self, other): return 0.0
10.32 +def float_mod(self, other): return 0.0
10.33 +def float_mul(self, other): return 0.0
10.34 +def float_neg(self): return 0.0
10.35 +def float_pow(self, other): return 0.0
10.36 +def float_sub(self, other): return 0.0
10.37 +
10.38 +def float_eq(self, other): return True or False
10.39 +def float_ge(self, other): return True or False
10.40 +def float_gt(self, other): return True or False
10.41 +def float_le(self, other): return True or False
10.42 +def float_lt(self, other): return True or False
10.43 +def float_ne(self, other): return True or False
10.44 +
10.45 +def float_str(self): return ""
10.46 +def float_int(self): return 0
10.47 +
10.48 +# vim: tabstop=4 expandtab shiftwidth=4
11.1 --- a/lib/native/int.py Fri Sep 01 23:41:53 2023 +0200
11.2 +++ b/lib/native/int.py Sat Sep 02 01:50:57 2023 +0200
11.3 @@ -8,7 +8,7 @@
11.4 non-core exceptions used by the native functions because they need to be
11.5 identified as being needed by the program.
11.6
11.7 -Copyright (C) 2011, 2015, 2016, 2017 Paul Boddie <paul@boddie.org.uk>
11.8 +Copyright (C) 2011, 2015, 2016, 2017, 2018 Paul Boddie <paul@boddie.org.uk>
11.9
11.10 This program is free software; you can redistribute it and/or modify it under
11.11 the terms of the GNU General Public License as published by the Free Software
11.12 @@ -53,5 +53,6 @@
11.13 def int_ne(self, other): return True or False
11.14
11.15 def int_str(self): return ""
11.16 +def int_float(self): return 0.0
11.17
11.18 # vim: tabstop=4 expandtab shiftwidth=4
12.1 --- a/lib/operator/augmented.py Fri Sep 01 23:41:53 2023 +0200
12.2 +++ b/lib/operator/augmented.py Sat Sep 02 01:50:57 2023 +0200
12.3 @@ -3,7 +3,7 @@
12.4 """
12.5 Operator support.
12.6
12.7 -Copyright (C) 2010, 2013, 2015, 2017 Paul Boddie <paul@boddie.org.uk>
12.8 +Copyright (C) 2010, 2013, 2015, 2017, 2019 Paul Boddie <paul@boddie.org.uk>
12.9
12.10 This program is free software; you can redistribute it and/or modify it under
12.11 the terms of the GNU General Public License as published by the Free Software
12.12 @@ -22,7 +22,8 @@
12.13 from operator.core import augassign
12.14 from native import int_add, int_div, int_mod, int_mul, int_pow, int_sub, \
12.15 int_and, int_or, int_xor, \
12.16 - is_int
12.17 + is_int, \
12.18 + float_add, float_div, float_mul, float_pow, float_sub
12.19
12.20 # These functions defer method lookup by wrapping the attribute access in
12.21 # lambda functions. Thus, the appropriate methods are defined locally, but no
12.22 @@ -36,6 +37,8 @@
12.23 def iadd(a, b):
12.24 if is_int(a) and is_int(b):
12.25 return int_add(a, b)
12.26 + elif a.__class__ is float and b.__class__ is float:
12.27 + return float_add(a, b)
12.28 return augassign(a, b, lambda a: a.__iadd__, lambda a: a.__add__, lambda b: b.__radd__)
12.29
12.30 def iand_(a, b):
12.31 @@ -46,6 +49,8 @@
12.32 def idiv(a, b):
12.33 if is_int(a) and is_int(b):
12.34 return int_div(a, b)
12.35 + elif a.__class__ is float and b.__class__ is float:
12.36 + return float_div(a, b)
12.37 return augassign(a, b, lambda a: a.__idiv__, lambda a: a.__div__, lambda b: b.__rdiv__)
12.38
12.39 def ifloordiv(a, b):
12.40 @@ -62,6 +67,8 @@
12.41 def imul(a, b):
12.42 if is_int(a) and is_int(b):
12.43 return int_mul(a, b)
12.44 + elif a.__class__ is float and b.__class__ is float:
12.45 + return float_mul(a, b)
12.46 return augassign(a, b, lambda a: a.__imul__, lambda a: a.__mul__, lambda b: b.__rmul__)
12.47
12.48 def ior_(a, b):
12.49 @@ -72,6 +79,8 @@
12.50 def ipow(a, b):
12.51 if is_int(a) and is_int(b):
12.52 return int_pow(a, b)
12.53 + elif a.__class__ is float and b.__class__ is float:
12.54 + return float_pow(a, b)
12.55 return augassign(a, b, lambda a: a.__ipow__, lambda a: a.__pow__, lambda b: b.__rpow__)
12.56
12.57 def irshift(a, b):
12.58 @@ -80,6 +89,8 @@
12.59 def isub(a, b):
12.60 if is_int(a) and is_int(b):
12.61 return int_sub(a, b)
12.62 + elif a.__class__ is float and b.__class__ is float:
12.63 + return float_sub(a, b)
12.64 return augassign(a, b, lambda a: a.__isub__, lambda a: a.__sub__, lambda b: b.__rsub__)
12.65
12.66 def ixor(a, b):
13.1 --- a/lib/operator/binary.py Fri Sep 01 23:41:53 2023 +0200
13.2 +++ b/lib/operator/binary.py Sat Sep 02 01:50:57 2023 +0200
13.3 @@ -3,7 +3,8 @@
13.4 """
13.5 Operator support.
13.6
13.7 -Copyright (C) 2010, 2013, 2015, 2016, 2017 Paul Boddie <paul@boddie.org.uk>
13.8 +Copyright (C) 2010, 2013, 2015, 2016, 2017,
13.9 + 2019 Paul Boddie <paul@boddie.org.uk>
13.10
13.11 This program is free software; you can redistribute it and/or modify it under
13.12 the terms of the GNU General Public License as published by the Free Software
13.13 @@ -23,7 +24,9 @@
13.14 from native import int_add, int_div, int_mod, int_mul, int_pow, int_sub, \
13.15 int_lshift, int_rshift, \
13.16 int_and, int_not, int_or, int_xor, \
13.17 - is_int
13.18 + is_int, \
13.19 + float_add, float_div, float_mul, float_pow, float_sub, \
13.20 + int_float
13.21
13.22 # These functions defer method lookup by wrapping the attribute access in
13.23 # lambda functions. Thus, the appropriate methods are defined locally, but no
13.24 @@ -34,6 +37,8 @@
13.25 def add(a, b):
13.26 if is_int(a) and is_int(b):
13.27 return int_add(a, b)
13.28 + elif a.__class__ is float and b.__class__ is float:
13.29 + return float_add(a, b)
13.30 return binary_op(a, b, lambda a: a.__add__, lambda b: b.__radd__)
13.31
13.32 def and_(a, b):
13.33 @@ -47,6 +52,8 @@
13.34 def div(a, b):
13.35 if is_int(a) and is_int(b):
13.36 return int_div(a, b)
13.37 + elif a.__class__ is float and b.__class__ is float:
13.38 + return float_div(a, b)
13.39 return binary_op(a, b, lambda a: a.__div__, lambda b: b.__rdiv__)
13.40
13.41 def floordiv(a, b):
13.42 @@ -71,6 +78,8 @@
13.43 def mul(a, b):
13.44 if is_int(a) and is_int(b):
13.45 return int_mul(a, b)
13.46 + elif a.__class__ is float and b.__class__ is float:
13.47 + return float_mul(a, b)
13.48 return binary_op(a, b, lambda a: a.__mul__, lambda b: b.__rmul__)
13.49
13.50 def or_(a, b):
13.51 @@ -81,6 +90,11 @@
13.52 def pow(a, b):
13.53 if is_int(a) and is_int(b):
13.54 return int_pow(a, b)
13.55 + elif a.__class__ is float:
13.56 + if is_int(b):
13.57 + return float_pow(a, int_float(b))
13.58 + if b.__class__ is float:
13.59 + return float_pow(a, b)
13.60 return binary_op(a, b, lambda a: a.__pow__, lambda b: b.__rpow__)
13.61
13.62 def rshift(a, b):
13.63 @@ -91,6 +105,8 @@
13.64 def sub(a, b):
13.65 if is_int(a) and is_int(b):
13.66 return int_sub(a, b)
13.67 + elif a.__class__ is float and b.__class__ is float:
13.68 + return float_sub(a, b)
13.69 return binary_op(a, b, lambda a: a.__sub__, lambda b: b.__rsub__)
13.70
13.71 def xor(a, b):
14.1 --- a/lib/operator/comparison.py Fri Sep 01 23:41:53 2023 +0200
14.2 +++ b/lib/operator/comparison.py Sat Sep 02 01:50:57 2023 +0200
14.3 @@ -3,7 +3,8 @@
14.4 """
14.5 Operator support.
14.6
14.7 -Copyright (C) 2010, 2013, 2015, 2016, 2017 Paul Boddie <paul@boddie.org.uk>
14.8 +Copyright (C) 2010, 2013, 2015, 2016, 2017,
14.9 + 2019 Paul Boddie <paul@boddie.org.uk>
14.10
14.11 This program is free software; you can redistribute it and/or modify it under
14.12 the terms of the GNU General Public License as published by the Free Software
14.13 @@ -20,7 +21,8 @@
14.14 """
14.15
14.16 from operator.core import binary_op
14.17 -from native import int_eq, int_ge, int_gt, int_le, int_lt, int_ne, is_int
14.18 +from native import int_eq, int_ge, int_gt, int_le, int_lt, int_ne, is_int, \
14.19 + float_eq, float_ge, float_gt, float_le, float_lt, float_ne
14.20
14.21 # These functions defer method lookup by wrapping the attribute access in
14.22 # lambda functions. Thus, the appropriate methods are defined locally, but no
14.23 @@ -31,31 +33,43 @@
14.24 def eq(a, b):
14.25 if is_int(a) and is_int(b):
14.26 return int_eq(a, b)
14.27 + elif a.__class__ is float and b.__class__ is float:
14.28 + return float_eq(a, b)
14.29 return binary_op(a, b, lambda a: a.__eq__, lambda b: b.__eq__, False)
14.30
14.31 def ge(a, b):
14.32 if is_int(a) and is_int(b):
14.33 return int_ge(a, b)
14.34 + elif a.__class__ is float and b.__class__ is float:
14.35 + return float_ge(a, b)
14.36 return binary_op(a, b, lambda a: a.__ge__, lambda b: b.__le__)
14.37
14.38 def gt(a, b):
14.39 if is_int(a) and is_int(b):
14.40 return int_gt(a, b)
14.41 + elif a.__class__ is float and b.__class__ is float:
14.42 + return float_gt(a, b)
14.43 return binary_op(a, b, lambda a: a.__gt__, lambda b: b.__lt__)
14.44
14.45 def le(a, b):
14.46 if is_int(a) and is_int(b):
14.47 return int_le(a, b)
14.48 + elif a.__class__ is float and b.__class__ is float:
14.49 + return float_le(a, b)
14.50 return binary_op(a, b, lambda a: a.__le__, lambda b: b.__ge__)
14.51
14.52 def lt(a, b):
14.53 if is_int(a) and is_int(b):
14.54 return int_lt(a, b)
14.55 + elif a.__class__ is float and b.__class__ is float:
14.56 + return float_lt(a, b)
14.57 return binary_op(a, b, lambda a: a.__lt__, lambda b: b.__gt__)
14.58
14.59 def ne(a, b):
14.60 if is_int(a) and is_int(b):
14.61 return int_ne(a, b)
14.62 + elif a.__class__ is float and b.__class__ is float:
14.63 + return float_ne(a, b)
14.64 return binary_op(a, b, lambda a: a.__ne__, lambda b: b.__ne__, True)
14.65
14.66 # vim: tabstop=4 expandtab shiftwidth=4
15.1 --- a/lib/operator/unary.py Fri Sep 01 23:41:53 2023 +0200
15.2 +++ b/lib/operator/unary.py Sat Sep 02 01:50:57 2023 +0200
15.3 @@ -3,7 +3,8 @@
15.4 """
15.5 Operator support.
15.6
15.7 -Copyright (C) 2010, 2013, 2015, 2016, 2017 Paul Boddie <paul@boddie.org.uk>
15.8 +Copyright (C) 2010, 2013, 2015, 2016, 2017,
15.9 + 2019 Paul Boddie <paul@boddie.org.uk>
15.10
15.11 This program is free software; you can redistribute it and/or modify it under
15.12 the terms of the GNU General Public License as published by the Free Software
15.13 @@ -20,7 +21,7 @@
15.14 """
15.15
15.16 from operator.core import unary_op
15.17 -from native.int import int_neg, int_not, is_int
15.18 +from native import int_neg, int_not, is_int, float_neg
15.19
15.20 # These functions defer method lookup by wrapping the attribute access in
15.21 # lambda functions. Thus, the appropriate methods are defined locally, but no
15.22 @@ -34,6 +35,8 @@
15.23 def neg(a):
15.24 if is_int(a):
15.25 return int_neg(a)
15.26 + elif a.__class__ is float:
15.27 + return float_neg(a)
15.28 return unary_op(a, lambda a: a.__neg__)
15.29
15.30 def not_(a):
15.31 @@ -42,7 +45,7 @@
15.32 return not a
15.33
15.34 def pos(a):
15.35 - if is_int(a):
15.36 + if is_int(a) or a.__class__ is float:
15.37 return a
15.38 return unary_op(a, lambda a: a.__pos__)
15.39
16.1 --- a/templates/Makefile Fri Sep 01 23:41:53 2023 +0200
16.2 +++ b/templates/Makefile Sat Sep 02 01:50:57 2023 +0200
16.3 @@ -2,7 +2,7 @@
16.4 include modules.mk
16.5 include options.mk
16.6
16.7 -SRC += calls.c exceptions.c main.c ops.c progops.c progtypes.c
16.8 +SRC += calls.c exceptions.c main.c ops.c progops.c progtypes.c signals.c
16.9 OBJ = $(SRC:.c=.o)
16.10 CFLAGS += -Wall -Wno-maybe-uninitialized -I. -finput-charset=UTF-8
16.11 LDFLAGS += -lm -lgc
17.1 --- a/templates/native/buffer.c Fri Sep 01 23:41:53 2023 +0200
17.2 +++ b/templates/native/buffer.c Sat Sep 02 01:50:57 2023 +0200
17.3 @@ -36,7 +36,7 @@
17.4
17.5 /* Calculate the size of the string. */
17.6 for (i = 0; i < data->size; i++)
17.7 - size += __load_via_object(__VALUE(data->attrs[i]), __size__).sizevalue;
17.8 + size += __TOINT(__load_via_object(__VALUE(data->attrs[i]), __size__));
17.9
17.10 /* Reserve space for a new string. */
17.11 s = (char *) __ALLOCATE(size + 1, sizeof(char));
17.12 @@ -45,7 +45,7 @@
17.13 for (i = 0, j = 0; i < data->size; i++)
17.14 {
17.15 o = __load_via_object(__VALUE(data->attrs[i]), __data__);
17.16 - n = __load_via_object(__VALUE(data->attrs[i]), __size__).sizevalue;
17.17 + n = __TOINT(__load_via_object(__VALUE(data->attrs[i]), __size__));
17.18 memcpy(s + j, o.strvalue, n); /* does not null terminate but final byte should be zero */
17.19 j += n;
17.20 }
18.1 --- a/templates/native/common.c Fri Sep 01 23:41:53 2023 +0200
18.2 +++ b/templates/native/common.c Sat Sep 02 01:50:57 2023 +0200
18.3 @@ -31,7 +31,7 @@
18.4 /* Create a new string and mutate the __data__, __size__ and __key__ attributes. */
18.5 __attr attr = __NEWINSTANCE(__builtins___str_str);
18.6 __store_via_object(__VALUE(attr), __data__, (__attr) {.strvalue=s});
18.7 - __store_via_object(__VALUE(attr), __size__, (__attr) {.sizevalue=size});
18.8 + __store_via_object(__VALUE(attr), __size__, __INTVALUE(size));
18.9 __store_via_object(__VALUE(attr), __key__, __NULL);
18.10 return attr;
18.11 }
18.12 @@ -44,6 +44,14 @@
18.13 return attr;
18.14 }
18.15
18.16 +__attr __new_float(double n)
18.17 +{
18.18 + /* Create a new float and set the trailing data. */
18.19 + __attr attr = __NEWINSTANCEIM(__builtins___float_float);
18.20 + __set_trailing_data(attr, __builtins___float_float, n);
18.21 + return attr;
18.22 +}
18.23 +
18.24 __fragment *__fragment_append(__fragment *data, __attr value)
18.25 {
18.26 __fragment *newdata = data;
19.1 --- a/templates/native/common.h Fri Sep 01 23:41:53 2023 +0200
19.2 +++ b/templates/native/common.h Sat Sep 02 01:50:57 2023 +0200
19.3 @@ -1,6 +1,6 @@
19.4 /* Common operations for native functions.
19.5
19.6 -Copyright (C) 2016, 2017 Paul Boddie <paul@boddie.org.uk>
19.7 +Copyright (C) 2016, 2017, 2018, 2021 Paul Boddie <paul@boddie.org.uk>
19.8
19.9 This program is free software; you can redistribute it and/or modify it under
19.10 the terms of the GNU General Public License as published by the Free Software
19.11 @@ -21,11 +21,15 @@
19.12
19.13 #include "types.h"
19.14
19.15 -/* Utility functions. */
19.16 +/* Utility macro for the special integer representation. */
19.17
19.18 #define __new_int(VALUE) __INTVALUE(VALUE)
19.19 +
19.20 +/* Utility functions. */
19.21 +
19.22 __attr __new_str(char *s, __int size);
19.23 __attr __new_list(__fragment *f);
19.24 +__attr __new_float(double n);
19.25 __fragment *__fragment_append(__fragment *data, __attr value);
19.26
19.27 #endif /* __NATIVE_COMMON_H__ */
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
20.2 +++ b/templates/native/float.c Sat Sep 02 01:50:57 2023 +0200
20.3 @@ -0,0 +1,216 @@
20.4 +/* Native functions for floating point operations.
20.5 +
20.6 +Copyright (C) 2016, 2017, 2018, 2019 Paul Boddie <paul@boddie.org.uk>
20.7 +
20.8 +This program is free software; you can redistribute it and/or modify it under
20.9 +the terms of the GNU General Public License as published by the Free Software
20.10 +Foundation; either version 3 of the License, or (at your option) any later
20.11 +version.
20.12 +
20.13 +This program is distributed in the hope that it will be useful, but WITHOUT
20.14 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
20.15 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
20.16 +details.
20.17 +
20.18 +You should have received a copy of the GNU General Public License along with
20.19 +this program. If not, see <http://www.gnu.org/licenses/>.
20.20 +*/
20.21 +
20.22 +#include <math.h> /* pow */
20.23 +#include <stdio.h> /* snprintf */
20.24 +#include <errno.h> /* errno */
20.25 +#include "native/common.h"
20.26 +#include "types.h"
20.27 +#include "exceptions.h"
20.28 +#include "ops.h"
20.29 +#include "progconsts.h"
20.30 +#include "progops.h"
20.31 +#include "progtypes.h"
20.32 +#include "main.h"
20.33 +
20.34 +/* Conversion of trailing data to a double-precision floating point number. */
20.35 +
20.36 +static double __TOFLOAT(__attr attr)
20.37 +{
20.38 + return __get_trailing_data(attr, __builtins___float_float);
20.39 +}
20.40 +
20.41 +/* Numeric formatting using snprintf.
20.42 + NOTE: This might be moved elsewhere and used by other types. */
20.43 +
20.44 +static __attr format_number(double n, int size)
20.45 +{
20.46 + char *s = (char *) __ALLOCATE(size, sizeof(char));
20.47 + int digits;
20.48 +
20.49 + /* Allocation should raise a memory error if it fails, so this loop should
20.50 + terminate via the return statement or an allocation failure. */
20.51 +
20.52 + while (1)
20.53 + {
20.54 + digits = snprintf(s, size, "%f", n);
20.55 +
20.56 + if (digits < size)
20.57 + {
20.58 + s = (char *) __REALLOCATE(s, (digits + 1) * sizeof(char));
20.59 + return __new_str(s, digits);
20.60 + }
20.61 +
20.62 + size = digits + 1;
20.63 + s = (char *) __REALLOCATE(s, size * sizeof(char));
20.64 + }
20.65 +
20.66 + return __NULL;
20.67 +}
20.68 +
20.69 +/* Floating point operations. Exceptions are raised in the signal handler. */
20.70 +
20.71 +__attr __fn_native_float_float_add(__attr __self, __attr self, __attr other)
20.72 +{
20.73 + /* self and other interpreted as float */
20.74 + double i = __TOFLOAT(self);
20.75 + double j = __TOFLOAT(other);
20.76 + return __new_float(i + j);
20.77 +}
20.78 +
20.79 +__attr __fn_native_float_float_sub(__attr __self, __attr self, __attr other)
20.80 +{
20.81 + /* self and other interpreted as float */
20.82 + double i = __TOFLOAT(self);
20.83 + double j = __TOFLOAT(other);
20.84 + return __new_float(i - j);
20.85 +}
20.86 +
20.87 +__attr __fn_native_float_float_mul(__attr __self, __attr self, __attr other)
20.88 +{
20.89 + /* self and other interpreted as float */
20.90 + double i = __TOFLOAT(self);
20.91 + double j = __TOFLOAT(other);
20.92 + return __new_float(i * j);
20.93 +}
20.94 +
20.95 +__attr __fn_native_float_float_div(__attr __self, __attr self, __attr other)
20.96 +{
20.97 + /* self and other interpreted as float */
20.98 + double i = __TOFLOAT(self);
20.99 + double j = __TOFLOAT(other);
20.100 + return __new_float(i / j);
20.101 +}
20.102 +
20.103 +__attr __fn_native_float_float_mod(__attr __self, __attr self, __attr other)
20.104 +{
20.105 + /* self and other interpreted as float */
20.106 + double i = __TOFLOAT(self);
20.107 + double j = __TOFLOAT(other);
20.108 + return __new_float(fmod(i, j));
20.109 +}
20.110 +
20.111 +__attr __fn_native_float_float_neg(__attr __self, __attr self)
20.112 +{
20.113 + /* self interpreted as float */
20.114 + double i = __TOFLOAT(self);
20.115 + return __new_float(-i);
20.116 +}
20.117 +
20.118 +__attr __fn_native_float_float_pow(__attr __self, __attr self, __attr other)
20.119 +{
20.120 + /* self and other interpreted as float */
20.121 + double i = __TOFLOAT(self);
20.122 + double j = __TOFLOAT(other);
20.123 + double result;
20.124 +
20.125 + errno = 0;
20.126 + result = pow(i, j);
20.127 +
20.128 + /* Test for overflow. */
20.129 +
20.130 + if (errno == ERANGE)
20.131 + __raise_overflow_error();
20.132 +
20.133 + /* Return the result. */
20.134 + return __new_float(result);
20.135 +}
20.136 +
20.137 +__attr __fn_native_float_float_le(__attr __self, __attr self, __attr other)
20.138 +{
20.139 + /* self and other interpreted as float */
20.140 + double i = __TOFLOAT(self);
20.141 + double j = __TOFLOAT(other);
20.142 +
20.143 + /* Return a boolean result. */
20.144 + return i <= j ? __builtins___boolean_True : __builtins___boolean_False;
20.145 +}
20.146 +
20.147 +__attr __fn_native_float_float_lt(__attr __self, __attr self, __attr other)
20.148 +{
20.149 + /* self and other interpreted as float */
20.150 + double i = __TOFLOAT(self);
20.151 + double j = __TOFLOAT(other);
20.152 +
20.153 + /* Return a boolean result. */
20.154 + return i < j ? __builtins___boolean_True : __builtins___boolean_False;
20.155 +}
20.156 +
20.157 +__attr __fn_native_float_float_ge(__attr __self, __attr self, __attr other)
20.158 +{
20.159 + /* self and other interpreted as float */
20.160 + double i = __TOFLOAT(self);
20.161 + double j = __TOFLOAT(other);
20.162 +
20.163 + /* Return a boolean result. */
20.164 + return i >= j ? __builtins___boolean_True : __builtins___boolean_False;
20.165 +}
20.166 +
20.167 +__attr __fn_native_float_float_gt(__attr __self, __attr self, __attr other)
20.168 +{
20.169 + /* self and other interpreted as float */
20.170 + double i = __TOFLOAT(self);
20.171 + double j = __TOFLOAT(other);
20.172 +
20.173 + /* Return a boolean result. */
20.174 + return i > j ? __builtins___boolean_True : __builtins___boolean_False;
20.175 +}
20.176 +
20.177 +__attr __fn_native_float_float_eq(__attr __self, __attr self, __attr other)
20.178 +{
20.179 + /* self and other interpreted as float */
20.180 + double i = __TOFLOAT(self);
20.181 + double j = __TOFLOAT(other);
20.182 +
20.183 + /* Return a boolean result. */
20.184 + return i == j ? __builtins___boolean_True : __builtins___boolean_False;
20.185 +}
20.186 +
20.187 +__attr __fn_native_float_float_ne(__attr __self, __attr self, __attr other)
20.188 +{
20.189 + /* self and other interpreted as float */
20.190 + double i = __TOFLOAT(self);
20.191 + double j = __TOFLOAT(other);
20.192 +
20.193 + /* Return a boolean result. */
20.194 + return i != j ? __builtins___boolean_True : __builtins___boolean_False;
20.195 +}
20.196 +
20.197 +__attr __fn_native_float_float_str(__attr __self, __attr self)
20.198 +{
20.199 + /* self interpreted as float */
20.200 + double i = __TOFLOAT(self);
20.201 +
20.202 + /* Return a new string. */
20.203 + return format_number(i, 64);
20.204 +}
20.205 +
20.206 +__attr __fn_native_float_float_int(__attr __self, __attr self)
20.207 +{
20.208 + /* self interpreted as float */
20.209 + double i = __TOFLOAT(self);
20.210 +
20.211 + /* NOTE: Test for conversion failure. */
20.212 + return __new_int((int) i);
20.213 +}
20.214 +
20.215 +/* Module initialisation. */
20.216 +
20.217 +void __main_native_float()
20.218 +{
20.219 +}
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
21.2 +++ b/templates/native/float.h Sat Sep 02 01:50:57 2023 +0200
21.3 @@ -0,0 +1,48 @@
21.4 +/* Native functions for floating point operations.
21.5 +
21.6 +Copyright (C) 2018 Paul Boddie <paul@boddie.org.uk>
21.7 +
21.8 +This program is free software; you can redistribute it and/or modify it under
21.9 +the terms of the GNU General Public License as published by the Free Software
21.10 +Foundation; either version 3 of the License, or (at your option) any later
21.11 +version.
21.12 +
21.13 +This program is distributed in the hope that it will be useful, but WITHOUT
21.14 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
21.15 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
21.16 +details.
21.17 +
21.18 +You should have received a copy of the GNU General Public License along with
21.19 +this program. If not, see <http://www.gnu.org/licenses/>.
21.20 +*/
21.21 +
21.22 +#ifndef __NATIVE_FLOAT_H__
21.23 +#define __NATIVE_FLOAT_H__
21.24 +
21.25 +#include "types.h"
21.26 +
21.27 +/* Floating point operations. */
21.28 +
21.29 +__attr __fn_native_float_float_add(__attr __self, __attr self, __attr other);
21.30 +__attr __fn_native_float_float_sub(__attr __self, __attr self, __attr other);
21.31 +__attr __fn_native_float_float_mul(__attr __self, __attr self, __attr other);
21.32 +__attr __fn_native_float_float_div(__attr __self, __attr self, __attr other);
21.33 +__attr __fn_native_float_float_mod(__attr __self, __attr self, __attr other);
21.34 +__attr __fn_native_float_float_neg(__attr __self, __attr self);
21.35 +__attr __fn_native_float_float_pow(__attr __self, __attr self, __attr other);
21.36 +
21.37 +__attr __fn_native_float_float_le(__attr __self, __attr self, __attr other);
21.38 +__attr __fn_native_float_float_lt(__attr __self, __attr self, __attr other);
21.39 +__attr __fn_native_float_float_ge(__attr __self, __attr self, __attr other);
21.40 +__attr __fn_native_float_float_gt(__attr __self, __attr self, __attr other);
21.41 +__attr __fn_native_float_float_eq(__attr __self, __attr self, __attr other);
21.42 +__attr __fn_native_float_float_ne(__attr __self, __attr self, __attr other);
21.43 +
21.44 +__attr __fn_native_float_float_str(__attr __self, __attr self);
21.45 +__attr __fn_native_float_float_int(__attr __self, __attr self);
21.46 +
21.47 +/* Module initialisation. */
21.48 +
21.49 +void __main_native_float();
21.50 +
21.51 +#endif /* __NATIVE_FLOAT_H__ */
22.1 --- a/templates/native/int.c Fri Sep 01 23:41:53 2023 +0200
22.2 +++ b/templates/native/int.c Sat Sep 02 01:50:57 2023 +0200
22.3 @@ -1,6 +1,6 @@
22.4 /* Native functions for integer operations.
22.5
22.6 -Copyright (C) 2016, 2017, 2021 Paul Boddie <paul@boddie.org.uk>
22.7 +Copyright (C) 2016, 2017, 2018, 2021 Paul Boddie <paul@boddie.org.uk>
22.8
22.9 This program is free software; you can redistribute it and/or modify it under
22.10 the terms of the GNU General Public License as published by the Free Software
22.11 @@ -294,6 +294,14 @@
22.12 return __new_str(s, strlen(s));
22.13 }
22.14
22.15 +__attr __fn_native_int_int_float(__attr __self, __attr self)
22.16 +{
22.17 + /* self interpreted as int */
22.18 + int i = __TOINT(self);
22.19 +
22.20 + return __new_float((double) i);
22.21 +}
22.22 +
22.23 /* Module initialisation. */
22.24
22.25 void __main_native_int()
23.1 --- a/templates/native/int.h Fri Sep 01 23:41:53 2023 +0200
23.2 +++ b/templates/native/int.h Sat Sep 02 01:50:57 2023 +0200
23.3 @@ -1,6 +1,6 @@
23.4 /* Native functions for integer operations.
23.5
23.6 -Copyright (C) 2016, 2017 Paul Boddie <paul@boddie.org.uk>
23.7 +Copyright (C) 2016, 2017, 2018 Paul Boddie <paul@boddie.org.uk>
23.8
23.9 This program is free software; you can redistribute it and/or modify it under
23.10 the terms of the GNU General Public License as published by the Free Software
23.11 @@ -48,6 +48,7 @@
23.12 __attr __fn_native_int_int_ne(__attr __self, __attr _data, __attr other);
23.13
23.14 __attr __fn_native_int_int_str(__attr __self, __attr _data);
23.15 +__attr __fn_native_int_int_float(__attr __self, __attr _data);
23.16
23.17 /* Module initialisation. */
23.18
24.1 --- a/templates/native/io.c Fri Sep 01 23:41:53 2023 +0200
24.2 +++ b/templates/native/io.c Sat Sep 02 01:50:57 2023 +0200
24.3 @@ -150,7 +150,7 @@
24.4 /* str.__data__ interpreted as string */
24.5 char *s = __load_via_object(__VALUE(str), __data__).strvalue;
24.6 /* str.__size__ interpreted as int */
24.7 - size_t to_write = __load_via_object(__VALUE(str), __size__).sizevalue;
24.8 + size_t to_write = __TOINT(__load_via_object(__VALUE(str), __size__));
24.9 size_t have_written = fwrite(s, sizeof(char), to_write, f);
24.10 int error;
24.11
24.12 @@ -207,7 +207,7 @@
24.13 /* str.__data__ interpreted as string */
24.14 char *s = __load_via_object(__VALUE(str), __data__).strvalue;
24.15 /* str.__size__ interpreted as int */
24.16 - size_t size = __load_via_object(__VALUE(str), __size__).sizevalue;
24.17 + size_t size = __TOINT(__load_via_object(__VALUE(str), __size__));
24.18 ssize_t have_written;
24.19
24.20 errno = 0;
25.1 --- a/templates/native/str.c Fri Sep 01 23:41:53 2023 +0200
25.2 +++ b/templates/native/str.c Sat Sep 02 01:50:57 2023 +0200
25.3 @@ -34,7 +34,7 @@
25.4 char *s = _data.strvalue;
25.5 char *o = other.strvalue;
25.6 /* _size, othersize interpreted as size */
25.7 - __int ss = _size.sizevalue, os = othersize.sizevalue;
25.8 + __int ss = __TOINT(_size), os = __TOINT(othersize);
25.9 __int n = ss + os;
25.10 char *r = (char *) __ALLOCATE(n + 1, sizeof(char));
25.11
25.12 @@ -95,7 +95,7 @@
25.13
25.14 __attr __fn_native_str_str_size(__attr __self, __attr _size)
25.15 {
25.16 - return __new_int(_size.sizevalue);
25.17 + return __new_int(__TOINT(_size));
25.18 }
25.19
25.20 __attr __fn_native_str_str_substr(__attr __self, __attr _data, __attr start, __attr end, __attr step)
26.1 --- a/templates/native/unicode.c Fri Sep 01 23:41:53 2023 +0200
26.2 +++ b/templates/native/unicode.c Sat Sep 02 01:50:57 2023 +0200
26.3 @@ -74,7 +74,7 @@
26.4 /* _data interpreted as string.__data__ */
26.5 char *s = _data.strvalue;
26.6 /* _size interpreted as size */
26.7 - __int size = _size.sizevalue;
26.8 + __int size = __TOINT(_size);
26.9 __int i, c = 0;
26.10
26.11 for (i = 0; i < size; i++)
26.12 @@ -90,7 +90,7 @@
26.13 /* _data interpreted as string.__data__ */
26.14 char *s = _data.strvalue;
26.15 /* _size interpreted as size */
26.16 - __int size = _size.sizevalue;
26.17 + __int size = __TOINT(_size);
26.18 __int i, c = 0, v;
26.19
26.20 for (i = 0; i < size; i++)
26.21 @@ -124,7 +124,7 @@
26.22 /* _data interpreted as string.__data__ */
26.23 char *s = _data.strvalue, *sub;
26.24 /* _size interpreted as size */
26.25 - __int ss = _size.sizevalue;
26.26 + __int ss = __TOINT(_size);
26.27 /* start interpreted as int */
26.28 __int istart = __TOINT(start);
26.29 /* end interpreted as int */
27.1 --- a/templates/ops.c Fri Sep 01 23:41:53 2023 +0200
27.2 +++ b/templates/ops.c Sat Sep 02 01:50:57 2023 +0200
27.3 @@ -30,7 +30,7 @@
27.4 if (!__INTEGER(attr))
27.5 return attr.value;
27.6 else
27.7 - return &__common_integer_obj;
27.8 + return (__ref) &__common_integer_obj;
27.9 }
27.10
27.11 /* Basic structure tests. */
28.1 --- a/templates/progops.c Fri Sep 01 23:41:53 2023 +0200
28.2 +++ b/templates/progops.c Sat Sep 02 01:50:57 2023 +0200
28.3 @@ -1,6 +1,6 @@
28.4 /* Operations depending on program specifics.
28.5
28.6 -Copyright (C) 2015, 2016, 2017, 2018, 2021 Paul Boddie <paul@boddie.org.uk>
28.7 +Copyright (C) 2015-2019, 2021 Paul Boddie <paul@boddie.org.uk>
28.8
28.9 This program is free software; you can redistribute it and/or modify it under
28.10 the terms of the GNU General Public License as published by the Free Software
28.11 @@ -127,6 +127,11 @@
28.12 #endif /* __HAVE___builtins___exception_io_EOFError */
28.13 }
28.14
28.15 +void __raise_floating_point_error()
28.16 +{
28.17 + __Raise(__new___builtins___core_FloatingPointError(__NULL));
28.18 +}
28.19 +
28.20 void __raise_io_error(__attr value)
28.21 {
28.22 #ifdef __HAVE___builtins___exception_io_IOError
28.23 @@ -161,6 +166,11 @@
28.24 __Raise(__new___builtins___core_TypeError(__NULL));
28.25 }
28.26
28.27 +void __raise_underflow_error()
28.28 +{
28.29 + __Raise(__new___builtins___core_UnderflowError(__NULL));
28.30 +}
28.31 +
28.32 void __raise_value_error(__attr value)
28.33 {
28.34 #ifdef __HAVE___builtins___exception_base_ValueError
28.35 @@ -324,7 +334,7 @@
28.36
28.37 value = attr.value;
28.38
28.39 - return value == &__predefined___builtins___boolean_True ? 1 :
28.40 - value == &__predefined___builtins___boolean_False ? 0 :
28.41 - __VALUE(__fn___builtins___boolean_bool(__NULL, attr)) == &__predefined___builtins___boolean_True;
28.42 + return value == (__ref) &__predefined___builtins___boolean_True ? 1 :
28.43 + value == (__ref) &__predefined___builtins___boolean_False ? 0 :
28.44 + __VALUE(__fn___builtins___boolean_bool(__NULL, attr)) == (__ref) &__predefined___builtins___boolean_True;
28.45 }
29.1 --- a/templates/progops.h Fri Sep 01 23:41:53 2023 +0200
29.2 +++ b/templates/progops.h Sat Sep 02 01:50:57 2023 +0200
29.3 @@ -1,6 +1,6 @@
29.4 /* Operations depending on program specifics.
29.5
29.6 -Copyright (C) 2015, 2016, 2017, 2018, 2021 Paul Boddie <paul@boddie.org.uk>
29.7 +Copyright (C) 2015-2019, 2021 Paul Boddie <paul@boddie.org.uk>
29.8
29.9 This program is free software; you can redistribute it and/or modify it under
29.10 the terms of the GNU General Public License as published by the Free Software
29.11 @@ -38,29 +38,25 @@
29.12 #define __newliteral___builtins___list_list(NUM, ...) __newdata_list(NUM, __ARGS(__VA_ARGS__))
29.13 #define __newliteral___builtins___tuple_tuple(NUM, ...) __newdata_tuple(NUM, __ARGS(__VA_ARGS__))
29.14
29.15 +/* Potentially superfluous operations. */
29.16 +
29.17 #ifdef __HAVE___builtins___dict_dict
29.18 __attr __newdata_dict(__int number, __attr args[]);
29.19 #define __newliteral___builtins___dict_dict(NUM, ...) __newdata_dict(NUM, __ARGS(__VA_ARGS__))
29.20 -#endif /* __HAVE___builtins___dict_dict */
29.21 +#endif
29.22
29.23 /* Helpers for raising errors within common operations. */
29.24
29.25 void __raise_eof_error();
29.26 -
29.27 +void __raise_floating_point_error();
29.28 void __raise_io_error(__attr value);
29.29 -
29.30 void __raise_memory_error();
29.31 -
29.32 void __raise_os_error(__attr value, __attr arg);
29.33 -
29.34 void __raise_overflow_error();
29.35 -
29.36 void __raise_unbound_method_error();
29.37 -
29.38 +void __raise_underflow_error();
29.39 void __raise_value_error(__attr value);
29.40 -
29.41 void __raise_zero_division_error();
29.42 -
29.43 void __raise_type_error();
29.44
29.45 /* Helper for raising exception instances. */
29.46 @@ -80,17 +76,21 @@
29.47 /* Generic operations depending on specific program details. */
29.48
29.49 void __SETDEFAULT(__ref obj, int pos, __attr value);
29.50 -
29.51 __attr __GETDEFAULT(__ref obj, int pos);
29.52 -
29.53 int __BOOL(__attr attr);
29.54
29.55 /* Convenience definitions. */
29.56
29.57 -#define __INSTANCESIZE(CLS) sizeof(__obj_##CLS)
29.58 +#define __OBJTYPE(CLS) __obj_##CLS
29.59 +#define __INSTANCESIZE(CLS) sizeof(__OBJTYPE(CLS))
29.60 #define __INSTANCETABLE(CLS) (__InstanceTable_##CLS)
29.61 #define __NEWINSTANCE(CLS) __new(&__INSTANCETABLE(CLS), &CLS, __INSTANCESIZE(CLS), 0)
29.62 #define __NEWINSTANCEIM(CLS) __new(&__INSTANCETABLE(CLS), &CLS, __INSTANCESIZE(CLS), 1)
29.63 #define __ISINSTANCE(ATTR, TYPE) __BOOL(__fn_native_introspection_isinstance(__NULL, ATTR, TYPE))
29.64
29.65 +/* Operations for accessing trailing data. */
29.66 +
29.67 +#define __get_trailing_data(ATTR, TYPE) (((__OBJTYPE(TYPE) *) ((ATTR).value))->trailing)
29.68 +#define __set_trailing_data(ATTR, TYPE, VALUE) ((__OBJTYPE(TYPE) *) ((ATTR).value))->trailing = VALUE;
29.69 +
29.70 #endif /* __PROGOPS_H__ */
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
30.2 +++ b/templates/signals.c Sat Sep 02 01:50:57 2023 +0200
30.3 @@ -0,0 +1,60 @@
30.4 +/* Signal handling.
30.5 +
30.6 +Copyright (C) 2019 Paul Boddie <paul@boddie.org.uk>
30.7 +
30.8 +This program is free software; you can redistribute it and/or modify it under
30.9 +the terms of the GNU General Public License as published by the Free Software
30.10 +Foundation; either version 3 of the License, or (at your option) any later
30.11 +version.
30.12 +
30.13 +This program is distributed in the hope that it will be useful, but WITHOUT
30.14 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
30.15 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
30.16 +details.
30.17 +
30.18 +You should have received a copy of the GNU General Public License along with
30.19 +this program. If not, see <http://www.gnu.org/licenses/>.
30.20 +*/
30.21 +
30.22 +#include <signal.h>
30.23 +#include <stdlib.h>
30.24 +
30.25 +#include "signals.h"
30.26 +#include "progops.h"
30.27 +
30.28 +void __signals_install_handlers()
30.29 +{
30.30 + struct sigaction context;
30.31 +
30.32 + context.sa_flags = SA_SIGINFO;
30.33 + context.sa_sigaction = __signals_fpe_handler;
30.34 + sigemptyset(&context.sa_mask);
30.35 +
30.36 + /* NOTE: Should test for -1 and errno. */
30.37 +
30.38 + sigaction(SIGFPE, &context, NULL);
30.39 +}
30.40 +
30.41 +void __signals_fpe_handler(int signum, siginfo_t *siginfo, void *context)
30.42 +{
30.43 + /* Return from setjmp using the signal number. */
30.44 +
30.45 + switch (siginfo->si_code)
30.46 + {
30.47 + case FPE_FLTOVF:
30.48 + __raise_overflow_error();
30.49 + break;
30.50 +
30.51 + case FPE_FLTUND:
30.52 + __raise_underflow_error();
30.53 + break;
30.54 +
30.55 + case FPE_FLTDIV:
30.56 + __raise_zero_division_error();
30.57 + break;
30.58 +
30.59 + default:
30.60 + __raise_floating_point_error();
30.61 + break;
30.62 + }
30.63 +}
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
31.2 +++ b/templates/signals.h Sat Sep 02 01:50:57 2023 +0200
31.3 @@ -0,0 +1,27 @@
31.4 +/* Signal handling.
31.5 +
31.6 +Copyright (C) 2019 Paul Boddie <paul@boddie.org.uk>
31.7 +
31.8 +This program is free software; you can redistribute it and/or modify it under
31.9 +the terms of the GNU General Public License as published by the Free Software
31.10 +Foundation; either version 3 of the License, or (at your option) any later
31.11 +version.
31.12 +
31.13 +This program is distributed in the hope that it will be useful, but WITHOUT
31.14 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
31.15 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
31.16 +details.
31.17 +
31.18 +You should have received a copy of the GNU General Public License along with
31.19 +this program. If not, see <http://www.gnu.org/licenses/>.
31.20 +*/
31.21 +
31.22 +#ifndef __SIGNALS_H__
31.23 +#define __SIGNALS_H__
31.24 +
31.25 +#include <signal.h>
31.26 +
31.27 +void __signals_install_handlers();
31.28 +void __signals_fpe_handler(int signum, siginfo_t *siginfo, void *context);
31.29 +
31.30 +#endif /* __SIGNALS_H__ */
32.1 --- a/templates/types.h Fri Sep 01 23:41:53 2023 +0200
32.2 +++ b/templates/types.h Sat Sep 02 01:50:57 2023 +0200
32.3 @@ -82,7 +82,8 @@
32.4 /* General attribute members. */
32.5
32.6 __ref value; /* attribute value */
32.7 - __int intvalue; /* integer value data (shifted value, tagged) */
32.8 + __int intvalue; /* integer value data or object-specific size
32.9 + (shifted value, tagged) */
32.10
32.11 /* Special case attribute members. */
32.12
32.13 @@ -92,11 +93,9 @@
32.14 __ppos pos; /* parameter table position for key */
32.15 };
32.16 __attr (*fn)(); /* callable details */
32.17 - float floatvalue; /* floating point value */
32.18 char * strvalue; /* string value */
32.19 __fragment * seqvalue; /* sequence data */
32.20 void * datavalue; /* object-specific data */
32.21 - __int sizevalue; /* object-specific size */
32.22 } __attr;
32.23
32.24 typedef struct __obj
32.25 @@ -104,6 +103,11 @@
32.26 const __table * table; /* attribute table */
32.27 __ppos pos; /* position of attribute indicating class */
32.28 __attr attrs[]; /* attributes */
32.29 +
32.30 + /* Specialisations of this type may add other members.
32.31 + See generator.py for type generation, progops.h for definitions, and
32.32 + the generated progtypes.h for the final details. */
32.33 +
32.34 } __obj;
32.35
32.36 #define __INSTANCE_SIZE(NUMBER) ((NUMBER) * sizeof(__attr) + sizeof(__table *) + sizeof(__ppos))
32.37 @@ -132,9 +136,10 @@
32.38 #define __NULL __ATTRVALUE(0)
32.39 #define __SETNULL(ATTR) ((ATTR).value = 0)
32.40
32.41 -/* Attribute as instance setting. */
32.42 +/* Attribute as instance value. */
32.43
32.44 -#define __INTVALUE(VALUE) ((__attr) {.intvalue=(((__int) VALUE) << __NUM_TAG_BITS) | __TAG_INT})
32.45 +#define __FROMINT(VALUE) ((((__int) VALUE) << __NUM_TAG_BITS) | __TAG_INT)
32.46 +#define __INTVALUE(VALUE) ((__attr) {.intvalue=__FROMINT(VALUE)})
32.47 #define __TOINT(ATTR) ((ATTR).intvalue >> __NUM_TAG_BITS)
32.48 #define __MAXINT ((((__int) 1) << ((sizeof(__int) * 8) - 1 - __NUM_TAG_BITS)) - 1)
32.49 #define __MININT (-(((__int) 1) << ((sizeof(__int) * 8) - 1 - __NUM_TAG_BITS)))
33.1 --- a/tests/numbers.py Fri Sep 01 23:41:53 2023 +0200
33.2 +++ b/tests/numbers.py Sat Sep 02 01:50:57 2023 +0200
33.3 @@ -55,6 +55,21 @@
33.4 print "# hash((sys.maxint - 1, 0)):",
33.5 print hash((sys.maxint - 1, 0))
33.6
33.7 +# Floating point numbers.
33.8 +
33.9 +i = 2.0 ** 29
33.10 +print i # 536870912.0
33.11 +j = -2.0 ** 29
33.12 +print j # -536870912.0
33.13 +print i + j # 0
33.14 +print i - j # -1073741824.0
33.15 +print i * i # 2.8823037615171174e+17
33.16 +
33.17 +try:
33.18 + print i ** i
33.19 +except OverflowError:
33.20 + print "i ** i: overflow occurred"
33.21 +
33.22 # Test combining numbers with strings.
33.23
33.24 s = "Number is " + str(123)
34.1 --- a/translator.py Fri Sep 01 23:41:53 2023 +0200
34.2 +++ b/translator.py Sat Sep 02 01:50:57 2023 +0200
34.3 @@ -885,7 +885,7 @@
34.4
34.5 # Produce the body and any additional return statement.
34.6
34.7 - expr = self.process_structure_node(n.code) or \
34.8 + expr = self.process_statement_node(n.code) or \
34.9 self.in_method() and \
34.10 function_name.rsplit(".", 1)[-1] == "__init__" and \
34.11 TrResolvedNameRef("self", self.importer.function_locals[function_name]["self"]) or \
34.12 @@ -1038,12 +1038,12 @@
34.13
34.14 first = True
34.15 for test, body in n.tests:
34.16 - test_ref = self.process_structure_node(test)
34.17 + test_ref = self.process_statement_node(test)
34.18 self.start_if(first, test_ref)
34.19
34.20 in_conditional = self.in_conditional
34.21 self.in_conditional = True
34.22 - self.process_structure_node(body)
34.23 + self.process_statement_node(body)
34.24 self.in_conditional = in_conditional
34.25
34.26 self.end_if()
34.27 @@ -1051,7 +1051,7 @@
34.28
34.29 if n.else_:
34.30 self.start_else()
34.31 - self.process_structure_node(n.else_)
34.32 + self.process_statement_node(n.else_)
34.33 self.end_else()
34.34
34.35 print >>self.out
34.36 @@ -1769,7 +1769,7 @@
34.37 self.writestmt("__Try")
34.38 self.writeline("{")
34.39 self.indent += 1
34.40 - self.process_structure_node(n.body)
34.41 + self.process_statement_node(n.body)
34.42
34.43 # Put the else statement in another try block that handles any raised
34.44 # exceptions and converts them to exceptions that will not be handled by
34.45 @@ -1779,7 +1779,7 @@
34.46 self.writestmt("__Try")
34.47 self.writeline("{")
34.48 self.indent += 1
34.49 - self.process_structure_node(n.else_)
34.50 + self.process_statement_node(n.else_)
34.51 self.indent -= 1
34.52 self.writeline("}")
34.53 self.writeline("__Catch (__tmp_exc)")
34.54 @@ -1823,7 +1823,7 @@
34.55 # Test for specific exceptions.
34.56
34.57 if name is not None:
34.58 - name_ref = self.process_structure_node(name)
34.59 + name_ref = self.process_statement_node(name)
34.60 self.writeline("else if (__ISINSTANCE(__tmp_exc.arg, %s))" % name_ref)
34.61 else:
34.62 self.writeline("else if (1)")
34.63 @@ -1837,7 +1837,7 @@
34.64 self.writestmt("%s;" % self.process_name_node(var, make_expression("__tmp_exc.arg")))
34.65
34.66 if handler is not None:
34.67 - self.process_structure_node(handler)
34.68 + self.process_statement_node(handler)
34.69
34.70 self.indent -= 1
34.71 self.writeline("}")
34.72 @@ -1866,7 +1866,7 @@
34.73 self.writestmt("__Try")
34.74 self.writeline("{")
34.75 self.indent += 1
34.76 - self.process_structure_node(n.body)
34.77 + self.process_statement_node(n.body)
34.78 self.indent -= 1
34.79 self.writeline("}")
34.80
34.81 @@ -1877,7 +1877,7 @@
34.82 self.writeline("__Catch (__tmp_exc)")
34.83 self.writeline("{")
34.84 self.indent += 1
34.85 - self.process_structure_node(n.final)
34.86 + self.process_statement_node(n.final)
34.87
34.88 # Introduce an if statement to handle the completion of a try block.
34.89
34.90 @@ -1918,7 +1918,7 @@
34.91 self.writeline("while (1)")
34.92 self.writeline("{")
34.93 self.indent += 1
34.94 - test = self.process_structure_node(n.test)
34.95 + test = self.process_statement_node(n.test)
34.96
34.97 # Emit the loop termination condition unless "while <true value>" is
34.98 # indicated.
34.99 @@ -1929,13 +1929,13 @@
34.100
34.101 self.start_if(True, self.make_negation(test))
34.102 if n.else_:
34.103 - self.process_structure_node(n.else_)
34.104 + self.process_statement_node(n.else_)
34.105 self.writestmt("break;")
34.106 self.end_if()
34.107
34.108 in_conditional = self.in_conditional
34.109 self.in_conditional = True
34.110 - self.process_structure_node(n.body)
34.111 + self.process_statement_node(n.body)
34.112 self.in_conditional = in_conditional
34.113
34.114 self.indent -= 1