[Nickle] nickle: Branch 'master' - 18 commits

Keith Packard keithp at keithp.com
Mon Oct 28 23:40:04 PDT 2024


 README.release              |   39 ++----
 alarm.c                     |    1 
 array.c                     |    1 
 atom.c                      |    1 
 bench/choose.c              |    8 -
 bench/composite.c           |    8 -
 bench/ifact.c               |    6 
 bench/meson.build           |   28 ++++
 bench/quit.bc               |    1 
 bench/rfact.c               |    6 
 box.c                       |    6 
 builtin-command.c           |    2 
 builtin-date.c              |    4 
 builtin-debug.c             |    2 
 builtin-environ.c           |   12 -
 builtin-file.c              |    4 
 builtin-foreign.c           |   18 +-
 builtin-math.c              |    2 
 builtin-pid.c               |   28 ++--
 builtin-semaphore.c         |    2 
 builtin-sockets.c           |    2 
 builtin-string.c            |    2 
 builtin-thread.c            |    2 
 builtin-toplevel.c          |    3 
 builtin.c                   |   36 +++--
 compile.c                   |   19 ++-
 configure.ac                |    4 
 debian/changelog            |    8 +
 debian/control              |    4 
 debian/docs                 |    1 
 debian/rules                |   16 +-
 debug.c                     |    4 
 doc/meson.build             |    6 
 doc/tutorial/meson.build    |   36 +++++
 doc/tutorial/tour/tour.adoc |    2 
 examples/meson.build        |   19 +++
 examples/smlng/meson.build  |   19 +++
 examples/smlng/test.5c      |    6 
 examples/turtle/meson.build |   18 ++
 execute.c                   |   18 +-
 file.c                      |   34 +++--
 float.c                     |   11 +
 foreign.c                   |    6 
 func.c                      |    5 
 gram.y                      |    4 
 hash.c                      |    4 
 int.c                       |   16 ++
 integer.c                   |   13 ++
 io.c                        |    2 
 lex.l                       |   13 +-
 main.c                      |   35 +++--
 mem.c                       |   18 +-
 mem.h                       |    8 -
 memp.h                      |    2 
 meson.build                 |  271 ++++++++++++++++++++++++++++++++++++++++++++
 meson_options.txt           |    8 +
 natural.c                   |    4 
 nickle.h                    |   17 ++
 pretty.c                    |    5 
 profile.c                   |    3 
 rational.c                  |   56 +++++----
 ref.c                       |   13 +-
 sched.c                     |   69 ++++++-----
 skiplist.5c                 |   39 +++---
 sort.5c                     |   36 ++++-
 string.c                    |    7 -
 struct.c                    |    4 
 symbol.c                    |    2 
 sync.c                      |    6 
 test/Makefile.am            |   14 --
 test/math-funcs.bc          |   70 +++++++++++
 test/math-tables.c          |  129 --------------------
 test/math-tables.sh         |  163 ++++++++++++++++++++++++++
 test/math.5c                |   67 ++++++----
 test/meson.build            |   45 +++++++
 test/sorttest.5c            |    7 -
 type.c                      |    6 
 union.c                     |    6 
 value.c                     |   77 +++++++-----
 value.h                     |   16 +-
 80 files changed, 1238 insertions(+), 477 deletions(-)

New commits:
commit 53feb84010f99071c1aac86a46e9dce57e1c12be
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Oct 28 15:11:47 2024 -0700

    Version 2.98
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/configure.ac b/configure.ac
index 9e727ff..80fa7ed 100644
--- a/configure.ac
+++ b/configure.ac
@@ -6,8 +6,8 @@ dnl for licensing information.
 
 AC_PREREQ([2.69])
 
-AC_INIT([nickle],[2.97],[http://nickle.org],[nickle])
-RELEASE_DATE="2024-01-13"
+AC_INIT([nickle],[2.98],[http://nickle.org],[nickle])
+RELEASE_DATE="2024-10-28"
 AC_CONFIG_SRCDIR([nickle.h])
 AC_CONFIG_HEADERS([nickle-config.h])
 AC_CONFIG_AUX_DIR(.)
diff --git a/debian/changelog b/debian/changelog
index 5523868..c1d9a92 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,11 @@
+nickle (2.98) unstable; urgency=medium
+
+  * Add gnomesort
+  * Switch to using bc to generate the math test vectors.
+  * Switch to meson
+
+ -- Keith Packard <keithp at keithp.com>  Mon, 28 Oct 2024 15:11:20 -0700
+
 nickle (2.97) unstable; urgency=medium
 
   * Install benchmark bits
diff --git a/meson.build b/meson.build
index 5cc7a09..1b3cc4c 100644
--- a/meson.build
+++ b/meson.build
@@ -12,10 +12,10 @@ project('nickle', 'c',
 	],
 	license : 'BSD',
 	meson_version : '>= 1.0',
-	version: '2.97'
+	version: '2.98'
        )
 
-release_date = '2024-01-13'
+release_date = '2024-10-28'
 
 prefix = get_option('prefix')
 include = prefix / get_option('includedir')
commit a0b57fe12bd5d25bad8d37cbb17b0642e33bcfc5
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Oct 28 22:27:17 2024 -0700

    debian: Switch to meson buildsystem
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/README.release b/README.release
index 1cf52dd..1ac82b8 100644
--- a/README.release
+++ b/README.release
@@ -29,4 +29,6 @@ important steps:
  9.	Push out changes to the repo
 		git-push origin master 2.<xx>
 
-10.	Upload release
\ No newline at end of file
+10.	Upload release
+		scp build/meson-dist/* nickle.org:/var/www/nickle/release
+		dput 
diff --git a/debian/control b/debian/control
index dc8b784..4dd9f16 100644
--- a/debian/control
+++ b/debian/control
@@ -4,7 +4,7 @@ Priority: optional
 Maintainer: Keith Packard <keithp at keithp.com>
 Homepage: https://nickle.org
 Build-Depends: debhelper-compat (= 13), libreadline-dev, ruby-asciidoctor-pdf,
- bison, flex, pkg-config, autoconf-archive, bc
+ bison, flex, meson, pkg-config, ninja-build, bc, libgmp-dev
 Rules-Requires-Root: no
 Standards-Version: 4.7.0
 
diff --git a/debian/docs b/debian/docs
index 82fcddb..50184fa 100644
--- a/debian/docs
+++ b/debian/docs
@@ -2,4 +2,3 @@ NEWS
 README
 README.name
 TODO
-doc/tutorial/nickle-tutorial.pdf
diff --git a/debian/rules b/debian/rules
index bfd6afb..7db08ac 100755
--- a/debian/rules
+++ b/debian/rules
@@ -12,22 +12,20 @@ export DEB_BUILD_MAINT_OPTIONS = hardening=+all
 export DH_VERBOSE=1
 
 %:
-	dh $@
+	dh $@ --buildsystem=meson
 
 override_dh_auto_configure:
-	CFLAGS_FOR_BUILD="$(CFLAGS)" LDFLAGS_FOR_BUILD="$(LDFLAGS)" dh_auto_configure
+	CFLAGS_FOR_BUILD="$(CFLAGS)" LDFLAGS_FOR_BUILD="$(LDFLAGS)" dh_auto_configure --buildsystem=meson
 
 # Don't install duplicate copyright info from COPYING files
 # Make examples which happen to start with #! executable
 
 override_dh_auto_install:
-	dh_auto_install && (find debian/nickle -name COPYING -print0 | xargs -0 rm)
+	dh_auto_install --buildsystem=meson && (find debian/nickle -name COPYING -print0 | xargs -0 rm)
 	find debian/nickle/usr/share/nickle -type f -print0 | xargs -0 grep -l '^#!.*nickle' | xargs -d '\n' chmod +x
 
+override_dh_update_autotools_config:
+	echo using meson
 
-# These files are generated. Makefile includes absolute paths which
-# makes it not work on end-user machines, and cause the build to be
-# not reproducible.
-
-override_dh_installdocs:
-	dh_installdocs -XMakefile -XMakefile.in
+override_dh_autoreconf:
+	echo using meson
commit 9d1f6696cfa880ce0136a1456d4d64acef9622ff
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Oct 28 15:10:48 2024 -0700

    debian: Add 'bc' build dependency
    
    We use bc to build the math test vectors.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/debian/control b/debian/control
index 96cb712..dc8b784 100644
--- a/debian/control
+++ b/debian/control
@@ -4,9 +4,9 @@ Priority: optional
 Maintainer: Keith Packard <keithp at keithp.com>
 Homepage: https://nickle.org
 Build-Depends: debhelper-compat (= 13), libreadline-dev, ruby-asciidoctor-pdf,
- bison, flex, pkg-config, autoconf-archive
+ bison, flex, pkg-config, autoconf-archive, bc
 Rules-Requires-Root: no
-Standards-Version: 4.6.2
+Standards-Version: 4.7.0
 
 Package: nickle
 Architecture: any
commit 2c86f60f1700f460b1845c7b56458463b87ab17c
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Oct 28 22:59:25 2024 -0700

    Update README.release
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/README.release b/README.release
index afd6550..1cf52dd 100644
--- a/README.release
+++ b/README.release
@@ -2,38 +2,31 @@ If you're going to package nickle for release, there are several
 important steps:
 
  1.	Create new version
- 		edit configure.in, changing the version number in the
-		AC_INIT line
+ 		edit meson.build, changing the version number in the
+		project() block
 		
- 2. 	rebuild the configuration files with autogen.sh
- 		sh autogen.sh --prefix=/usr --mandir=/usr/share/man
+ 2. 	run meson
+ 		meson setup build
 		
- 3.	make distcheck
+ 3.	Test the release
+		meson test -C build
  
  4.	Update debian/changelog
-
 		git log --pretty=oneline 2.<xx>..master
 		
- 5.	Build the release
-
-		make release-files
- 
- 6.	Commit these changes
-	
+ 5.	Commit these changes
 		git-commit -m'Update to version 2.<xx>' -a
 
- 7.	Tag
-
+ 6.	Tag
 		git-tag -s -m 'Version 2.<xx>' 2.<xx>
 
- 8.	Push out changes to the repo
+ 7.	Build the release
+		meson dist -C build
 
-		git-push origin master 2.<xx>
-
- 9.	Push out the release
+ 8.	Build debian builds
+		gbp buildpackage
 
-		make release
-
-10.	Push debian bits
+ 9.	Push out changes to the repo
+		git-push origin master 2.<xx>
 
-		dput nickle_2.<xx>-1_i386.changes
+10.	Upload release
\ No newline at end of file
commit 1b8059d38ae4d05e636f57c54756e9f4f5168ff4
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Oct 28 19:20:04 2024 -0700

    Add meson build files
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/bench/meson.build b/bench/meson.build
new file mode 100644
index 0000000..1d8b23a
--- /dev/null
+++ b/bench/meson.build
@@ -0,0 +1,28 @@
+#
+# Copyright © 1988-2024 Keith Packard and Bart Massey.
+# All Rights Reserved.  See the file COPYING in this directory
+# for licensing information.
+#
+
+benchmarks = ['choose', 'composite', 'ifact', 'rfact']
+
+gmp_dep = cc.find_library('gmp')
+
+bc = find_program('bc', required: false)
+
+foreach benchmark : benchmarks
+
+  benchmark('c-' + benchmark,
+	    executable('c-' + benchmark, benchmark + '.c',
+		       dependencies: gmp_dep))
+
+  if bc.found()
+    benchmark('bc-' + benchmark, bc,
+	      args: files([benchmark + '.bc', 'quit.bc']))
+  endif
+
+  benchmark('nickle-' + benchmark, nickle,
+	    args: files(benchmark + '.5c'),
+	    env: test_env)
+
+endforeach
diff --git a/bench/quit.bc b/bench/quit.bc
new file mode 100644
index 0000000..ff60466
--- /dev/null
+++ b/bench/quit.bc
@@ -0,0 +1 @@
+quit
diff --git a/doc/meson.build b/doc/meson.build
new file mode 100644
index 0000000..2789d0a
--- /dev/null
+++ b/doc/meson.build
@@ -0,0 +1,6 @@
+#
+# Copyright © 1988-2024 Keith Packard and Bart Massey.
+# All Rights Reserved.  See the file COPYING in this directory
+# for licensing information.
+#
+subdir('tutorial')
diff --git a/doc/tutorial/meson.build b/doc/tutorial/meson.build
new file mode 100644
index 0000000..139b889
--- /dev/null
+++ b/doc/tutorial/meson.build
@@ -0,0 +1,36 @@
+#
+# Copyright © 1988-2024 Keith Packard and Bart Massey.
+# All Rights Reserved.  See the file COPYING in this directory
+# for licensing information.
+#
+
+prog_asciidoctor = find_program('asciidoctor-pdf', required: false)
+
+adoc_files = [
+  'advanced/namespaces.adoc',
+  'advanced/continuations.adoc',
+  'advanced/copying.adoc',
+  'advanced/concurrency.adoc',
+  'advanced/exceptions.adoc',
+  'nickle-tutorial.adoc',
+  'builtins/math.adoc',
+  'builtins/strings.adoc',
+  'builtins/io.adoc',
+  'basics/command.adoc',
+  'basics/invoke.adoc',
+  'tour/tour.adoc',
+  'intro/functions.adoc',
+  'intro/variables.adoc',
+  'intro/statements.adoc',
+  'intro/expressions.adoc',
+]
+
+if prog_asciidoctor.found()
+  custom_target('nickle-tutorial',
+		input : 'nickle-tutorial.adoc',
+		output: 'nickle-tutorial.pdf',
+		command: [ prog_asciidoctor, '-o', '@OUTPUT@', '@INPUT@' ],
+		depend_files: files(adoc_files),
+		install: true,
+		install_dir: nickle_docdir)
+endif
diff --git a/examples/meson.build b/examples/meson.build
new file mode 100644
index 0000000..28c6106
--- /dev/null
+++ b/examples/meson.build
@@ -0,0 +1,19 @@
+#
+# Copyright © 1988-2024 Keith Packard and Bart Massey.
+# All Rights Reserved.  See the file COPYING in this directory
+# for licensing information.
+#
+
+examples = [
+  'comb.5c', 'cribbage.5c', 'erat.5c', 'fourfours.5c',
+  'initializer.5c', 'is-prime.5c', 'kaiser.5c', 'menace2.5c',
+  'miller-rabin.5c', 'mutextest.5c', 'numbers.5c', 'polynomial.5c',
+  'prime.5c', 'qbrating.5c', 'randtest.5c', 'restart.5c', 'roman.5c',
+  'rsa-demo.5c', 'rsa.5c', 'skiplisttest.5c', 'sudoku.5c'
+]
+
+install_data(examples + ['COPYING'],
+	     install_dir: nickle_examplesdir)
+
+subdir('smlng')
+subdir('turtle')
diff --git a/examples/smlng/meson.build b/examples/smlng/meson.build
new file mode 100644
index 0000000..602ffc4
--- /dev/null
+++ b/examples/smlng/meson.build
@@ -0,0 +1,19 @@
+#
+# SGML-like parser
+# Copyright © 2001 Keith Packard and Carl Worth
+#
+# All Rights Reserved.  See the file COPYING in this directory
+# for licensing information.
+#
+
+nickle_files = [ 'context.5c', 'generate.5c', 'parse.5c', 'test.5c' ]
+
+smlng_dir = nickle_examplesdir / 'smlng'
+
+install_data(nickle_files + ['COPYING', 'data.sgml'],
+	     install_dir: smlng_dir)
+
+test('smlng', nickle,
+     args: files(['test.5c', 'data.sgml']),
+     env: test_env,
+     timeout: 240)
diff --git a/examples/turtle/meson.build b/examples/turtle/meson.build
new file mode 100644
index 0000000..b1cc3d5
--- /dev/null
+++ b/examples/turtle/meson.build
@@ -0,0 +1,18 @@
+#
+# Draw "snowflake" fractal
+#
+# Copyright © 2001  Bart Massey.
+# All Rights Reserved.  See the file COPYING in this directory
+# for licensing information.
+nickle_files =[ 'snowflake.5c', 'turtle.5c']
+
+turtle_dir = nickle_examplesdir / 'turtle'
+
+install_data(nickle_files + ['snowflake.tex', 'COPYING'],
+	     install_dir: turtle_dir)
+
+test('snowflake', nickle,
+     args: files('snowflake.5c'),
+     timeout: 240,
+     env: test_env)
+
diff --git a/meson.build b/meson.build
new file mode 100644
index 0000000..5cc7a09
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,271 @@
+#
+# Copyright © 1988-2024 Keith Packard and Bart Massey.
+# All Rights Reserved.  See the file COPYING in this directory
+# for licensing information.
+#
+
+project('nickle', 'c',
+	default_options: [
+	  'buildtype=debugoptimized',
+	  'c_std=gnu18',
+	  'warning_level=2',
+	],
+	license : 'BSD',
+	meson_version : '>= 1.0',
+	version: '2.97'
+       )
+
+release_date = '2024-01-13'
+
+prefix = get_option('prefix')
+include = prefix / get_option('includedir')
+datadir = prefix / get_option('datadir')
+docdir = datadir / 'doc'
+
+nickle_libdir = datadir / 'nickle'
+nickle_includedir = include / 'nickle'
+nickle_docdir = docdir / 'nickle'
+nickle_examplesdir = nickle_libdir / 'examples'
+
+cc = meson.get_compiler('c')
+
+add_project_arguments(
+  '-DBUILD="@0@"'.format(release_date),
+  '-DBUILD_VERSION="@0@"'.format(meson.project_version()),
+  '-DLOCAL_BUILD',
+  '-DNICKLELIBDIR="@0@"'.format(nickle_libdir),
+  language : 'c'
+)
+
+add_project_arguments(cc.get_supported_arguments(
+  [
+    '-fno-strict-aliasing',
+    '-fwrapv',
+    '-Werror=vla',
+    '-Warray-bounds',
+    '-Werror=double-promotion',
+    '-Wno-missing-braces',
+    '-Wno-return-type',
+    '-Wno-unused-command-line-argument',
+    '-Wmissing-prototypes',
+    '-Wmissing-declarations',
+    '-Werror=implicit-fallthrough=5',
+    '-Werror=unreachable-code-fallthrough',
+    '-Werror=implicit-function-declaration',
+    '-Wold-style-definition',
+    '-Wno-implicit-int',
+    '-Wformat',
+    '-Wformat-security',
+    '-Wdate-time',
+    '-Wunused-parameter',
+    '-Wmissing-field-initializers',
+    '-Wsign-compare',
+    '-Wenum-conversion',
+    '-Wold-style-declaration',
+  ]),
+		      language: 'c')
+
+if get_option('libedit')
+  readline_dep = dependency('libedit')
+  readline_h = '<readline.h>'
+  history_h = ''
+else
+  readline_dep = dependency('readline', required: false)
+  readline_h = '<readline/readline.h>'
+  history_h = '<readline/history.h>'
+endif
+math_dep = cc.find_library('m', required : true)
+
+getpgrp_void = cc.compiles('''#include <unistd.h>
+int func() { return (int) getpgrp(); }
+''')
+
+have_dlclose = cc.has_function('dlclose')
+have_dlerror = cc.has_function('dlerror')
+have_dlfcn_h = cc.has_header('dlfcn.h')
+have_dlopen = cc.has_function('dlopen')
+have_dlsym = cc.has_function('dlsym')
+have_extern_syms = cc.has_link_argument('-Wl,-E')
+have_fcntl_h = cc.has_header('fcntl.h')
+have_getrlimit = cc.has_function('getrlimit')
+have_gettimeofday = cc.has_function('gettimeofday')
+have_putenv = cc.has_function('putenv')
+have_rl_catch_signals = cc.has_function('rl_catch_signals',
+				       prefix: '#include ' + readline_h,
+				       dependencies: readline_dep)
+
+have_rl_cleanup_after_signal = cc.has_function('rl_cleanup_after_signal',
+				       prefix: '#include ' + readline_h,
+				       dependencies: readline_dep)
+
+have_rl_echo_signal_char = cc.has_function('rl_echo_signal_char',
+				       prefix: '#include ' + readline_h,
+				       dependencies: readline_dep)
+
+have_rl_free_line_state = cc.has_function('rl_free_line_state',
+				       prefix: '#include ' + readline_h,
+				       dependencies: readline_dep)
+
+have_rl_reset_after_signal = cc.has_function('rl_reset_after_signal',
+				       prefix: '#include ' + readline_h,
+				       dependencies: readline_dep)
+have_setenv = cc.has_function('setenv')
+have_setrlimit = cc.has_function('setrlimit')
+have_sigaction = cc.has_function('sigaction')
+have_sigignore = cc.has_function('sigignore')
+have_significand = cc.has_function('significand',
+				   prefix: '#include <math.h>',
+				   dependencies: math_dep)
+have_sigrelse = cc.has_function('sigrelse')
+have_stdint_h = cc.has_header('stdint.h')
+have_stdint_h = cc.has_header('stdint.h')
+have_strings_h = cc.has_header('strings.h')
+have_string_h = cc.has_header ('string.h')
+have_stropts_h = cc.has_header('stropts.h')
+have_struct_tm_tm_gmtoff = cc.has_member('struct tm', 'tm_gmtoff',
+					 prefix: '#include <time.h>')
+have_struct_tm_tm_zone = cc.has_member('struct tm', 'tm_zone',
+					 prefix: '#include <time.h>')
+have_sys_resource_h = cc.has_header('sys/resource.h')
+have_sys_time_h = cc.has_header('sys/time.h')
+have_sys_types_h = cc.has_header('sys/types.h')
+have_time_h = cc.has_header('time.h')
+have_uint64_t = cc.has_type('uint64_t',
+			    prefix: '#include <stdint.h>')
+have_unistd_h = cc.has_header('unistd.h')
+have_unsetenv = cc.has_function('unsetenv')
+have_vfprintf = cc.has_function('vfprintf',
+				prefix: '#include <stdio.h>')
+sizeof_unsigned_int = cc.sizeof('unsigned int')
+sizeof_unsigned_long = cc.sizeof('unsigned long')
+sizeof_unsigned_long_long = cc.sizeof('unsigned long long')
+sizeof_unsigned_short = cc.sizeof('unsigned short')
+
+conf_data = configuration_data({
+				 'GETPGRP_VOID' : getpgrp_void,
+				 'HAVE_DLCLOSE' : have_dlclose,
+				 'HAVE_DLERROR' : have_dlerror,
+				 'HAVE_DLFCN_H' : have_dlfcn_h,
+				 'HAVE_DLOPEN' : have_dlopen,
+				 'HAVE_DLSYM' : have_dlsym,
+				 'HAVE_EXTERN_SYMS' : have_extern_syms,
+				 'HAVE_FCNTL_H' : have_fcntl_h,
+				 'HAVE_GETRLIMIT' : have_getrlimit,
+				 'HAVE_GETTIMEOFDAY' : have_gettimeofday,
+				 'HAVE_LIBREADLINE' : readline_dep.found(),
+				 'HAVE_PUTENV': have_putenv,
+				 'HAVE_RL_CATCH_SIGNALS': have_rl_catch_signals,
+				 'HAVE_RL_CLEANUP_AFTER_SIGNAL': have_rl_cleanup_after_signal,
+				 'HAVE_RL_ECHO_SIGNAL_CHAR': have_rl_echo_signal_char,
+				 'HAVE_RL_FREE_LINE_STATE': have_rl_free_line_state,
+				 'HAVE_RL_RESET_AFTER_SIGNAL': have_rl_reset_after_signal,
+				 'HAVE_SETENV': have_setenv,
+				 'HAVE_SETRLIMIT': have_setrlimit,
+				 'HAVE_SIGACTION': have_sigaction,
+				 'HAVE_SIGIGNORE': have_sigignore,
+				 'HAVE_SIGNIFICAND': have_significand,
+				 'HAVE_SIGRELSE': have_sigrelse,
+				 'HAVE_STDINT_H': have_stdint_h,
+				 'HAVE_STRINGS_H': have_strings_h,
+				 'HAVE_STRING_H': have_string_h,
+				 'HAVE_STROPTS_H': have_stropts_h,
+				 'HAVE_STRUCT_TM_TM_GMTOFF': have_struct_tm_tm_gmtoff,
+				 'HAVE_STRUCT_TM_TM_ZONE': have_struct_tm_tm_zone,
+				 'HAVE_SYS_RESOURCE_H': have_sys_resource_h,
+				 'HAVE_SYS_TIME_H': have_sys_time_h,
+				 'HAVE_SYS_TYPES_H': have_sys_types_h,
+				 'HAVE_TIME_H': have_time_h,
+				 'HAVE_UINT64_T': have_uint64_t,
+				 'HAVE_UNISTD_H': have_unistd_h,
+				 'HAVE_UNSETENV': have_unsetenv,
+				 'HAVE_VPRINTF': have_vfprintf,
+				 'PACKAGE_BUGREPORT': '"http://nickle.org"',
+				 'READLINE_H': readline_h,
+				 'SIZEOF_UNSIGNED_INT': sizeof_unsigned_int,
+				 'SIZEOF_UNSIGNED_LONG': sizeof_unsigned_long,
+				 'SIZEOF_UNSIGNED_LONG_LONG': sizeof_unsigned_long_long,
+				 'SIZEOF_UNSIGNED_SHORT': sizeof_unsigned_short,
+				 'VERSION': '"@0@"'.format(meson.project_version()),
+			       })
+
+if history_h != ''
+  conf_data.set('HISTORY_H', history_h)
+endif
+
+nickle_srcs = [
+  'alarm.c', 'array.c', 'atom.c', 'box.c', 'compile.c', 'debug.c',
+  'divide.c', 'edit.c', 'error.c', 'execute.c', 'expr.c', 'file.c',
+  'float.c', 'foreign.c', 'frame.c', 'func.c', 'gcd.c', 'hash.c',
+  'int.c', 'integer.c', 'io.c', 'main.c', 'mem.c', 'natural.c',
+  'pretty.c', 'profile.c', 'rational.c', 'ref.c', 'refer.c',
+  'sched.c', 'scope.c', 'stack.c', 'string.c', 'struct.c', 'symbol.c',
+  'sync.c', 'type.c', 'union.c', 'util.c', 'value.c', 'mem.h',
+  'memp.h', 'nickle.h', 'opcode.h', 'ref.h', 'stack.h', 'value.h',
+  'builtin-command.c', 'builtin-debug.c', 'builtin-environ.c',
+  'builtin-file.c', 'builtin-math.c', 'builtin-namespaces.h',
+  'builtin-semaphore.c', 'builtin-sockets.c', 'builtin-string.c',
+  'builtin-thread.c', 'builtin-toplevel.c', 'builtin-pid.c',
+  'builtin-date.c', 'builtin.c', 'builtin.h', 'builtin-foreign.c',
+]
+
+nickle_files = [
+  'builtin.5c', 'math.5c', 'scanf.5c', 'mutex.5c',
+  'arc4.5c', 'prng.5c', 'command.5c', 'abort.5c',
+  'printf.5c', 'history.5c', 'ctype.5c', 'string.5c', 'socket.5c',
+  'file.5c', 'parse-args.5c', 'svg.5c', 'process.5c',
+  'prime_sieve.5c', 'factorial.5c', 'gamma.5c', 'sort.5c', 'list.5c', 'skiplist.5c',
+  'json.5c', 'cha-cha.5c',
+]
+
+nickle_headers = [
+  'builtin.h', 'mem.h', 'nickle.h', 'ref.h', 'value.h',
+  'builtin-namespaces.h', 'memp.h', 'opcode.h', 'stack.h'
+]
+  
+nickle_start = files('builtin.5c')[0]
+
+prog_bison = find_program('bison', 'byacc', 'yacc', required : true)
+
+gram_ch = custom_target(
+  'gram.[ch]',
+  input : 'gram.y',
+  output : ['gram.c', 'gram.h'],
+  command : [  prog_bison, '-o', '@OUTPUT0@', '-d', '@INPUT@'],
+  install: true,
+  install_dir: [false, nickle_includedir])
+
+prog_flex = find_program('flex', 'lex', required : true)
+
+lex_c = custom_target(
+  'lex.c',
+  input : 'lex.l',
+  output : 'lex.c',
+  command : [prog_flex, '-o', '@OUTPUT@', '@INPUT@'])
+
+nickle_srcs += [gram_ch, lex_c]
+
+configure_file(output : 'nickle-config.h',
+	       configuration : conf_data,
+	       install_dir : nickle_includedir)
+
+install_headers(nickle_headers,
+		install_dir: nickle_includedir)
+
+install_data(nickle_files,
+	     install_dir: nickle_libdir)
+
+nickle = executable('nickle', nickle_srcs,
+		    dependencies : [ readline_dep, math_dep ],
+		    include_directories : include_directories('.'))
+
+test_env = environment(
+  {
+    'NICKLESTART': meson.current_source_dir() / 'builtin.5c',
+    'NICKLEPATH': meson.current_source_dir()
+  }
+  )
+
+subdir('test')
+subdir('examples')
+subdir('bench')
+subdir('doc')
diff --git a/meson_options.txt b/meson_options.txt
new file mode 100644
index 0000000..8c8fe94
--- /dev/null
+++ b/meson_options.txt
@@ -0,0 +1,8 @@
+#
+# Copyright © 1988-2024 Keith Packard and Bart Massey.
+# All Rights Reserved.  See the file COPYING in this directory
+# for licensing information.
+#
+
+option('libedit', type: 'boolean', value: false,
+       description: 'Use libedit instead of libreadline')
diff --git a/test/meson.build b/test/meson.build
new file mode 100644
index 0000000..b9ad998
--- /dev/null
+++ b/test/meson.build
@@ -0,0 +1,45 @@
+#
+# Copyright © 1988-2024 Keith Packard and Bart Massey.
+# All Rights Reserved.  See the file COPYING in this directory
+# for licensing information.
+#
+
+tests = [
+  'scanf.5c',
+  'gcdtest.5c',
+  'inttest.5c',
+  'optest.5c',
+  'orderofoptest.5c',
+  'rattest.5c',
+  'reftest.5c',
+  'arraytest.5c',
+  'modtest.5c',
+  'hashtest.5c',
+  'signal.5c',
+  'round.5c',
+  'math.5c',
+  'factorial.5c',
+  'is_type.5c',
+  'jsontest.5c',
+  'datetest.5c',
+  'string-file.5c',
+  'sorttest.5c',
+  'chacha_test.5c'
+]
+
+prog_math_tables = find_program('math-tables.sh', required: true)
+math_tables_dep = custom_target('math-tables.5c',
+				capture: true,
+				command: prog_math_tables,
+				output: 'math-tables.5c'
+			       )
+
+foreach test : tests
+  test(test, nickle,
+       args: files(test),
+       depends: math_tables_dep,
+       env: test_env,
+       workdir: meson.current_build_dir(),
+       timeout: 240
+      )
+endforeach
commit 2170904c8a65efa6d84a080d87f5cb1191ea0735
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Oct 28 21:02:31 2024 -0700

    bench: Clean up C compiler warnings
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/bench/choose.c b/bench/choose.c
index 782bc91..6246949 100644
--- a/bench/choose.c
+++ b/bench/choose.c
@@ -1,7 +1,7 @@
 #include <stdio.h>
 #include <gmp.h>
 
-void ifact(mpz_t res, mpz_t n) {
+static void ifact(mpz_t res, mpz_t n) {
   mpz_t count;
   mpz_init_set(count, n);
   mpz_set_si(res, 1);
@@ -12,7 +12,7 @@ void ifact(mpz_t res, mpz_t n) {
   mpz_clear(count);
 }
 
-void choose(mpz_t res, mpz_t n, mpz_t r) {
+static void choose(mpz_t res, mpz_t n, mpz_t r) {
   mpz_t ifr, ifnr, diff;
   mpz_init(ifr);
   mpz_init(ifnr);
@@ -28,7 +28,7 @@ void choose(mpz_t res, mpz_t n, mpz_t r) {
   mpz_clear(diff);
 }
 
-void do_choose(signed long int xa1, signed long int xa2) {
+static void do_choose(signed long int xa1, signed long int xa2) {
     mpz_t a1, a2, res;
 
     mpz_init_set_si(a1, xa1);
@@ -44,5 +44,5 @@ void do_choose(signed long int xa1, signed long int xa2) {
 
 int main(void) {
   do_choose(20000, 5000);
-  exit(0);
+  return 0;
 }
diff --git a/bench/composite.c b/bench/composite.c
index 44c7357..e5021e9 100644
--- a/bench/composite.c
+++ b/bench/composite.c
@@ -2,7 +2,7 @@
 #include <gmp.h>
 
 /* Miller-Rabin test from Corwin/Rivest/Leiserson */
-void witnessexp(mpz_t res, mpz_t b, mpz_t e, mpz_t m) {
+static void witnessexp(mpz_t res, mpz_t b, mpz_t e, mpz_t m) {
   mpz_t xres, tmp, rem, m1;
   if (mpz_cmp_si(e, 0) == 0) {
     mpz_set_si (res, -1);
@@ -57,7 +57,7 @@ void witnessexp(mpz_t res, mpz_t b, mpz_t e, mpz_t m) {
 /* Note that rather than trying random
    bases, we try _all_ bases[!]... */
 /* ([!] Don't even _think_ it.) */
-void composite(mpz_t res, mpz_t n) {
+static void composite(mpz_t res, mpz_t n) {
   mpz_t n1, j;
   mpz_init(n1);
   mpz_sub_ui(n1, n, 1);
@@ -82,7 +82,7 @@ void composite(mpz_t res, mpz_t n) {
   return;
 }
 
-void do_composite(signed long int xa) {
+static void do_composite(signed long int xa) {
     mpz_t a, res;
 
     mpz_init_set_si(a, xa);
@@ -96,5 +96,5 @@ void do_composite(signed long int xa) {
 
 int main(void) {
   do_composite(39157);
-  exit(0);
+  return 0;
 }
diff --git a/bench/ifact.c b/bench/ifact.c
index b0f2ff3..8376877 100644
--- a/bench/ifact.c
+++ b/bench/ifact.c
@@ -1,7 +1,7 @@
 #include <stdio.h>
 #include <gmp.h>
 
-void ifact(mpz_t res, mpz_t n) {
+static void ifact(mpz_t res, mpz_t n) {
   mpz_t count;
   mpz_init_set(count, n);
   mpz_set_si(res, 1);
@@ -12,7 +12,7 @@ void ifact(mpz_t res, mpz_t n) {
   mpz_clear(count);
 }
 
-void do_ifact(signed long int xa) {
+static void do_ifact(signed long int xa) {
     mpz_t a, res;
 
     mpz_init_set_si(a, xa);
@@ -26,5 +26,5 @@ void do_ifact(signed long int xa) {
 
 int main(void) {
   do_ifact(20000);
-  exit(0);
+  return 0;
 }
diff --git a/bench/rfact.c b/bench/rfact.c
index 8ae459b..42cfa68 100644
--- a/bench/rfact.c
+++ b/bench/rfact.c
@@ -1,7 +1,7 @@
 #include <stdio.h>
 #include <gmp.h>
 
-void rfact(mpz_t res, mpz_t n) {
+static void rfact(mpz_t res, mpz_t n) {
   mpz_t tmp;
   if (mpz_cmp_si(n, 0) <= 0) {
     mpz_set_si(res, 1);
@@ -14,7 +14,7 @@ void rfact(mpz_t res, mpz_t n) {
   mpz_mul(res, res, n);
 }
 
-void do_rfact(signed long int xa) {
+static void do_rfact(signed long int xa) {
     mpz_t a, res;
 
     mpz_init_set_si(a, xa);
@@ -28,5 +28,5 @@ void do_rfact(signed long int xa) {
 
 int main(void) {
   do_rfact(20000);
-  exit(0);
+  return 0;
 }
commit 971e56193dfef6f2ee1d3503d5890b786e426595
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Oct 28 15:55:35 2024 -0700

    test: Reduce sort testing
    
    Make testing go a bit faster by running 1/4 as many sort tests
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/test/sorttest.5c b/test/sorttest.5c
index 5aa5fb4..ea65857 100644
--- a/test/sorttest.5c
+++ b/test/sorttest.5c
@@ -26,8 +26,8 @@ void check(&real[] values, string sort)
 
 bool int_gt(int a, int b) = a > b;
 
-for (int i = 0; i < 100; i++) {
-    int len = randint(10000);
+for (int i = 0; i < 25; i++) {
+    int len = randint(1000);
     printf("test %d len %d\n", i, len);
     real[*] v = Sort::randomints(len, 1000000);
     real[*] qv = v;
commit f48b19967ba9da51fe48b365a9ac64db868b8e8c
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Oct 28 15:20:12 2024 -0700

    test: Increase math test precision to 70 digits
    
    The test vectors are generated using 'scale=100' in bc. Take advantage
    of that and check that the nickle results match to 70 digits.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/test/math.5c b/test/math.5c
index ed67de0..9b30768 100644
--- a/test/math.5c
+++ b/test/math.5c
@@ -6,8 +6,9 @@
 
 load "math-tables.5c"
 
-int test_precision = 64;
+int test_precision = 333;
 int errors = 0;
+real error_bound = 1e-70;
 
 real checked(real(real) f, real a) {
 	try {
@@ -30,7 +31,7 @@ real checked2(real(real, real) f, real a, real b) {
 		/* Just return the same value for large magnitudes
 		 * as small variations in input cause the sign to flip
 		 */
-		 
+
 		if (r > 1e10)
 			return 9999;
 		if (r < -1e10)
@@ -45,14 +46,14 @@ real checked2(real(real, real) f, real a, real b) {
 void check(string op, real(real) f, real input, real correct)
 {
 	real	value = checked(f, input);
-	
+
 	if (is_number (value))
 	{
 		real	error = abs (value - correct);
 
-		if (abs(correct) >= 1 && error < abs(correct) * 1e-8)
+		if (abs(correct) >= 1 && error < abs(correct) * error_bound)
 			return;
-		if (abs(correct) < 1 && error < 1e-8)
+		if (abs(correct) < 1 && error < error_bound)
 			return;
 		printf ("error %v value %v\n", error, value);
 	}
@@ -66,14 +67,14 @@ void check(string op, real(real) f, real input, real correct)
 void check2(string op, real(real, real) f, real input1, real input2, real correct)
 {
 	real	value = checked2(f, input1, input2);
-	
+
 	if (is_number (value))
 	{
 		real	error = abs (value - correct);
 
-		if (abs(correct) >= 1 && error < abs(correct) * 1e-10)
+		if (abs(correct) >= 1 && error < abs(correct) * error_bound)
 			return;
-		if (abs(correct) < 1 && error < 1e-10)
+		if (abs(correct) < 1 && error < error_bound)
 			return;
 		printf ("error %v value %v\n", error, value);
 	}
commit eca8f327cdef1ae4eb36bd4be0d5f24645c2be8a
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Oct 28 15:08:47 2024 -0700

    test: Make log precision checks faster
    
    Reduce the number of values used when testing log for internal
    consistency (log(x*y) == log(x) + log(y)).
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/test/math.5c b/test/math.5c
index 55c38d1..ed67de0 100644
--- a/test/math.5c
+++ b/test/math.5c
@@ -57,7 +57,7 @@ void check(string op, real(real) f, real input, real correct)
 		printf ("error %v value %v\n", error, value);
 	}
 	if (value != correct) {
-		printf ("check failed %s(%v) (was %.-g, should be %.-g)",
+		printf ("check failed %s(%v) (was %.-g, should be %.-g)\n",
 			op, input, value, correct);
 		errors++;
 	}
@@ -78,7 +78,7 @@ void check2(string op, real(real, real) f, real input1, real input2, real correc
 		printf ("error %v value %v\n", error, value);
 	}
 	if (value != correct) {
-		printf ("check failed %s(%.-g, %.-g) (was %.-g, should be %.-g)",
+		printf ("check failed %s(%.-g, %.-g) (was %.-g, should be %.-g)\n",
 			op, input1, input2, value, correct);
 		errors++;
 	}
@@ -86,6 +86,7 @@ void check2(string op, real(real, real) f, real input1, real input2, real correc
 
 void check_sin_cos()
 {
+	printf("Checking sin and cos\n");
 	for (int i = 0; i < dim(sin_cos_table); i++) {
 		real	angle = sin_cos_table[i].angle;
 		real	sin_value = sin_cos_table[i].sin;
@@ -93,6 +94,7 @@ void check_sin_cos()
 		check("sin", sin, angle, sin_value);
 		check("cos", cos, angle, cos_value);
 	}
+	printf("Checking asin and acos\n");
 	for (int i = 0; i < dim(asin_acos_table); i++) {
 		real	ratio = asin_acos_table[i].ratio;
 		real	asin_value = asin_acos_table[i].asin;
@@ -104,16 +106,19 @@ void check_sin_cos()
 
 void check_tan()
 {
+	printf("Checking tan\n");
 	for (int i = 0; i < dim(tan_table); i++) {
 		real angle = tan_table[i].angle;
 		real tan_value = tan_table[i].tan;
 		check("tan", tan, angle, tan_value);
 	}
+	printf("Checking atan\n");
 	for (int i = 0; i < dim(atan_table); i++) {
 		real ratio = atan_table[i].ratio;
 		real atan_value = atan_table[i].atan;
 		check("atan", atan, ratio, atan_value);
 	}
+	printf("Checking atan2\n");
 	for (int i = 0; i < dim(atan2_table); i++) {
 		real y = atan2_table[i].y;
 		real x = atan2_table[i].x;
@@ -147,21 +152,23 @@ string e_digits = ("2." +
 
 void check_e()
 {
-    File::sscanf(e_digits, "%f", &(real e_good));
-    for (int prec = 10; prec < 3000; prec *= 2) {
-	real e_tmp = Math::e_value(prec);
-	real error = abs (e_tmp - e_good);
-	/* prec-2 bits right of the decimal point */
-	real limit = 2**(-(prec-2));
-	if (error > limit) {
-	    printf("e_value(%d) error %g limit %g value %g\n", prec, error, limit, e_tmp);
-	    errors++;
+	printf("Checking e\n");
+	File::sscanf(e_digits, "%f", &(real e_good));
+	for (int prec = 10; prec < 3000; prec *= 2) {
+		real e_tmp = Math::e_value(prec);
+		real error = abs (e_tmp - e_good);
+		/* prec-2 bits right of the decimal point */
+		real limit = 2**(-(prec-2));
+		if (error > limit) {
+			printf("e_value(%d) error %g limit %g value %g\n", prec, error, limit, e_tmp);
+			errors++;
+		}
 	}
-    }
 }
 
 void check_exp()
 {
+	printf("Checking exp precision\n");
 	for (int prec = 10; prec <= 1000; prec *= 10) {
 		real eval = Math::e_value(1000);
 		for (int x = 0; x < 100; x++) {
@@ -204,14 +211,21 @@ void check_exp()
 			}
 		}
 	}
+	printf("Checking exp\n");
+	for (int i = 0; i < dim(exp_table); i++) {
+		real in = exp_table[i].in;
+		real exp_value = exp_table[i].exp;
+		check("exp", exp, in, exp_value);
+	}
 }
 
 void check_log()
 {
+	printf("Checking log precision\n");
 	int log_errors = 0;
 	for (int prec = 10; prec <= 1000; prec *= 10) {
 		real eval = Math::e_value(prec);
-		for (real x = imprecise(0.001, prec); x < 20; x *= 1.2) {
+		for (real x = imprecise(0.001, prec); x < 20; x *= 1.5) {
 			real	lnx = log(x);
 
 			real	explnx = exp(lnx);
@@ -225,7 +239,7 @@ void check_log()
 				errors++;
 			}
 
-			for (real y = imprecise(0.001, prec); y < 20; y *= 1.2) {
+			for (real y = imprecise(0.001, prec); y < 20; y *= 1.5) {
 				real	lny = log(y);
 
 				if (sign (lnx) != sign(lny))
@@ -242,7 +256,7 @@ void check_log()
 					printf("precision difference %d %d\n",
 					       plnxy, plnx_lny);
 
-				int	bitdiff = ceil(abs(log2(abs(lnx)) - log2(abs(lny))));
+				int	bitdiff = max(2, ceil(abs(log2(abs(lnx)) - log2(abs(lny)))));
 
 				real	limit = 2 ** -(prec - bitdiff - 5);
 
@@ -254,16 +268,12 @@ void check_log()
 			}
 		}
 	}
+	printf("Checking log\n");
 	for (int i = 0; i < dim(log_table); i++) {
 		real in = log_table[i].in;
 		real log_value = log_table[i].log;
 		check("log", log, in, log_value);
 	}
-	for (int i = 0; i < dim(exp_table); i++) {
-		real in = exp_table[i].in;
-		real exp_value = exp_table[i].exp;
-		check("exp", exp, in, exp_value);
-	}
 }
 
 check_sin_cos();
commit 2e56c7d5c0e4ef03f3e3db66368d4a1f00207b2f
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Oct 28 15:07:32 2024 -0700

    test: Replace C math test generator with bc generator
    
    This improves the available precision of the test vectors while
    eliminating variance in the installed test vector file from
    from math library or C compiler changes.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/test/Makefile.am b/test/Makefile.am
index f7ab8ae..598cfcb 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -32,17 +32,11 @@ TESTS_ENVIRONMENT=NICKLESTART=$(top_srcdir)/builtin.5c NICKLEPATH=$(top_srcdir)
 TESTS=$(check_SCRIPTS)
 LOG_COMPILER=$(top_builddir)/nickle
 
-EXTRA_DIST=$(check_SCRIPTS) math-tables.c
+EXTRA_DIST=$(check_SCRIPTS) math-tables.sh math-funcs.bc
 
 math.5c: $(TABLES)
 
-$(TABLES): math-tables$(BUILD_EXEEXT)
-	./math-tables$(BUILD_EXEEXT) > $(TABLES)
+$(TABLES): math-tables.sh math-funcs.bc
+	$(srcdir)/math-tables.sh > $(TABLES)
 
-math-tables$(BUILD_EXEEXT): math-tables.o
-	$(CC_FOR_BUILD) -o $@ $(CFLAGS_FOR_BUILD) $(LDFLAGS_FOR_BUILD) math-tables.o -lm
-
-math-tables.o: $(srcdir)/math-tables.c
-	$(CC_FOR_BUILD) -o $@ $(CPPFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD) -c $(srcdir)/math-tables.c
-
-CLEANFILES=$(TABLES) math-tables$(BUILD_EXEEXT) math-tables.o
+CLEANFILES=$(TABLES)
diff --git a/test/math-funcs.bc b/test/math-funcs.bc
new file mode 100644
index 0000000..0266853
--- /dev/null
+++ b/test/math-funcs.bc
@@ -0,0 +1,70 @@
+scale = 100
+
+p = 4*a(1)
+
+/* arcsin */
+define b(x) {
+	auto v;
+	if (x < -1.0 || x > 1.0)
+		return (10000);
+	if (x == -1)
+		return (-p/2);
+	if (x == 1)
+		return (p/2);
+	v = a(x / sqrt(1 - x * x));
+	if (v < -p/2) v += p;
+	return (v);
+}
+
+/* arccos */
+define d(x) {
+	auto v;
+	if (x < -1.0 || x > 1.0)
+		return (10000);
+	if (x == 0)
+		return(p/2);
+	if (x == -1)
+		return p;
+	v = a(sqrt(1 - x * x) / x);
+	if (v < 0) v += p;
+	return (v);
+}
+
+/* tan */
+define t(x) {
+	auto v, w, u;
+	v = s(x);
+	w = c(x);
+	u = w;
+	if (u < 0)
+		u = -u;
+	if (u < .1^20)
+		return (9999);
+	if (w == 0)
+		return (10000);
+	return (v / w);
+}
+
+/* atan2 */
+define u(y, x) {
+	auto w;
+	if (y == 0) {
+		if (x < 0)
+			return (p);
+		return 0;
+	}
+	if (x == 0) {
+		if (y < 0)
+			return (-p/2);
+		return (p/2);
+	}
+	w = a(y/x);
+	if (y < 0) {
+		if (x < 0)
+			w -= p;
+	} else {
+		if (x < 0)
+			w += p;
+	}
+	return (w);
+}
diff --git a/test/math-tables.c b/test/math-tables.c
deleted file mode 100644
index 129c989..0000000
--- a/test/math-tables.c
+++ /dev/null
@@ -1,129 +0,0 @@
-#include <math.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#define FMT	"%25.17f"
-
-double
-print_val(double x)
-{
-	if (isnan(x))
-		return 10000;
-	if (x > 1e10)
-		return 9999;
-	if (x < -1e10)
-		return 9999;
-	if (fabs(x) < 1e-20)
-		return 0;
-	return x;
-}
-
-static void
-sin_cos_table(void)
-{
-	double	a;
-	double	r;
-
-	printf ("/* %20.15f */\n", asin(-1));
-	printf ("typedef struct { real angle, sin, cos; } sin_cos_t;\n");
-	printf ("sin_cos_t[] sin_cos_table = {\n");
-	for (a = -800; a <= 800; a += 1) {
-		double a_f = a / 100;
-		printf ("\t{ .angle =     " FMT ", .sin = " FMT ", .cos = " FMT " },\n",
-			a_f, print_val(sin(a_f)), print_val(cos(a_f)));
-		printf ("\t{ .angle = π * " FMT ", .sin = " FMT ", .cos = " FMT " },\n",
-			a_f, print_val(sin(M_PI * a_f)), print_val(cos(M_PI * a_f)));
-	}
-	printf ("};\n");
-
-	printf ("typedef struct { real ratio, asin, acos; } asin_acos_t;\n");
-	printf ("asin_acos_t[] asin_acos_table = {\n");
-	for (r = -200; r <= 200; r += 1) {
-		double r_f = r / 100;
-		printf ("\t{ .ratio = " FMT ", .asin = " FMT ", .acos = " FMT " },\n",
-			r_f, print_val(asin(r_f)), print_val(acos(r_f)));
-	}
-	printf ("};\n");
-}
-
-static void
-tan_table(void)
-{
-	double	a;
-	double	r;
-	double	x, y;
-
-	printf ("typedef struct { real angle, tan; } tan_t;\n");
-	printf ("tan_t[] tan_table = {\n");
-	for (a = -800; a <= 800; a += 1) {
-		double a_f = a/100;
-		printf ("\t{ .angle =     " FMT ", .tan = " FMT " },\n",
-			a_f, print_val(tan(a_f)));
-		printf ("\t{ .angle = π * " FMT ", .tan = " FMT " },\n",
-			a_f, print_val(tan(M_PI * a_f)));
-	}
-	printf ("};\n");
-
-	printf ("typedef struct { real ratio, atan; } atan_t;\n");
-	printf ("atan_t[] atan_table = {\n");
-	for (r = -1000; r <= 1000; r += 1) {
-		double r_f = r / 10;
-		printf ("\t{ .ratio = " FMT ", .atan = " FMT " },\n",
-			r_f, print_val(atan(r_f)));
-	}
-	printf ("};\n");
-	
-	printf ("typedef struct { real y, x, atan2; } atan2_t;\n");
-	printf ("atan2_t[] atan2_table = {\n");
-	for (y = -30; y <= 30; y += 1) {
-		double y_f = y / 10;
-		for (x = -30; x <= 30; x += 1) {
-			double x_f = x/10;
-			double v;
-
-			/*
-			 * looks like glibc has a bug -- atan2(0,0) returns
-			 * π/4 instead of 0
-			 */
-			if (y_f == 0 && x_f == 0)
-				v = 0;
-			else
-				v = atan2(y_f,x_f);
-
-			printf ("\t{ .y = " FMT ", .x = " FMT ", .atan2 = " FMT " },\n",
-				y_f, x_f, print_val(v));
-		}
-	}
-	printf ("};\n");
-}
-
-void
-log_table(void)
-{
-	double	v;
-	printf ("typedef struct { real in, log; } log_t;\n");
-	printf ("log_t[] log_table = {\n");
-	for (v = 1; v < 1e20; v *= 2) {
-		double v_f = v/1e6;
-		printf("\t{ .in = " FMT ", .log = " FMT " },\n",
-		       v_f, log(v_f));
-	}
-	printf ("};\n");
-	printf ("typedef struct { real in, exp; } exp_t;\n");
-	printf ("exp_t[] exp_table = {\n");
-	for (v = -1000; v < 1000; v += 1) {
-		double v_f = v/100;
-		printf("\t{ .in = " FMT ", .exp = " FMT " },\n",
-		       v_f, exp(v_f));
-	}
-	printf ("};\n");
-}
-
-int
-main(int argc, char **argv)
-{
-	sin_cos_table();
-	tan_table();
-	log_table();
-	exit(0);
-}
diff --git a/test/math-tables.sh b/test/math-tables.sh
new file mode 100755
index 0000000..cfc60a4
--- /dev/null
+++ b/test/math-tables.sh
@@ -0,0 +1,163 @@
+#!/bin/sh
+
+dir=`dirname $0`
+
+# Which tables to generate
+
+make_sin=y
+make_asin=y
+make_tan=y
+make_atan=y
+make_log=y
+make_exp=y
+
+if [ $# -gt 0 ]; then
+    make_sin=n
+    make_asin=n
+    make_tan=n
+    make_atan=n
+    make_log=n
+    make_exp=n
+    for i in "$@"; do
+	case "$i" in
+	    sin)
+		make_sin=y
+		;;
+	    asin)
+		make_asin=y
+		;;
+	    tan)
+		make_tan=y
+		;;
+	    atan)
+		make_atan=y
+		;;
+	    log)
+		make_log=y
+		;;
+	    exp)
+		make_exp=y
+		;;
+	esac
+    done
+fi
+
+# sine and cosine table
+
+inc=1
+ainc=1
+
+echo "typedef struct { real angle, sin, cos; } sin_cos_t;"
+echo "sin_cos_t[] sin_cos_table = {"
+
+a="-800"
+while [ "$a" -le "800" -a $make_sin = "y" ]; do
+    sin=`echo "s($a / 100)" | bc -l "$dir"/math-funcs.bc | fmt --width=500 | tr -d '\\\n ' `
+    cos=`echo "c($a / 100)" | bc -l "$dir"/math-funcs.bc | fmt --width=500 | tr -d '\\\n ' `
+    psin=`echo "s(p * $a / 100)" | bc -l "$dir"/math-funcs.bc | fmt --width=500 | tr -d '\\\n ' `
+    pcos=`echo "c(p * $a / 100)" | bc -l "$dir"/math-funcs.bc | fmt --width=500 | tr -d '\\\n ' `
+    echo "    { .angle = $a / 100.0,"
+    echo "      .sin = $sin,"
+    echo "      .cos = $cos },"
+    echo "    { .angle = π * $a / 100.0,"
+    echo "      .sin = $psin,"
+    echo "      .cos = $pcos },"
+    a=`expr "$a" + "$inc"`
+done
+
+echo "};"
+
+# arcsine and arccosine table
+
+echo "typedef struct { real ratio, asin, acos; } asin_acos_t;"
+echo "asin_acos_t[] asin_acos_table = {"
+
+r="-200"
+while [ "$r" -le 200 -a $make_asin = "y" ]; do
+    asin=`echo "b($r / 100)" | bc -l "$dir"/math-funcs.bc | fmt --width=500 | tr -d '\\\n ' `
+    acos=`echo "d($r / 100)" | bc -l "$dir"/math-funcs.bc | fmt --width=500 | tr -d '\\\n ' `
+    echo "    { .ratio = $r / 100,"
+    echo "      .asin = $asin,"
+    echo "      .acos = $acos },"
+    r=`expr "$r" + "$inc"`
+done
+
+echo "};"
+
+# tangent table
+
+echo "typedef struct { real angle, tan; } tan_t;"
+echo "tan_t[] tan_table = {"
+
+a="-800"
+while [ "$a" -le 800 -a $make_tan = "y" ]; do
+    tan=`echo "t($a / 100)" | bc -l "$dir"/math-funcs.bc | fmt --width=500 | tr -d '\\\n ' `
+    ptan=`echo "t(p * $a / 100)" | bc -l "$dir"/math-funcs.bc | fmt --width=500 | tr -d '\\\n ' `
+    echo "    { .angle = $a / 100.0,"
+    echo "      .tan = $tan },"
+    echo "    { .angle = π * $a / 100.0,"
+    echo "      .tan = $ptan },"
+    a=`expr "$a" + "$inc"`
+done
+echo "};"
+
+# arctangent table
+
+echo "typedef struct { real ratio, atan; } atan_t;"
+echo "atan_t[] atan_table = {"
+
+r="-1000"
+while [ "$r" -le 1000 -a $make_atan = "y" ]; do
+    atan=`echo "a($r / 100)" | bc -l "$dir"/math-funcs.bc | fmt --width=500 | tr -d '\\\n ' `
+    echo "    { .ratio = $r / 100,"
+    echo "      .atan = $atan },"
+    r=`expr "$r" + "$inc"`
+done
+echo "};"
+
+# arctangent(y/x) table
+
+echo "typedef struct { real y, x, atan2; } atan2_t;"
+echo "atan2_t[] atan2_table = {"
+
+y="-30"
+while [ "$y" -le 30 -a "$make_atan" = "y" ]; do
+      x="-30"
+      while [ "$x" -le 30 ]; do
+	  x=`expr "$x" + "$ainc"`
+	  atan2=`echo "u($y / 100, $x / 100)" | bc -l "$dir"/math-funcs.bc | fmt --width=500 | tr -d '\\\n ' `
+	  echo "    { .y = $y / 100.0, .x = $x / 100.0,"
+	  echo "      .atan2 = $atan2 },"
+      done
+      y=`expr "$y" + "$ainc"`
+done
+echo "};"
+
+# log table
+
+echo "typedef struct { real in, log; } log_t;"
+echo "log_t[] log_table = {"
+
+r="0"
+while [ "$r" -le 66 -a "$make_log" = "y" ]; do
+    in=`echo "2 ^ $r" | bc`
+    log=`echo "l($in / 1000000)" | bc -l "$dir"/math-funcs.bc | fmt --width=500 | tr -d '\\\n ' `
+    echo "    { .in = $in / 1000000.0,"
+    echo "      .log = $log },"
+    r=`expr "$r" + "$ainc"`
+done
+echo "};"
+
+# exp table
+
+echo "typedef struct { real in, exp; } exp_t;"
+echo "exp_t[] exp_table = {"
+
+r="-1000"
+while [ "$r" -le 1000 -a $make_exp = "y" ]; do
+    exp=`echo "e($r / 100)" | bc -l "$dir"/math-funcs.bc | fmt --width=500 | tr -d '\\\n ' `
+    echo "    { .in = $r / 100.0,"
+    echo "      .exp = $exp },"
+    r=`expr "$r" + "$inc"`
+done
+echo "};"
commit 9fd6483fa0ae0fa43398a7979c924b80e1dc37a3
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Oct 28 22:27:45 2024 -0700

    examples/smlng: Allow input to be specified on command line
    
    Don't require use of stdin
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/examples/smlng/test.5c b/examples/smlng/test.5c
index fc61c5d..8fb9361 100644
--- a/examples/smlng/test.5c
+++ b/examples/smlng/test.5c
@@ -6,5 +6,9 @@
 
 library "parse.5c"
 
-*Parse::element e = Parse::get(stdin);
+file f = stdin;
+if (dim(argv) > 0)
+    f = File::open(argv[1], "r");
+
+*Parse::element e = Parse::get(f);
 Parse::dump(e);
commit 8491338ac48b51304fed3622f6d2b521d7f981e5
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Oct 28 21:04:59 2024 -0700

    doc: Add missing trailing newline
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/doc/tutorial/tour/tour.adoc b/doc/tutorial/tour/tour.adoc
index 3ea191c..66743d4 100644
--- a/doc/tutorial/tour/tour.adoc
+++ b/doc/tutorial/tour/tour.adoc
@@ -135,4 +135,4 @@ public void handprint (int[*] hand)
 hand { 7 8 Q 10 5 }  has 6 points.
 > quit
 $
-----
\ No newline at end of file
+----
commit 12a2868cddb26afd6f56484a83e21a2f212a9532
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Oct 28 21:05:42 2024 -0700

    skiplist.5c: Expose 'List' type
    
    List is just an alias for Skip
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/skiplist.5c b/skiplist.5c
index 459c948..af966b9 100644
--- a/skiplist.5c
+++ b/skiplist.5c
@@ -10,9 +10,9 @@ namespace Skiplist {
     public typedef bool (poly a, poly b) Greater;
 
     public typedef void (poly a) Visit;
-    
+
     public exception not_found (poly missing);
-    
+
     /*
      * Private representation of an element
      */
@@ -45,7 +45,7 @@ namespace Skiplist {
     {
 	int bits = PRNG::randbits(MaxLevel * 2);
 	int level = 0;
-	
+
 	while (++level < MaxLevel)
 	{
 	    if ((bits & 3) != 0)
@@ -54,7 +54,7 @@ namespace Skiplist {
 	}
 	return level;
     }
-    
+
     public Skip new (Greater greater)
 	/*
 	 * Allocate a new list with 'greater' as the ordering function
@@ -63,9 +63,9 @@ namespace Skiplist {
 	return &(SkipRec) {
 	    .level = 0,
 	    .greater = greater,
-	    .header = { 
+	    .header = {
 		.forward = (ElementPtr[MaxLevel]) { [i] = ElementPtr.nil },
-		.value = <> 
+		.value = <>
 	    }
 	};
     }
@@ -81,7 +81,7 @@ namespace Skiplist {
 	for (int i = list->level; --i >= 0; )
 	{
 	    while (x.element->forward[i] != ElementPtr.nil &&
-		   list->greater (value, 
+		   list->greater (value,
 				  x.element->forward[i].element->value))
 		x = x.element->forward[i];
 	}
@@ -101,8 +101,8 @@ namespace Skiplist {
 
 	for (int i = list->level; --i >= 0;)
 	{
-	    while (x.element->forward[i] != ElementPtr.nil && 
-		   list->greater (value, 
+	    while (x.element->forward[i] != ElementPtr.nil &&
+		   list->greater (value,
 				  x.element->forward[i].element->value))
 		x = x.element->forward[i];
 	    update[i] = x;
@@ -123,7 +123,7 @@ namespace Skiplist {
 	    .value = value,
 	    .forward = (ElementPtr[level]) {}
 	};
-	
+
 	for (int i = 0; i < level; i++)
 	{
 	    new.element->forward[i] = update[i].element->forward[i];
@@ -142,8 +142,8 @@ namespace Skiplist {
 
 	for (int i = list->level; --i >= 0;)
 	{
-	    while (x.element->forward[i] != ElementPtr.nil && 
-		   list->greater (value, 
+	    while (x.element->forward[i] != ElementPtr.nil &&
+		   list->greater (value,
 				  x.element->forward[i].element->value))
 		x = x.element->forward[i];
 	    update[i] = x;
@@ -152,13 +152,13 @@ namespace Skiplist {
 	if (x == ElementPtr.nil || list->greater (x.element->value, value))
 	    raise not_found (value);
 
-	for (int i = 0; 
-	     i < list->level && update[i].element->forward[i] == x; 
+	for (int i = 0;
+	     i < list->level && update[i].element->forward[i] == x;
 	     i++)
 	{
 	    update[i].element->forward[i] = x.element->forward[i];
 	}
-	
+
 	while (list->level > 0 &&
 	       list->header.forward[list->level-1] == ElementPtr.nil)
 	    list->level--;
@@ -167,7 +167,7 @@ namespace Skiplist {
     public void walk (Skip list, Visit visit)
 	/*
 	 * Invoke 'visit' for each element of 'list'.
-	 * Operations on 
+	 * Operations on
 	 */
     {
 	for (ElementPtr e = list->header.forward[0];
@@ -201,7 +201,7 @@ namespace Skiplist {
 	     e != ElementPtr.nil;
 	     e = e.element->forward[0])
 	{
-	    len++;	     
+	    len++;
 	}
 	return len;
     }
@@ -212,8 +212,8 @@ namespace Skiplist {
 
 	for (int i = list->level; --i >= 0;)
 	{
-	    while (x.element->forward[i] != ElementPtr.nil && 
-		   list->greater (value, 
+	    while (x.element->forward[i] != ElementPtr.nil &&
+		   list->greater (value,
 				  x.element->forward[i].element->value))
 		x = x.element->forward[i];
 	}
@@ -226,4 +226,5 @@ namespace Skiplist {
 
 namespace Sortlist {
     public import Skiplist;
+    public typedef Skip List;
 }
commit ab06132d530f49eb2d3e87b405e6eaa791ab22ba
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Oct 28 22:47:03 2024 -0700

    Fixup signed/unsigned compares
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/box.c b/box.c
index 2d58edd..4d5fb00 100644
--- a/box.c
+++ b/box.c
@@ -11,7 +11,7 @@ BoxMark (void *object)
 {
     BoxPtr	box = object;
     Value	*elements;
-    int		i;
+    unsigned long	i;
 
     elements = BoxElements(box);
     if (box->replace)
@@ -110,7 +110,7 @@ BoxRewrite (BoxPtr box, int *ep)
      * was resized.  But, that's "hard".  This check will
      * at least prevent a seg fault.
      */
-    if (e >= box->nvalues)
+    if (e >= 0 && (unsigned long) e >= box->nvalues)
     {
 	RaiseStandardException (exception_invalid_array_bounds, 2,
 				Void, NewInt (e));
diff --git a/builtin-file.c b/builtin-file.c
index 577c1d7..41858fd 100644
--- a/builtin-file.c
+++ b/builtin-file.c
@@ -210,7 +210,7 @@ import_File_namespace(void)
 	    "\n"
 	    " Raised when reading at end-of-file.\n"
 	    " 'file' is the file at eof.\n" },
-	{0,			0 },
+	{0, 0, 0, 0 },
     };
 
     const struct ebuiltin   *e;
diff --git a/builtin-pid.c b/builtin-pid.c
index 066e21d..3adc76b 100644
--- a/builtin-pid.c
+++ b/builtin-pid.c
@@ -91,10 +91,10 @@ do_PID_setuid (Value uid)
     int u = IntPart (uid, "Invalid uid");
     if (aborting)
 	RETURN(Void);
-    
+
     if (setuid (u) < 0)
 	RETURN (error (uid));
-	
+
     RETURN (Void);
 }
 
@@ -105,10 +105,10 @@ do_PID_seteuid (Value euid)
     int u = IntPart (euid, "Invalid euid");
     if (aborting)
 	RETURN(Void);
-    
+
     if (seteuid (u) < 0)
 	RETURN (error (euid));
-	
+
     RETURN (Void);
 }
 
@@ -119,10 +119,10 @@ do_PID_setgid (Value gid)
     int u = IntPart (gid, "Invalid gid");
     if (aborting)
 	RETURN(Void);
-    
+
     if (setgid (u) < 0)
 	RETURN (error (gid));
-	
+
     RETURN (Void);
 }
 
@@ -133,10 +133,10 @@ do_PID_setegid (Value egid)
     int u = IntPart (egid, "Invalid egid");
     if (aborting)
 	RETURN(Void);
-    
+
     if (setegid (u) < 0)
 	RETURN (error (egid));
-	
+
     RETURN (Void);
 }
 
@@ -155,10 +155,10 @@ do_PID_setgroups (Value groups)
 	if (aborting)
 	    RETURN(Void);
     }
-    
+
     if (setgroups (n, g) < 0)
 	RETURN (error (groups));
-	
+
     RETURN (Void);
 }
 
@@ -226,12 +226,12 @@ import_PID_namespace (void)
 	    " 'message' is a printable error string.\n"
 	    " 'error' is a symbolic error code.\n"
 	    " 'value' is the value which failed.\n" },
-	{ 0, 0 },
+	{ 0, 0, 0, 0 },
     };
     const struct ebuiltin   *e;
-	
+
     PIDNamespace = BuiltinNamespace (/*parent*/ 0, "PID")->namespace.namespace;
-    
+
     for (e = excepts; e->name; e++)
 	BuiltinAddException (&PIDNamespace, e->exception, e->name, e->args, e->doc);
 
@@ -239,5 +239,3 @@ import_PID_namespace (void)
     BuiltinFuncs1 (&PIDNamespace, funcs_1);
     EXIT ();
 }
-
-    
diff --git a/builtin.c b/builtin.c
index 5ced1d9..aae62d9 100644
--- a/builtin.c
+++ b/builtin.c
@@ -13,21 +13,21 @@
 #include	"builtin.h"
 
 static const struct sbuiltin svars[] = {
-    { "> ",	    "prompt" },
-    { "+ ",	    "prompt2" },
-    { "- ",	    "prompt3" },
-    { "%g",	    "format" },
+    { "> ",	    "prompt", 0 },
+    { "+ ",	    "prompt2", 0  },
+    { "- ",	    "prompt3", 0  },
+    { "%g",	    "format", 0  },
 #ifdef BUILD_VERSION
-    { BUILD_VERSION, "version" },
+    { BUILD_VERSION, "version", 0  },
 #else
-    { VERSION, "version" },
+    { VERSION, "version", 0  },
 #endif
 #ifdef BUILD
-    { BUILD,	    "build" },
+    { BUILD,	    "build", 0  },
 #else
-    { "?",	    "build" },
+    { "?",	    "build", 0  },
 #endif
-    { 0,    0 },
+    { 0, 0, 0 },
 };
 
 extern NamespacePtr CommandNamespace;
@@ -39,19 +39,19 @@ static const struct envbuiltin envvars[] = {
 #else
     { NICKLELIBDIR,	"nickle_libdir",	&CommandNamespace },
 #endif
-    { 0,    0 },
+    { 0, 0, 0 },
 };
 
 static const struct filebuiltin fvars[] = {
-    { "stdin",	&FileStdinBox },
-    { "stdout",	&FileStdoutBox },
-    { "stderr",	&FileStderrBox },
-    { 0,	0 },
+    { "stdin",	&FileStdinBox, 0  },
+    { "stdout",	&FileStdoutBox, 0  },
+    { "stderr",	&FileStderrBox, 0  },
+    { 0, 0, 0  },
 };
 
 static const struct ibuiltin ivars[] = {
     { DEFAULT_FLOAT_PREC, "float_precision", &GlobalNamespace },
-    { 0,    0 },
+    { 0, 0, 0 },
 };
 
 static const struct ebuiltin excepts[] = {
@@ -94,7 +94,7 @@ static const struct ebuiltin excepts[] = {
 	"\n"
 	" 'value' isn't compatible with a unary operator.\n"
 	" 'message' indicates which operator is problematic.\n" },
-    {0,				0 },
+    {0, 0, 0, 0 },
 };
 
 SymbolPtr
diff --git a/debug.c b/debug.c
index f1bd87a..a6eff16 100644
--- a/debug.c
+++ b/debug.c
@@ -55,7 +55,7 @@ static const struct {
 static void
 DebugAddCommands (void)
 {
-    int	i;
+    size_t	i;
     for (i = 0; i < NUM_DEBUG_COMMANDS; i++)
 	DebugAddCommand (debugCommands[i].function, debugCommands[i].names);
 }
@@ -63,7 +63,7 @@ DebugAddCommands (void)
 static void
 DebugDeleteCommands (void)
 {
-    int	i;
+    size_t	i;
     for (i = 0; i < NUM_DEBUG_COMMANDS; i++)
 	DebugDeleteCommand (debugCommands[i].function);
 }
diff --git a/execute.c b/execute.c
index 1b7c5e2..a074726 100644
--- a/execute.c
+++ b/execute.c
@@ -276,7 +276,7 @@ ThreadAssign (Value ref, Value v, Bool initialize)
 	RaiseStandardException (exception_invalid_binop_values, 2, ref, v);
     else if (RefConstant(ref) && !initialize)
 	RaiseStandardException (exception_readonly_box, 1, v);
-    else if (ref->ref.element >= ref->ref.box->nvalues)
+    else if (ref->ref.element < 0 || (unsigned long) ref->ref.element >= ref->ref.box->nvalues)
 	RaiseStandardException (exception_invalid_array_bounds, 2,
 				NewInt(ref->ref.element), v);
     else if (!TypeCompatibleAssign (RefType (ref), v))
diff --git a/file.c b/file.c
index a1b87f9..7341263 100644
--- a/file.c
+++ b/file.c
@@ -431,7 +431,7 @@ FileInitErrors (void)
     ENTER ();
     StructType	    *st;
     Atom	    *atoms;
-    int		    i;
+    size_t	    i;
     SymbolPtr	    error_type;
 
     error_type = NewSymbolType (AtomId("error_type"), 0);
@@ -516,7 +516,7 @@ FileGetError (int err)
 {
     ENTER();
     Value	    ret;
-    int		    i;
+    size_t	    i;
     StructType	    *st;
 
     for (i = 0; i < NUM_FILE_ERRORS; i++)
@@ -534,7 +534,7 @@ FileGetError (int err)
 Value
 FileGetErrorMessage (int err)
 {
-    int i;
+    size_t i;
     for (i = 0; i < NUM_FILE_ERRORS; i++)
 	if (fileErrorMap[i].value == err)
 	    return NewStrString (fileErrorMap[i].message);
@@ -600,6 +600,8 @@ ValueRep FileRep = {
     0,
     0,
     FilePrint,
+    0,
+    0,
 };
 
 Value
@@ -2057,17 +2059,17 @@ FileSetBuffer (Value file, int mode)
  */
 
 int
-FileOutchar (Value file, int c)
+FileOutchar (Value file, uint32_t c)
 {
     char d;
     int	bits;
     
-         if (c <       0x80) { d = c;                         bits= -6; }
-    else if (c <      0x800) { d= ((c >>  6) & 0x1F) | 0xC0;  bits=  0; }
-    else if (c <    0x10000) { d= ((c >> 12) & 0x0F) | 0xE0;  bits=  6; }
-    else if (c <   0x200000) { d= ((c >> 18) & 0x07) | 0xF0;  bits= 12; }
-    else if (c <  0x4000000) { d= ((c >> 24) & 0x03) | 0xF8;  bits= 18; }
-    else if (c < 0x80000000) { d= ((c >> 30) & 0x01) | 0xFC;  bits= 24; }
+         if (c <       0x80UL) { d = c;                         bits= -6; }
+    else if (c <      0x800UL) { d= ((c >>  6) & 0x1F) | 0xC0;  bits=  0; }
+    else if (c <    0x10000UL) { d= ((c >> 12) & 0x0F) | 0xE0;  bits=  6; }
+    else if (c <   0x200000UL) { d= ((c >> 18) & 0x07) | 0xF0;  bits= 12; }
+    else if (c <  0x4000000UL) { d= ((c >> 24) & 0x03) | 0xF8;  bits= 18; }
+    else if (c < 0x80000000UL) { d= ((c >> 30) & 0x01) | 0xFC;  bits= 24; }
     else return FileError;
 
     if (FileOutput (file, d) < 0)
@@ -2132,7 +2134,7 @@ FileInchar (Value file)
 }
 
 void
-FileUnchar (Value file, int c)
+FileUnchar (Value file, uint32_t c)
 {
     char d;
     int	bits;
diff --git a/float.c b/float.c
index c9d2ae3..82be9f7 100644
--- a/float.c
+++ b/float.c
@@ -275,7 +275,7 @@ FloatAdd (Value av, Value bv, int expandOk, Bool negate)
     Fpart	*exp;
     int		d;
     unsigned	prec;
-    int		alen, blen;
+    unsigned	alen, blen;
 
     if (FpartZero(a->mant)) {
 	if (negate)
diff --git a/func.c b/func.c
index e89c527..c47c816 100644
--- a/func.c
+++ b/func.c
@@ -156,6 +156,7 @@ ValueRep   FuncRep = {
     0,
     FuncPrint,
     0,
+    0,
 };
 
 Value
diff --git a/mem.c b/mem.c
index 91eeb3b..eefa154 100644
--- a/mem.c
+++ b/mem.c
@@ -53,10 +53,10 @@ int		    useMap[NUMSIZES+1];
  */
 
 static struct block *
-newBlock (int sizeIndex)
+newBlock (size_t sizeIndex)
 {
     struct block    *b;
-    int		    size;
+    size_t	    size;
     
     if (sizeIndex < NUMSIZES)
 	size = BLOCKSIZE;
@@ -90,7 +90,7 @@ newBlock (int sizeIndex)
  */
 
 struct bfree *
-MemAllocateHunk (int sizeIndex)
+MemAllocateHunk (size_t sizeIndex)
 {
     struct block	*b;
     struct bfree    	*new;
@@ -121,7 +121,7 @@ MemAllocateHunk (int sizeIndex)
 }
 
 void *
-MemAllocate (DataType *type, int size)
+MemAllocate (DataType *type, size_t size)
 {
     int	sizeIndex = 0;
     struct bfree    *new;
@@ -157,7 +157,7 @@ MemAllocate (DataType *type, int size)
 }
 
 void *
-MemAllocateRef (DataType *type, int size)
+MemAllocateRef (DataType *type, size_t size)
 {
     struct bfree    *new = MemAllocate (type, size);
 
@@ -172,7 +172,7 @@ MemAllocateRef (DataType *type, int size)
  */
 
 struct bfree *
-MemAllocateHuge (int size)
+MemAllocateHuge (size_t size)
 {
     return (struct bfree *) HUNKS (newBlock (size));
 }
@@ -368,9 +368,9 @@ sweep (void)
      */
     for (p = &head; (b = *p); )
     {
-	int		sizeIndex = b->sizeIndex;
-	int		n = NUMHUNK_ALL(sizeIndex);
-	int		size = HUNKSIZE_ALL(sizeIndex);
+	size_t		sizeIndex = b->sizeIndex;
+	size_t		n = NUMHUNK_ALL(sizeIndex);
+	size_t		size = HUNKSIZE_ALL(sizeIndex);
 	unsigned char   *data = HUNKS(b);
 	struct bfree    *first = 0;
 	struct bfree    **prev = &first;
diff --git a/mem.h b/mem.h
index 9445580..06cd728 100644
--- a/mem.h
+++ b/mem.h
@@ -67,16 +67,16 @@ union block_round {
 # define HUNKS(b)	((unsigned char *) (b) + HEADSIZE)
 
 struct bfree *
-MemAllocateHunk (int sizeIndex);
+MemAllocateHunk (size_t sizeIndex);
 
 struct bfree *
-MemAllocateHuge (int size);
+MemAllocateHuge (size_t size);
 
 void
-*MemAllocate (DataType *type, int size);
+*MemAllocate (DataType *type, size_t size);
 
 void
-*MemAllocateRef (DataType *type, int size);
+*MemAllocateRef (DataType *type, size_t size);
 
 #ifdef MEM_TRACE
 void
diff --git a/natural.c b/natural.c
index e219271..1e41534 100644
--- a/natural.c
+++ b/natural.c
@@ -829,7 +829,7 @@ NaturalPowMod (Natural *n, Natural *p, Natural *m)
 }
 
 static int
-digit_width (digit d, int base)
+digit_width (digit d, digit base)
 {
     int	    width = 1;
     while (d >= base)
@@ -841,7 +841,7 @@ digit_width (digit d, int base)
 }
 
 int
-NaturalEstimateLength (Natural *a, int base)
+NaturalEstimateLength (Natural *a, digit base)
 {
     if (length (a) == 0)
 	return 2;
diff --git a/ref.c b/ref.c
index e31f6cb..5cf5a79 100644
--- a/ref.c
+++ b/ref.c
@@ -31,7 +31,7 @@ RefPlus (Value av, Value bv, int expandOk)
     else
 	RETURN (Void);
     i = i + ref->element;
-    if (i < 0 || i >= ref->box->nvalues ||
+    if (i < 0 || (unsigned long) i >= ref->box->nvalues ||
 	(!ref->box->homogeneous && i != ref->element))
     {
 	RaiseStandardException (exception_invalid_array_bounds, 2,
@@ -79,7 +79,7 @@ RefMinus (Value av, Value bv, int expandOk)
 	RETURN (NewInt (ref->element - bref->element));
     }
     i = i + element;
-    if (i < 0 || i >= ref->box->nvalues || (!ref->box->homogeneous && i != ref->element))
+    if (i < 0 || (unsigned long) i >= ref->box->nvalues || (!ref->box->homogeneous && i != ref->element))
     {
 	RaiseStandardException (exception_invalid_array_bounds, 2,
 				av, bv);
@@ -184,8 +184,9 @@ ValueRep RefRep = {
     0,
     RefPrint,
     RefTypeCheck,
+    0,
 };
-    
+
 DataCachePtr	refCache;
 
 Value
diff --git a/sched.c b/sched.c
index 973fa5b..53680ad 100644
--- a/sched.c
+++ b/sched.c
@@ -80,7 +80,7 @@ void
 ThreadStepped (Value thread)
 {
     Value   t;
-    
+
     if ((t = thread->thread.next) &&
         thread->thread.priority <= t->thread.priority)
     {
@@ -97,7 +97,7 @@ ThreadsWakeup (Value sleep, WakeKind kind)
     for (thread = stopped; thread; thread = next)
     {
 	next = thread->thread.next;
-	if ((thread->thread.state == ThreadSuspended) && 
+	if ((thread->thread.state == ThreadSuspended) &&
 	    thread->thread.sleep == sleep)
 	{
 	    thread->thread.sleep = 0;
@@ -120,7 +120,7 @@ ThreadFinish (Value thread, Bool error)
 	lastThreadError = error;
     }
 }
-	    
+
 Value
 do_Thread_join (Value target)
 {
@@ -252,7 +252,7 @@ static int
 KillThread (Value thread)
 {
     int	ret;
-    
+
     if (!ValueIsThread(thread))
     {
 	RaiseStandardException (exception_invalid_argument, 3,
@@ -297,7 +297,7 @@ void
 TraceFunction (Value file, FramePtr frame, CodePtr code, ExprPtr name)
 {
     int		    fe;
-    
+
     FilePuts (file, "    ");
     if (name)
 	PrettyExpr (file, name, -1, 0, False);
@@ -356,7 +356,7 @@ do_Thread_trace (int n, Value *p)
     InstPtr	pc;
     ObjPtr	obj;
     int		depth = 20;
-    
+
     if (n == 0)
 	v = lookupVar (0, "cont");
     else
@@ -436,8 +436,9 @@ ValueRep    ThreadRep = {
     0,
     ThreadPrint,
     0,
+    0,
 };
-    
+
 static int  ThreadId;
 
 Value
@@ -447,7 +448,7 @@ NewThread (FramePtr frame, ObjPtr code)
     Value ret;
 
     ret = ALLOCATE (&ThreadRep.data, sizeof (Thread));
-    
+
     ret->thread.jump = 0;
     ret->thread.state = ThreadRunning;
     ret->thread.priority = 0;
@@ -455,12 +456,12 @@ NewThread (FramePtr frame, ObjPtr code)
     ret->thread.id = ++ThreadId;
     ret->thread.partial = 0;
     ret->thread.next = 0;
-    
+
     ContinuationInit (&ret->thread.continuation);
     ret->thread.continuation.obj = code;
     ret->thread.continuation.pc = ObjCode (code, 0);
     ret->thread.continuation.frame = frame;
-    
+
     complete = True;
     if (code->error)
 	ret->thread.state = ThreadFinished;
@@ -582,7 +583,7 @@ FarJumpContinuation (ContinuationPtr continuation, FarJumpPtr farJump)
     int		frames;
 
     ret = NewContinuation (continuation, 0);
-    
+
     /*
      * Unwind twixts
      */
@@ -625,7 +626,7 @@ FarJumpContinuation (ContinuationPtr continuation, FarJumpPtr farJump)
 	frame = frame->previous;
     }
     ret->continuation.frame = frame;
-    /* 
+    /*
      * Set pc for non-return jumps
      */
     if (farJump->inst >= 0)
@@ -636,7 +637,7 @@ FarJumpContinuation (ContinuationPtr continuation, FarJumpPtr farJump)
      * only intervening catch frames are on the stack
      * and they never have extra values on the stack
      */
-    
+
     ret->continuation.pc = pc;
     ret->continuation.obj = obj;
     RETURN (ret);
@@ -647,7 +648,7 @@ ContinuationMark (void *object)
 {
     ContinuationPtr	continuation = object;
 
-    assert (!continuation->pc || 
+    assert (!continuation->pc ||
 	    (ObjCode (continuation->obj, 0) <= continuation->pc &&
 	     continuation->pc <= ObjCode (continuation->obj, ObjLast(continuation->obj))));
     MemReference (continuation->obj);
@@ -695,6 +696,7 @@ ValueRep    ContinuationRep = {
     0,
     ContinuationPrint,
     0,
+    0,
 };
 
 Value
@@ -732,7 +734,7 @@ ContinuationTrace (char *where, Continuation *continuation, int indent)
     TwixtPtr	twixts = continuation->twixts;
     ObjPtr	obj = continuation->obj;
     InstPtr	pc = continuation->pc;
-    
+
     if (!dump_jump)
 	return;
     TraceIndent (indent);
@@ -846,7 +848,7 @@ static void
 JumpUnhandledException (Value thread)
 {
     Value   continuation = STACK_POP (thread->thread.continuation.stack);
-    
+
     /* make exec loop reschedule */
     if (thread == running)
 	SetSignalError ();
@@ -863,7 +865,7 @@ JumpContinue (Value thread, InstPtr *next)
     ENTER ();
     JumpPtr	jump = thread->thread.jump;
     TwixtPtr	twixt;
-    
+
     if (jump->leave)
     {
 	/*
@@ -985,7 +987,7 @@ do_setjmp (Value continuation_ref, Value ret)
 {
     ENTER ();
     Value	continuation;
-    
+
     if (!ValueIsRef(continuation_ref))
     {
 	RaiseStandardException (exception_invalid_argument, 3,
@@ -1097,9 +1099,9 @@ RaiseException (Value thread, SymbolPtr except, Value args, InstPtr *next)
     ENTER ();
     CatchPtr	    catch;
     ContinuationPtr continuation = 0;
-    
-    for (catch = thread->thread.continuation.catches; 
-	 catch; 
+
+    for (catch = thread->thread.continuation.catches;
+	 catch;
 	 catch = catch->continuation.catches)
     {
 	if (catch->exception == except)
@@ -1118,7 +1120,7 @@ RaiseException (Value thread, SymbolPtr except, Value args, InstPtr *next)
     {
 	int	i;
 	InstPtr	pc = thread->thread.continuation.pc;
-	
+
 	PrintError ("Unhandled exception %A (", except->symbol.name);
 	if (args)
 	{
@@ -1136,7 +1138,7 @@ RaiseException (Value thread, SymbolPtr except, Value args, InstPtr *next)
 		    pc,
 		    20);
 	continuation = EmptyContinuation();
-	STACK_PUSH (continuation->stack, 
+	STACK_PUSH (continuation->stack,
 		    NewContinuation (&thread->thread.continuation, pc));
     }
     ContinuationJump (thread, continuation, args, next);
@@ -1167,7 +1169,7 @@ SymbolPtr
 CheckStandardException (void)
 {
     SymbolPtr		except = standardExceptions[standardException];
-    
+
     signalException = False;
     standardException = exception_none;
     standardExceptionArgs = 0;
@@ -1183,7 +1185,7 @@ RaiseStandardException (StandardException   se,
     Value	args;
     int		i;
     va_list	va;
-    
+
     va_start (va, argc);
     i = argc;
     args = NewArray (False, False, typePoly, 1, &i);
@@ -1201,7 +1203,7 @@ JumpStandardException (Value thread, InstPtr *next)
     ENTER ();
     SymbolPtr		except = standardExceptions[standardException];
     Value		args = standardExceptionArgs;
-    
+
     aborting = False;
     if (except)
 	RaiseException (thread, except, args, next);
@@ -1217,7 +1219,7 @@ SignalThread (Value thread, Value signal, Bool executing)
     int		i = 1;
     Value	args = NewArray (False, False, typePoly, 1, &i);
     SymbolPtr	except = standardExceptions[exception_signal];
-    
+
     ArrayValueSet (&args->array, 0, signal);
     if (thread == running && executing)
     {
@@ -1228,7 +1230,7 @@ SignalThread (Value thread, Value signal, Bool executing)
     else if (except)
     {
 	InstPtr	next;
-	
+
 	RaiseException (thread, except, args, &next);
 	thread->thread.continuation.value = args;
 	thread->thread.continuation.pc = next;
diff --git a/string.c b/string.c
index f483b40..89e92c6 100644
--- a/string.c
+++ b/string.c
@@ -51,7 +51,7 @@ StringEqual (Value av, Value bv, int expandOk)
 static Value
 StringLess (Value av, Value bv, int expandOk)
 {
-    long    len;
+    size_t  len;
     int	    c;
 
     (void) expandOk;
diff --git a/sync.c b/sync.c
index bd0e185..c3e16e4 100644
--- a/sync.c
+++ b/sync.c
@@ -93,6 +93,7 @@ ValueRep   SemaphoreRep = {
     0,
     SemaphorePrint,
     0,
+    0,
 };
 
 Value
diff --git a/union.c b/union.c
index 06781a0..cf51cfc 100644
--- a/union.c
+++ b/union.c
@@ -107,6 +107,7 @@ ValueRep    UnionRep = {
     0,
     UnionPrint,
     0,
+    0,
 };
 
 Value
diff --git a/value.c b/value.c
index 70b83a4..441efd0 100644
--- a/value.c
+++ b/value.c
@@ -570,7 +570,7 @@ ShiftL (Value av, Value bv)
 	Sign	sign = Positive;
 	int	b = ValueInt(bv);
 
-	if (ValueIsInt (av) && b < NICKLE_INT_BITS)
+	if (ValueIsInt (av) && b >= 0 && (unsigned) b < NICKLE_INT_BITS)
 	{
 	    signed_digit    rd = (signed_digit) ValueInt (av) << b;
 
@@ -614,7 +614,7 @@ ShiftR (Value av, Value bv)
 	Sign	sign = Positive;
 	int	b = ValueInt(bv);
 
-	if (ValueIsInt (av) && b < NICKLE_INT_BITS)
+	if (ValueIsInt (av) && b >= 0 && (unsigned) b < NICKLE_INT_BITS)
 	{
 	    av = NewInt (ValueInt (av) >> b);
 	}
@@ -849,6 +849,8 @@ ValueRep UnitRep = {
     { 0 },	    /* unary */
     0, 0,
     UnitPrint,	    /* print */
+    0,
+    0,
 };
 
 static Value
@@ -898,6 +900,8 @@ ValueRep BoolRep = {
     { 0 },	    /* unary */
     0, 0,
     BoolPrint,	    /* print */
+    0,
+    0,
 };
 
 static Value
diff --git a/value.h b/value.h
index 2ac1d5e..8536239 100644
--- a/value.h
+++ b/value.h
@@ -217,7 +217,7 @@ Natural	*NaturalRsl (Natural *v, int shift);
 Natural	*NaturalLsl (Natural *v, int shift);
 Natural	*NaturalMask (Natural *v, int bits);
 int	NaturalPowerOfTwo (Natural *v);
-int	NaturalEstimateLength (Natural *, int base);
+int	NaturalEstimateLength (Natural *, digit base);
 void	NaturalCopy (Natural *, Natural *);
 Bool	NaturalZero (Natural *);
 Bool	NaturalEven (Natural *);
@@ -598,7 +598,7 @@ typedef struct _float {
 
 typedef struct _string {
     BaseValue	    base;
-    long	    length;
+    size_t	    length;
     char	    chars[0];
 } String;
 
@@ -1195,8 +1195,8 @@ int	FileInput (Value);
 int	FileOutput (Value, char);
 void	FileUnput (Value, unsigned char);
 int	FileInchar (Value);
-int	FileOutchar (Value, int);
-void	FileUnchar (Value, int);
+int	FileOutchar (Value, uint32_t);
+void	FileUnchar (Value, uint32_t);
 Value   FileCreate (int fd, int flags);
 int	FileFlush (Value, Bool block);
 int	FileClose (Value);
commit c9d2db54151c6795eadc8d4f30bf54da5c8a122b
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Oct 28 22:28:12 2024 -0700

    Annotate unused parameters with (void)
    
    Allow use of -Wunused-parameters
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/alarm.c b/alarm.c
index 0d6a520..25fd769 100644
--- a/alarm.c
+++ b/alarm.c
@@ -154,6 +154,7 @@ ReferencePtr	SleepingReference;
 static void
 _CatchAlarm (int sig)
 {
+    (void) sig;
     resetSignal (SIGALRM, _CatchAlarm);
     SetSignalTimer();
 }
diff --git a/array.c b/array.c
index 55183a0..43a9d5a 100644
--- a/array.c
+++ b/array.c
@@ -57,6 +57,7 @@ ArrayEqual (Value av, Value bv, int expandOk)
     int	    alimit = ArrayLimit (av), blimit = ArrayLimit (bv);
     int	    d;
 
+    (void) expandOk;
     if (a->ndim != b->ndim)
 	return FalseVal;
     for (d = 0; d < a->ndim; d++)
diff --git a/atom.c b/atom.c
index 1124d5e..2169378 100644
--- a/atom.c
+++ b/atom.c
@@ -16,6 +16,7 @@ typedef struct _atom {
 static void
 AtomEntryMark (void *object)
 {
+    (void) object;
     ;
 }
 
diff --git a/box.c b/box.c
index 1d78369..2d58edd 100644
--- a/box.c
+++ b/box.c
@@ -33,6 +33,7 @@ NewBox (Bool constant, Bool array, int nvalues, TypePtr type)
     BoxPtr  box;
     int	    i;
 
+    (void) array;
     box = ALLOCATE (&BoxType, sizeof (Box) + nvalues * sizeof (Value));
     box->constant = constant;
     box->homogeneous = True;
@@ -51,6 +52,7 @@ NewTypedBox (Bool array, BoxTypesPtr bt)
     BoxPtr  box;
     int	    i;
 
+    (void) array;
     box = ALLOCATE (&BoxType, sizeof (Box) + bt->count * sizeof (Value));
     box->constant = False;
     box->homogeneous = False;
diff --git a/builtin.c b/builtin.c
index 1c1bbed..5ced1d9 100644
--- a/builtin.c
+++ b/builtin.c
@@ -129,6 +129,7 @@ BuiltinSymbolValue(NamespacePtr *namespacep,
 		   BoxPtr   value)
 {
     ENTER ();
+    (void) type;
     RETURN (BuiltinAddName (namespacep, 
 			    NewSymbolGlobalValue (AtomId (string),
 						  value)));
diff --git a/compile.c b/compile.c
index 1ae4968..9701272 100644
--- a/compile.c
+++ b/compile.c
@@ -257,7 +257,8 @@ static void
 CompileStorage (ObjPtr obj, ExprPtr stat, SymbolPtr symbol, CodePtr code)
 {
     ENTER ();
-    
+
+    (void) stat;
     if (!symbol)
 	obj->error = True;
     /*
@@ -297,6 +298,7 @@ CompileDimensionStorage (ObjPtr obj, Class class, TypePtr type, CodePtr code)
     if (class == class_typedef)
 	class = code ? class_auto : class_global;
 
+    (void) obj;
     switch (class) {
     case class_global:
     case class_const:
@@ -336,6 +338,7 @@ CompileCheckSymbol (ObjPtr obj, ExprPtr stat, ExprPtr name, CodePtr code,
     int		d;
     CodePtr	c;
 
+    (void) createIfNecessary;
     s = name->atom.symbol;
     if (!s)
     {
@@ -1022,7 +1025,8 @@ CompileTypecheckArgs (ObjPtr	obj,
     Type	*actual_type;
     int		i;
     Bool	varactual;
-    
+
+    (void) argc;
     func_type = TypeCombineFunction (type);
     if (!func_type)
     {
@@ -1389,6 +1393,7 @@ CompileBuildArray (ObjPtr obj, ExprPtr expr, TypePtr type,
     ENTER ();
     InstPtr	inst;
 
+    (void) expr;
     if (dim)
     {
 	while (dim)
@@ -3137,12 +3142,13 @@ _CompileNonLocal (ObjPtr obj, BranchMod mod, ExprPtr expr, CodePtr code)
     InstPtr	inst;
     int		target;
 
+    (void) code;
     switch (mod) {
     case BranchModBreak:	target = NON_LOCAL_BREAK; break;
     case BranchModContinue:	target = NON_LOCAL_CONTINUE; break;
     case BranchModReturn:
     case BranchModReturnVoid:	target = NON_LOCAL_RETURN; break;
-    case BranchModNone:		
+    case BranchModNone:
     default:			RETURN(obj);
     }
     for (nl = obj->nonLocal; nl; nl = nl->prev)
@@ -4054,6 +4060,8 @@ CompileDeclInitObjStart (ObjPtr *obj, CodePtr code, CodePtr code_compile)
 static void
 CompileDeclInitObjFinish (ObjPtr *obj, ObjPtr *initObj, CodePtr code, CodePtr code_compile)
 {
+    (void) obj;
+    (void) initObj;
     if (code_compile)
     {
 	code_compile->func.inStaticInit = False;
diff --git a/execute.c b/execute.c
index 6db11aa..1b7c5e2 100644
--- a/execute.c
+++ b/execute.c
@@ -330,6 +330,7 @@ ThreadArrayInd (Value thread, Bool resizable, Value dim, Type *type)
     int	    ndim = ArrayLimits(a)[0];
     int	    *dims;
 
+    (void) thread;
     dims = AllocateTemp (ndim * sizeof (int));
     for (i = 0; i < ndim; i++)
     {
@@ -423,6 +424,7 @@ ThreadArrayReplicate (Value thread, Value array, int dim, int start)
     int		total;
     Value	*elements;
 
+    (void) thread;
     for (i = 0; i < dim; i++)
 	dimsize *= ArrayDims(&array->array)[i];
     start = start - dimsize;
@@ -443,7 +445,7 @@ ThreadArrayReplicate (Value thread, Value array, int dim, int start)
 
 void
 ThreadStackDump (Value thread);
-    
+
 static Value
 ThreadArrayInit (Value thread, Value value, AInitMode mode, 
 		 int dim, int *stack, InstPtr *next)
@@ -453,6 +455,7 @@ ThreadArrayInit (Value thread, Value value, AInitMode mode,
     int	    i;
     int	    ndim;
 
+    (void) next;
     if (aborting)
 	RETURN(value);
     switch (mode) {
@@ -853,7 +856,8 @@ static Value
 ThreadOpDot (Value thread, Value value, Atom atom, Bool fetch)
 {
     Value   v;
-    
+
+    (void) thread;
     switch (ValueTag(value)) {
     default:
 	RaiseStandardException (exception_invalid_unop_value, 1, value);
diff --git a/file.c b/file.c
index cce24f0..a1b87f9 100644
--- a/file.c
+++ b/file.c
@@ -455,6 +455,7 @@ volatile Bool	signalChild;
 static void
 sigchld (int sig)
 {
+    (void) sig;
     resetSignal (SIGCHLD, sigchld);
     SetSignalChild ();
 }
@@ -576,6 +577,12 @@ FileFree (void *object)
 static Bool
 FilePrint (Value f, Value av, char format, int base, int width, int prec, int fill)
 {
+    (void) av;
+    (void) format;
+    (void) base;
+    (void) width;
+    (void) prec;
+    (void) fill;
     FilePuts (f, "file");
     return True;
 }
diff --git a/float.c b/float.c
index 106195e..c9d2ae3 100644
--- a/float.c
+++ b/float.c
@@ -364,7 +364,8 @@ FloatTimes (Value av, Value bv, int expandOk)
     Fpart	*mant;
     Fpart	*exp;
     unsigned	prec;
-    
+
+    (void) expandOk;
     mant = FpartMult (a->mant, b->mant);
     exp = FpartAdd (a->exp, b->exp, False);
     if (a->prec < b->prec)
@@ -385,6 +386,7 @@ FloatDivide (Value av, Value bv, int expandOk)
     unsigned	prec;
     unsigned	iprec, alen;
 
+    (void) expandOk;
     if (FpartZero (b->mant))
     {
 	RaiseStandardException (exception_divide_by_zero, 2,
@@ -481,6 +483,7 @@ FloatNegate (Value av, int expandOk)
     ENTER ();
     Float   *a = &av->floats;
 
+    (void) expandOk;
     RETURN (NewFloat (FpartNegate (a->mant), a->exp, a->prec));
 }
 
@@ -516,6 +519,7 @@ FloatFloor (Value av, int expandOk)
     Fpart   *exp;
     int	    d;
 
+    (void) expandOk;
     if (a->exp->sign == Positive)
 	RETURN (FloatInteger (av));
     if (NaturalLess (NewNatural (a->prec), a->exp->mag))
@@ -534,7 +538,7 @@ FloatFloor (Value av, int expandOk)
     exp = zero_fpart;
     RETURN (FloatInteger (NewFloat (mant, exp, a->prec - d)));
 }
-   
+
 static Value
 FloatCeil (Value av, int expandOk)
 {
@@ -544,6 +548,7 @@ FloatCeil (Value av, int expandOk)
     Fpart   *exp;
     int	    d;
 
+    (void) expandOk;
     if (a->exp->sign == Positive)
 	RETURN (FloatInteger (av));
     if (NaturalLess (NewNatural (a->prec), a->exp->mag))
diff --git a/foreign.c b/foreign.c
index e7c8f7b..7d9942c 100644
--- a/foreign.c
+++ b/foreign.c
@@ -9,6 +9,7 @@
 static Value
 ForeignEqual (Value av, Value bv, int expandOk)
 {
+    (void) expandOk;
     if (av->foreign.data == bv->foreign.data)
 	return TrueVal;
     return FalseVal;
@@ -17,6 +18,11 @@ ForeignEqual (Value av, Value bv, int expandOk)
 static Bool
 ForeignPrint (Value f, Value av, char format, int base, int width, int prec, int fill)
 {
+    (void) format;
+    (void) base;
+    (void) width;
+    (void) prec;
+    (void) fill;
     FilePrintf (f, "foreign %s (0x%x)", av->foreign.id, av->foreign.data);
     return True;
 }
diff --git a/func.c b/func.c
index 8656d71..e89c527 100644
--- a/func.c
+++ b/func.c
@@ -122,6 +122,10 @@ FuncPrint (Value f, Value av, char format, int base, int width, int prec, int fi
 {
     Bool    nest = False;
 
+    (void) base;
+    (void) width;
+    (void) prec;
+    (void) fill;
     if (format == 'v')
 	nest = True;
     PrettyCode (f, av->func.code, 0, class_undef, publish_private, 0, nest);
diff --git a/hash.c b/hash.c
index 70335d5..5c932f9 100644
--- a/hash.c
+++ b/hash.c
@@ -187,6 +187,7 @@ HashEqual (Value av, Value bv, int expandOk)
     HashValue	i;
     Value	*ae, *be;
 
+    (void) expandOk;
     /* if they have different numbers of valid elements, they're not equal */
     if (at->count != bt->count)
 	return FalseVal;
@@ -323,6 +324,7 @@ NewHash (Bool constant, TypePtr keyType, TypePtr type)
 {
     ENTER ();
     Value   ret = ALLOCATE (&HashRep.data, sizeof (HashTable));
+    (void) constant;
     ret->hash.hashSet = 0;
     ret->hash.count = 0;
     ret->hash.type = type;
diff --git a/int.c b/int.c
index e0899ea..55c2cde 100644
--- a/int.c
+++ b/int.c
@@ -49,7 +49,7 @@ logbase2(int a)
 	log += 1;
     return log;
 }
-		
+
 #define HALF_BITS   (NICKLE_INT_BITS>>1)
 #define HALF_MAX    (1 << (NICKLE_INT_BITS>>1))
 
@@ -59,6 +59,7 @@ IntTimes (Value av, Value bv, int expandOk)
     int		    a = ValueInt(av), b = ValueInt(bv);
     signed_digit    rd = (signed_digit) a * (signed_digit) b;
 
+    (void) expandOk;
     if (rd > (signed_digit) MAX_NICKLE_INT || rd < (signed_digit) MIN_NICKLE_INT)
 	return NewSignedDigitInteger (rd);
     return NewInt ((int) rd);
@@ -92,6 +93,7 @@ IntDiv (Value av, Value bv, int expandOk)
     int		d;
     Value	ret;
 
+    (void) expandOk;
     if (b == 0)
     {
 	RaiseStandardException (exception_divide_by_zero, 2,
@@ -135,6 +137,7 @@ IntMod (Value av, Value bv, int expandOk)
     int		a = ValueInt(av), b = ValueInt(bv);
     int		r;
 
+    (void) expandOk;
     if (b == 0)
     {
 	RaiseStandardException (exception_divide_by_zero, 2,
@@ -167,6 +170,8 @@ static Value
 IntEqual (Value av, Value bv, int expandOk)
 {
     int		a = ValueInt(av), b = ValueInt(bv);
+
+    (void) expandOk;
     if (a == b)
 	return TrueVal;
     return FalseVal;
@@ -176,6 +181,8 @@ static Value
 IntLess (Value av, Value bv, int expandOk)
 {
     int		a = ValueInt(av), b = ValueInt(bv);
+
+    (void) expandOk;
     if (a < b)
 	return TrueVal;
     return FalseVal;
@@ -185,6 +192,8 @@ static Value
 IntLand (Value av, Value bv, int expandOk)
 {
     ENTER ();
+
+    (void) expandOk;
     int		a = ValueInt(av), b = ValueInt(bv);
     RETURN (NewInt (a & b));
 }
@@ -194,6 +203,8 @@ IntLor (Value av, Value bv, int expandOk)
 {
     ENTER ();
     int		a = ValueInt(av), b = ValueInt(bv);
+
+    (void) expandOk;
     RETURN (NewInt (a | b));
 }
 
@@ -203,6 +214,7 @@ IntNegate (Value av, int expandOk)
     ENTER ();
     int	    a = ValueInt(av);
 
+    (void) expandOk;
     if (-(-a) != a)
 	RETURN (Negate (NewIntInteger (a)));
     RETURN (NewInt (-a));
@@ -211,12 +223,14 @@ IntNegate (Value av, int expandOk)
 static Value
 IntFloor (Value av, int expandOk)
 {
+    (void) expandOk;
     return av;
 }
 
 static Value
 IntCeil (Value av, int expandOk)
 {
+    (void) expandOk;
     return av;
 }
 
diff --git a/integer.c b/integer.c
index 1247fd8..a44d65e 100644
--- a/integer.c
+++ b/integer.c
@@ -53,6 +53,7 @@ IntegerPlus (Value av, Value bv, int expandOk)
     Integer	*a = &av->integer, *b = &bv->integer;
     Value	ret;
 
+    (void) expandOk;
     switch (catagorize_signs(ISign(a), ISign(b))) {
     case BothPositive:
     default:
@@ -84,6 +85,7 @@ IntegerMinus (Value av, Value bv, int expandOk)
     Integer	*a = &av->integer, *b = &bv->integer;
     Value	ret;
 
+    (void) expandOk;
     switch (catagorize_signs(ISign(a), ISign(b))) {
     case BothPositive:
     default:
@@ -115,6 +117,7 @@ IntegerTimes (Value av, Value bv, int expandOk)
     Integer	*a = &av->integer, *b = &bv->integer;
     Sign	sign;
 
+    (void) expandOk;
     sign = Positive;
     if (ISign(a) != ISign(b))
 	sign = Negative;
@@ -152,6 +155,7 @@ IntegerDiv (Value av, Value bv, int expandOk)
     Sign	sign;
     Natural	*quo, *rem;
 
+    (void) expandOk;
     if  (NaturalZero (IMag(b)))
     {
 	RaiseStandardException (exception_divide_by_zero, 2,
@@ -174,6 +178,7 @@ IntegerMod (Value av, Value bv, int expandOk)
     Integer	*a = &av->integer, *b = &bv->integer;
     Natural	*rem;
 
+    (void) expandOk;
     if  (NaturalZero (IMag(b)))
     {
 	RaiseStandardException (exception_divide_by_zero, 2,
@@ -192,6 +197,7 @@ IntegerLess (Value av, Value bv, int expandOk)
     Integer	*a = &av->integer, *b = &bv->integer;
     Value	ret;
 
+    (void) expandOk;
     ret = FalseVal;
     switch (catagorize_signs (ISign(a), ISign(b))) {
     case BothPositive:
@@ -216,6 +222,7 @@ IntegerEqual (Value av, Value bv, int expandOk)
 {
     Integer	*a = &av->integer, *b = &bv->integer;
 
+    (void) expandOk;
     if (ISign(a) == ISign(b) && NaturalEqual (IMag(a), IMag(b)))
 	return TrueVal;
     return FalseVal;
@@ -235,6 +242,7 @@ IntegerLand (Value av, Value bv, int expandOk)
     Integer	*a = &av->integer, *b = &bv->integer;
     Natural	*am = IMag(a), *bm = IMag(b), *m;
 
+    (void) expandOk;
     DebugN("a", am);
     if (ISign(a) == Negative)
     {
@@ -269,6 +277,7 @@ IntegerLor (Value av, Value bv, int expandOk)
     Integer	*a = &av->integer, *b = &bv->integer;
     Natural	*am = IMag(a), *bm = IMag(b), *m;
 
+    (void) expandOk;
     DebugN("a", am);
     if (ISign(a) == Negative)
     {
@@ -299,24 +308,28 @@ IntegerNegate (Value av, int expandOk)
 {
     Integer *a = &av->integer;
 
+    (void) expandOk;
     return NewInteger (SignNegate (ISign(a)), IMag(a));
 }
 
 static Value
 IntegerFloor (Value av, int expandOk)
 {
+    (void) expandOk;
     return av;
 }
 
 static Value
 IntegerCeil (Value av, int expandOk)
 {
+    (void) expandOk;
     return av;
 }
 
 static Value
 IntegerPromote (Value av, Value bv)
 {
+    (void) bv;
     if (ValueIsInt(av))
 	av = NewIntInteger (ValueInt(av));
     return av;
diff --git a/io.c b/io.c
index 22af373..496b654 100644
--- a/io.c
+++ b/io.c
@@ -27,6 +27,7 @@ Bool		anyFileWriteBlocked;
 static void
 sigio (int sig)
 {
+    (void) sig;
     resetSignal (SIGIO, sigio);
     SetSignalIo ();
 }
@@ -96,6 +97,7 @@ BoxPtr   FileStdinBox, FileStdoutBox, FileStderrBox;
 Bool
 IoTimeout (void *closure)
 {
+    (void) closure;
     if (!stdinOwned)
 	IoStart ();
     FileCheckBlocked (False);
diff --git a/lex.l b/lex.l
index 1957d05..6c340e8 100644
--- a/lex.l
+++ b/lex.l
@@ -106,6 +106,7 @@ LexGetChar (void);
 static int
 ReadlineGetChar (FILE *f)
 {
+    (void) f;
     return LexGetChar ();
 }
 #endif
diff --git a/main.c b/main.c
index f10d4d7..7c9d317 100644
--- a/main.c
+++ b/main.c
@@ -151,6 +151,9 @@ resetSignal (int sig, void (*func) (int sig))
 {
 #ifndef HAVE_SIGACTION
     signal (sig, func);
+#else
+    (void) sig;
+    (void) func;
 #endif
 }
 
@@ -159,6 +162,7 @@ volatile Bool	signalInterrupt;
 void
 intr (int sig)
 {
+    (void) sig;
     resetSignal (SIGINT, intr);
     if (signalInterrupt) {
 	int ret = write(2,"Double interrupt, exiting\n", 26);
@@ -223,6 +227,7 @@ die (int sig)
 void
 segv (int sig)
 {
+    (void) sig;
     IoStop ();
 #ifdef HAVE_RL_CLEANUP_AFTER_SIGNAL
     if (stdin_in_readline)
diff --git a/pretty.c b/pretty.c
index b49cda9..84b66cb 100644
--- a/pretty.c
+++ b/pretty.c
@@ -163,6 +163,7 @@ PrettyArrayInit (Value f, Expr *e, int level, Bool nest);
 static void
 PrettyArrayInits (Value f, Expr *e, int level, Bool nest)
 {
+    (void) level;
     while (e)
     {
 	if (e->tree.left)
diff --git a/profile.c b/profile.c
index 15876c4..a107cbd 100644
--- a/profile.c
+++ b/profile.c
@@ -18,6 +18,7 @@ Bool				profiling;
 static void
 sigprofile (int sig)
 {
+    (void) sig;
     resetSignal (SIGVTALRM, sigprofile);
     currentTick += TICK_MS;
     SetSignalProfile ();
diff --git a/rational.c b/rational.c
index 1e4f96d..d9a0e14 100644
--- a/rational.c
+++ b/rational.c
@@ -18,7 +18,7 @@ RationalInit (void)
 {
     return 1;
 }
-	
+
 #if 0
 static Value
 natural_to_rational (Natural *n)
@@ -32,7 +32,7 @@ static Value
 RationalPlusHelper (Sign sign, Rational *a, Rational *b)
 {
     ENTER ();
-    RETURN (NewRational (sign, 
+    RETURN (NewRational (sign,
 			  NaturalPlus (NaturalTimes (a->num, b->den),
 				       NaturalTimes (b->num, a->den)),
 			  NaturalTimes (a->den, b->den)));
@@ -47,7 +47,7 @@ RationalMinusHelper (Rational *a, Rational *b)
 
     ra = NaturalTimes (a->num, b->den);
     rb = NaturalTimes (b->num, a->den);
-    if (NaturalLess (ra, rb)) 
+    if (NaturalLess (ra, rb))
     {
 	sign = Negative;
 	t = ra;
@@ -65,6 +65,7 @@ RationalPlus (Value av, Value bv, int expandOk)
     Rational	*a = &av->rational, *b = &bv->rational;
     Value	ret;
 
+    (void) expandOk;
     switch (catagorize_signs(a->sign, b->sign)) {
     case BothPositive:
     case BothNegative:
@@ -89,6 +90,7 @@ RationalMinus (Value av, Value bv, int expandOk)
     Rational	*a = &av->rational, *b = &bv->rational;
     Value	ret;
 
+    (void) expandOk;
     switch (catagorize_signs(a->sign, b->sign)) {
     case BothPositive:
 	ret = RationalMinusHelper (a, b);
@@ -113,10 +115,11 @@ RationalTimes (Value av, Value bv, int expandOk)
     Rational	*a = &av->rational, *b = &bv->rational;
     Sign	sign;
 
+    (void) expandOk;
     sign = Positive;
     if (a->sign != b->sign)
 	sign = Negative;
-    RETURN (NewRational (sign, 
+    RETURN (NewRational (sign,
 			 NaturalTimes (a->num, b->num),
 			 NaturalTimes (a->den, b->den)));
 }
@@ -128,6 +131,7 @@ RationalDivide (Value av, Value bv, int expandOk)
     Rational	*a = &av->rational, *b = &bv->rational;
     Sign	sign;
 
+    (void) expandOk;
     if (NaturalZero (b->num))
     {
 	RaiseStandardException (exception_divide_by_zero, 2,
@@ -137,7 +141,7 @@ RationalDivide (Value av, Value bv, int expandOk)
     sign = Positive;
     if (a->sign != b->sign)
 	sign = Negative;
-    RETURN (NewRational (sign, 
+    RETURN (NewRational (sign,
 			  NaturalTimes (a->num, b->den),
 			  NaturalTimes (a->den, b->num)));
 }
@@ -164,7 +168,7 @@ RationalDivide (Value av, Value bv, int expandOk)
  *  (e * b * d) / f = (a * d) % (c * b)
  *  e / f = ((a * d) % (c * b)) / (b * d)
  */
-    
+
 static Value
 RationalMod (Value av, Value bv, int expandOk)
 {
@@ -172,6 +176,7 @@ RationalMod (Value av, Value bv, int expandOk)
     Rational	*a = &av->rational, *b = &bv->rational;
     Natural	*rem, *div;
 
+    (void) expandOk;
     if (NaturalZero (b->num))
     {
 	RaiseStandardException (exception_divide_by_zero, 2,
@@ -194,6 +199,7 @@ RationalLess (Value av, Value bv, int expandOk)
     Rational	*t;
     int		ret;
 
+    (void) expandOk;
     switch (catagorize_signs (a->sign, b->sign)) {
     case BothNegative:
 	t = a;
@@ -223,9 +229,10 @@ static Value
 RationalEqual (Value av, Value bv, int expandOk)
 {
     Rational	*a = &av->rational, *b = &bv->rational;
-    
-    if (a->sign == b->sign && 
-	NaturalEqual (a->num, b->num) && 
+
+    (void) expandOk;
+    if (a->sign == b->sign &&
+	NaturalEqual (a->num, b->num) &&
 	NaturalEqual (a->den, b->den))
     {
 	return TrueVal;
@@ -239,6 +246,7 @@ RationalNegate (Value av, int expandOk)
     ENTER ();
     Rational	*a = &av->rational;
 
+    (void) expandOk;
     RETURN (NewRational (SignNegate (a->sign), a->num, a->den));
 }
 
@@ -249,6 +257,7 @@ RationalFloor (Value av, int expandOk)
     Rational	*a = &av->rational;
     Natural	*quo, *rem;
 
+    (void) expandOk;
     quo = NaturalDivide (a->num, a->den, &rem);
     if (!NaturalZero (rem) && a->sign == Negative)
 	quo = NaturalPlus (quo, one_natural);
@@ -262,6 +271,7 @@ RationalCeil (Value av, int expandOk)
     Rational	*a = &av->rational;
     Natural	*quo, *rem;
 
+    (void) expandOk;
     quo = NaturalDivide (a->num, a->den, &rem);
     if (!NaturalZero (rem) && a->sign == Positive)
 	quo = NaturalPlus (quo, one_natural);
@@ -273,6 +283,7 @@ RationalPromote (Value av, Value bv)
 {
     ENTER ();
 
+    (void) bv;
     switch (ValueTag(av)) {
     case rep_int:
 	av = NewIntRational (ValueInt(av));
@@ -285,7 +296,7 @@ RationalPromote (Value av, Value bv)
     }
     RETURN (av);
 }
-	    
+
 static Value
 RationalReduce (Value av)
 {
@@ -376,7 +387,7 @@ static int
 IntFactor (int a)
 {
     int	    v, lim;
-    
+
     if (!a)
 	return 0;
     if ((a & 1) == 0)
@@ -426,9 +437,9 @@ IntPowMod (int a, int p, int m)
 		la = (la * la) % lm;
 	}
 	result = (int) lr;
-#else	
+#else
 	ENTER ();
-	result = NaturalToInt (NaturalPowMod (NewNatural (a), 
+	result = NaturalToInt (NaturalPowMod (NewNatural (a),
 					      NewNatural (p),
 					      NewNatural (m)));
 	EXIT ();
@@ -539,7 +550,7 @@ NewFactor (Natural *prime, int power, FactorPtr next)
     RETURN (f);
 }
 
-static FactorPtr 
+static FactorPtr
 GenerateFactors (Natural *n, Natural *max)
 {
     ENTER ();
@@ -561,7 +572,7 @@ GenerateFactors (Natural *n, Natural *max)
 		p = NewNatural (3);
 	    else
 		p = NaturalPlus (p, two_natural);
-	    
+
 	    d = NaturalDivide (n, p, &rem);
 	    if (NaturalZero (rem))
 		break;
@@ -590,7 +601,7 @@ FactorBump (FactorPtr	f)
 {
     PartialPtr	p, minp;
     Natural	*factor;
-    
+
     ENTER ();
     if (!f)
 	RETURN(0);
@@ -943,7 +954,7 @@ RationalDecimalPrint (Value f, Value rv, char format, int base, int width, int p
 	    EXIT ();
 	    return False;
 	}
-	in = NaturalSprint (initial + initial_width + 1, 
+	in = NaturalSprint (initial + initial_width + 1,
 			    init, base, &initial_width);
 	if (!in)
 	{
@@ -973,9 +984,9 @@ RationalDecimalPrint (Value f, Value rv, char format, int base, int width, int p
 	    repeat_width = -1;
 	    rep_width >>= 1;
 	}
-	rep = NaturalDivide (NaturalTimes (partial, 
+	rep = NaturalDivide (NaturalTimes (partial,
 					   NaturalIntPow (dig, rep_width)),
-			     r->den, 
+			     r->den,
 			     &partial);
 	if (aborting)
 	{
@@ -1053,7 +1064,7 @@ RationalPrint (Value f, Value rv, char format, int base, int width, int prec, in
     int		num_width, den_width;
     int		print_width;
     Bool	ret = True;
-    
+
     if (format == 'a') {
 	Value fv = NewRationalFloat(r, DEFAULT_FLOAT_PREC);
 	ValueRep *rep = ValueRep(fv);
@@ -1122,7 +1133,7 @@ RationalMark (void *object)
     MemReference (rational->den);
 }
 
-ValueRep    RationalRep = { 
+ValueRep    RationalRep = {
     { RationalMark, 0, "RationalRep" },    /* base */
     rep_rational,	    /* tag */
     {			    /* binary */
@@ -1164,7 +1175,7 @@ NewRational (Sign sign, Natural *num, Natural *den)
 	if (NaturalLength(den) != 1 || NaturalDigits(den)[0] != 1)
 	{
 	    g = NaturalGcd (num, den);
-	    if (NaturalLength (g) != 1 || NaturalDigits(g)[0] != 1) 
+	    if (NaturalLength (g) != 1 || NaturalDigits(g)[0] != 1)
 	    {
 		num = NaturalDivide (num, g, &rem);
 		den = NaturalDivide (den, g, &rem);
diff --git a/ref.c b/ref.c
index d199553..e31f6cb 100644
--- a/ref.c
+++ b/ref.c
@@ -13,6 +13,7 @@ RefPlus (Value av, Value bv, int expandOk)
     int	    i;
     Ref	    *ref;
 
+    (void) expandOk;
     if (ValueIsInt(av))
     {
 	i = IntPart (av, "Attempt to add non-integer to reference type");
@@ -48,6 +49,7 @@ RefMinus (Value av, Value bv, int expandOk)
     int	    element;
     Ref	    *ref, *bref;
 
+    (void) expandOk;
     if (ValueIsInt(av))
     {
 	i = IntPart (av, "Attempt to subtract non-integer to reference type");
@@ -91,6 +93,7 @@ RefLess (Value av, Value bv, int expandOk)
 {
     Ref	*aref = &av->ref, *bref = &bv->ref;
 
+    (void) expandOk;
     if (aref->box != bref->box || 
 	(!aref->box->homogeneous && aref->element != bref->element))
     {
@@ -108,6 +111,7 @@ RefEqual (Value av, Value bv, int expandOk)
 {
     Ref	*aref = &av->ref, *bref = &bv->ref;
 
+    (void) expandOk;
     if (aref->box != bref->box || aref->element != bref->element)
 	return FalseVal;
     return TrueVal;
@@ -116,6 +120,7 @@ RefEqual (Value av, Value bv, int expandOk)
 static ValueRep *
 RefTypeCheck (BinaryOp op, Value av, Value bv, int expandOk)
 {
+    (void) expandOk;
     switch (op) {
     case MinusOp:
 	if (ValueIsRef(av) && ValueIsRef(bv))
diff --git a/sched.c b/sched.c
index 6fc363b..973fa5b 100644
--- a/sched.c
+++ b/sched.c
@@ -403,6 +403,11 @@ ThreadMark (void *object)
 static Bool
 ThreadPrint (Value f, Value av, char format, int base, int width, int prec, int fill)
 {
+    (void) format;
+    (void) base;
+    (void) width;
+    (void) prec;
+    (void) fill;
     FilePrintf (f, "%%%d", av->thread.id);
     return True;
 }
@@ -656,6 +661,12 @@ ContinuationMark (void *object)
 static Bool
 ContinuationPrint (Value f, Value av, char format, int base, int width, int prec, int fill)
 {
+    (void) av;
+    (void) format;
+    (void) base;
+    (void) width;
+    (void) prec;
+    (void) fill;
     FilePuts (f, "continutation");
     return True;
 }
diff --git a/string.c b/string.c
index 5945e95..f483b40 100644
--- a/string.c
+++ b/string.c
@@ -24,6 +24,7 @@ StringPlus (Value av, Value bv, int expandOk)
     ENTER();
     Value	ret;
 
+    (void) expandOk;
     ret = NewString (av->string.length + bv->string.length);
     (void) memcpy (StringChars(&ret->string),
 		   StringChars(&av->string),
@@ -37,6 +38,7 @@ StringPlus (Value av, Value bv, int expandOk)
 static Value
 StringEqual (Value av, Value bv, int expandOk)
 {
+    (void) expandOk;
     if (av->string.length != bv->string.length)
 	return FalseVal;
     if (!memcmp (StringChars (&av->string), 
@@ -52,6 +54,7 @@ StringLess (Value av, Value bv, int expandOk)
     long    len;
     int	    c;
 
+    (void) expandOk;
     len = av->string.length;
     if (len > bv->string.length)
 	len = bv->string.length;
@@ -71,6 +74,8 @@ StringPrint (Value f, Value av, char format, int base, int width, int prec, int
     long    len = av->string.length;
     int	    print_width;
     
+    (void) base;
+    (void) prec;
     print_width = FileStringWidth (string, len, format);
     while (width > print_width)
     {
diff --git a/struct.c b/struct.c
index 4c999d2..1dda900 100644
--- a/struct.c
+++ b/struct.c
@@ -90,7 +90,8 @@ StructEqual (Value a, Value b, int expandOk)
 {
     int		    i;
     StructType	    *at = a->structs.type;
-    
+
+    (void) expandOk;
     if (at->nelements != b->structs.type->nelements)
 	return FalseVal;
     for (i = 0; i < at->nelements; i++)
@@ -148,6 +149,7 @@ NewStruct (StructType *type, Bool constant)
     ENTER ();
     Value	    ret;
 
+    (void) constant;
     ret = ALLOCATE (&StructRep.data, sizeof (Struct));
     ret->structs.type = type;
     ret->structs.values = 0;
diff --git a/sync.c b/sync.c
index 4777ba5..bd0e185 100644
--- a/sync.c
+++ b/sync.c
@@ -60,6 +60,11 @@ do_Semaphore_signal (Value s)
 static Bool
 SemaphorePrint (Value f, Value av, char format, int base, int width, int prec, int fill)
 {
+    (void) format;
+    (void) base;
+    (void) width;
+    (void) prec;
+    (void) fill;
     FilePrintf (f, "semaphore %d (%d)", av->semaphore.id, av->semaphore.count);
     return True;
 }
diff --git a/union.c b/union.c
index 7bb4242..06781a0 100644
--- a/union.c
+++ b/union.c
@@ -72,7 +72,8 @@ static Value
 UnionEqual (Value av, Value bv, int expandOk)
 {
     Union	    *a = &av->unions, *b = &bv->unions;
-    
+
+    (void) expandOk;
     if (!ValueIsUnion(av))
 	return Equal (av, BoxValue (b->value, 0));
     if (!ValueIsUnion(bv))
@@ -82,7 +83,7 @@ UnionEqual (Value av, Value bv, int expandOk)
     return Equal (BoxValue (a->value, 0), BoxValue (b->value, 0));
 }
 
-ValueRep    UnionRep = { 
+ValueRep    UnionRep = {
     { UnionMark, 0, "UnionRep" },	    /* base */
     rep_union,		    /* tag */
     {			    /* binary */
diff --git a/value.c b/value.c
index 9c313bf..70b83a4 100644
--- a/value.c
+++ b/value.c
@@ -99,7 +99,7 @@ IntPart (Value av, char *error)
     if (!ValueIsInt(av))
     {
 	RaiseStandardException (exception_invalid_argument, 3,
-				NewStrString (error), 
+				NewStrString (error),
 				NewInt (0), av);
 	return 0;
     }
@@ -112,7 +112,7 @@ BoolPart (Value av, char *error)
     if (!ValueIsBool(av))
     {
 	RaiseStandardException (exception_invalid_argument, 3,
-				NewStrString (error), 
+				NewStrString (error),
 				NewInt (0), av);
 	return 0;
     }
@@ -128,7 +128,7 @@ SignedDigitPart(Value av, char *error)
 	return IntegerToSignedDigit(&av->integer);
 
     RaiseStandardException (exception_invalid_argument, 3,
-			    NewStrString (error), 
+			    NewStrString (error),
 			    NewInt (0), av);
     return 0;
 }
@@ -143,26 +143,26 @@ BinaryOperate (Value av, Value bv, BinaryOp operator)
 	switch (operator) {
 	case PlusOp:
 	    r = ValueInt(av) + ValueInt(bv);
-    
+
 	    if (NICKLE_INT_CARRIED(r))
 		return Plus (NewIntInteger (ValueInt(av)), NewIntInteger(ValueInt(bv)));
 	    return NewInt(r);
 	case MinusOp:
 	    r = ValueInt(av) - ValueInt(bv);
-    
+
 	    if (NICKLE_INT_CARRIED(r))
 		return Minus (NewIntInteger (ValueInt(av)), NewIntInteger(ValueInt(bv)));
-	    return NewInt(r);    
+	    return NewInt(r);
 	case TimesOp:
 	    a = ValueInt(av), b = ValueInt(bv);
 	    rd = (signed_digit) a * (signed_digit) b;
-    
+
 	    if (rd > (signed_digit) MAX_NICKLE_INT || rd < (signed_digit) MIN_NICKLE_INT)
 		return NewSignedDigitInteger (rd);
 	    return NewInt ((int) rd);
 	case DivideOp:
 	    a = ValueInt(av), b = ValueInt(bv);
-    
+
 	    if (b == 0)
 	    {
 		RaiseStandardException (exception_divide_by_zero, 2,
@@ -174,7 +174,7 @@ BinaryOperate (Value av, Value bv, BinaryOp operator)
 	    return NewInt (a/b);
 	case DivOp:
 	    a = ValueInt(av), b = ValueInt(bv);
-    
+
 	    if (b == 0)
 	    {
 		RaiseStandardException (exception_divide_by_zero, 2,
@@ -203,7 +203,7 @@ BinaryOperate (Value av, Value bv, BinaryOp operator)
 	    return NewInt (r);
 	case ModOp:
 	    a = ValueInt(av), b = ValueInt(bv);
-    
+
 	    if (b == 0)
 	    {
 		RaiseStandardException (exception_divide_by_zero, 2,
@@ -249,7 +249,7 @@ BinaryOperate (Value av, Value bv, BinaryOp operator)
 	Value	ret;
 	ValueRep	*arep = ValueRep(av), *brep = ValueRep(bv);
 	ValueRep	*rep = 0;
-    
+
 	if (arep->typecheck)
 	    rep = (*arep->typecheck) (operator, av, bv, 1);
 	else if (brep->typecheck)
@@ -292,7 +292,7 @@ UnaryOperate (Value v, UnaryOp operator)
     ENTER ();
     Value	ret;
     ValueRep	*rep = ValueRep(v);
-    
+
     if (!rep->unary[operator])
     {
 	RaiseStandardException (exception_invalid_unop_value, 1,
@@ -322,6 +322,7 @@ NumericDiv (Value av, Value bv, int expandOk)
 {
     ENTER ();
 
+    (void) expandOk;
     av = Divide (av, bv);
     if (Negativep (bv))
 	av = Ceil (av);
@@ -375,7 +376,7 @@ Lxor (Value av, Value bv)
 {
     ENTER ();
     RETURN (Land (Lnot (Land (av, bv)),
-		  Lor (av, bv))); 
+		  Lor (av, bv)));
 }
 
 Value
@@ -419,7 +420,7 @@ Factorial (Value av)
 {
     ENTER ();
     Value   tv;
-    Value   i;    
+    Value   i;
     StackPointer    iref, tvref;
 
     if (!Integralp (ValueTag(av)) || Negativep (av))
@@ -568,11 +569,11 @@ ShiftL (Value av, Value bv)
     {
 	Sign	sign = Positive;
 	int	b = ValueInt(bv);
-	
+
 	if (ValueIsInt (av) && b < NICKLE_INT_BITS)
 	{
 	    signed_digit    rd = (signed_digit) ValueInt (av) << b;
-	    
+
 	    if (rd > (signed_digit) MAX_NICKLE_INT || rd < (signed_digit) MIN_NICKLE_INT)
 		av = NewSignedDigitInteger (rd);
 	    else
@@ -612,7 +613,7 @@ ShiftR (Value av, Value bv)
     {
 	Sign	sign = Positive;
 	int	b = ValueInt(bv);
-	
+
 	if (ValueIsInt (av) && b < NICKLE_INT_BITS)
 	{
 	    av = NewInt (ValueInt (av) >> b);
@@ -640,14 +641,14 @@ Value
 Gcd (Value av, Value bv)
 {
     ENTER ();
-    
+
     if (!Integralp (ValueTag(av)) || !Integralp (ValueTag(bv)))
     {
 	RaiseStandardException (exception_invalid_binop_values, 2,
 				av, bv);
 	RETURN (Void);
     }
-    RETURN (Reduce (NewInteger (Positive, 
+    RETURN (Reduce (NewInteger (Positive,
 				NaturalGcd (IntegerMag(IntegerRep.promote (av, 0)),
 					    IntegerMag(IntegerRep.promote (bv, 0))))));
 }
@@ -657,7 +658,7 @@ Value
 Bdivmod (Value av, Value bv)
 {
     ENTER ();
-    
+
     if (!Integralp (ValueTag(av)) || !Integralp (ValueTag(bv)))
     {
 	RaiseStandardException (exception_invalid_binop_values, 2,
@@ -673,7 +674,7 @@ Value
 KaryReduction (Value av, Value bv)
 {
     ENTER ();
-    
+
     if (!Integralp (ValueTag(av)) || !Integralp (ValueTag(bv)))
     {
 	RaiseStandardException (exception_invalid_binop_values, 2,
@@ -695,7 +696,7 @@ Print (Value f, Value v, char format, int base, int width, int prec, int fill)
     int		i;
     Bool	ret;
     ValueRep	*rep;
-    
+
     if (!v)
     {
 	FilePuts (f, "<uninit>");
@@ -791,6 +792,7 @@ CopyMutable (Value v)
 Value
 ValueEqual (Value a, Value b, int expandOk)
 {
+    (void) expandOk;
     return a == b ? TrueVal : FalseVal;
 }
 
@@ -810,12 +812,21 @@ ValueHash (Value v)
 static Value
 UnitEqual (Value av, Value bv, int expandOk)
 {
+    (void) av;
+    (void) bv;
+    (void) expandOk;
     return TrueVal;
 }
 
 static Bool
 UnitPrint (Value f, Value av, char format, int base, int width, int prec, int fill)
 {
+    (void) av;
+    (void) format;
+    (void) base;
+    (void) width;
+    (void) prec;
+    (void) fill;
     FilePuts (f, "<>");
     return True;
 }
@@ -823,7 +834,7 @@ UnitPrint (Value f, Value av, char format, int base, int width, int prec, int fi
 ValueRep UnitRep = {
     { 0, 0, "UnitRep" },	    /* data */
     rep_void,	    /* tag */
-    { 
+    {
 	0,	    /* Plus */
 	0,	    /* Minus */
 	0,	    /* Times */
@@ -853,12 +864,18 @@ NewVoid (void)
 static Value
 BoolEqual (Value av, Value bv, int expandOk)
 {
+    (void) expandOk;
     return (av == TrueVal) == (bv == TrueVal) ? TrueVal : FalseVal;
 }
 
 static Bool
 BoolPrint (Value f, Value av, char format, int base, int width, int prec, int fill)
 {
+    (void) format;
+    (void) base;
+    (void) width;
+    (void) prec;
+    (void) fill;
     FilePuts (f, av == TrueVal ? "true" : "false");
     return True;
 }
@@ -866,7 +883,7 @@ BoolPrint (Value f, Value av, char format, int base, int width, int prec, int fi
 ValueRep BoolRep = {
     { 0, 0, "BoolRep" },	    /* data */
     rep_bool,	    /* tag */
-    { 
+    {
 	0,	    /* Plus */
 	0,	    /* Minus */
 	0,	    /* Times */
@@ -907,12 +924,12 @@ DataCacheMark (void *object)
 
 static DataType DataCacheType = { DataCacheMark, 0, "DataCacheType" };
 
-DataCachePtr 
+DataCachePtr
 NewDataCache (int size)
 {
     ENTER ();
     DataCachePtr   dc;
-    dc = (DataCachePtr) MemAllocate (&DataCacheType, 
+    dc = (DataCachePtr) MemAllocate (&DataCacheType,
 				      sizeof (DataCache) +
 				      size * sizeof (void *));
     dc->size = size;
diff --git a/value.h b/value.h
index 77a79b2..2ac1d5e 100644
--- a/value.h
+++ b/value.h
@@ -989,7 +989,7 @@ static inline Value BoxValueGet(Box *box, long e) {
 	return BoxElements(box)[e];
 }
 
-static inline Bool BoxConstant(Box *box, int e) {
+static inline Bool BoxConstant(Box *box) {
 	return box->constant;
 }
 
@@ -1098,7 +1098,7 @@ static inline TypePtr RefType (Value r) {
 }
 
 static inline Bool RefConstant(Value r) {
-	return BoxConstant(r->ref.box, r->ref.element);
+	return BoxConstant(r->ref.box);
 }
 
 Value	NewInteger (Sign sign, Natural *mag);
commit 3ffd064f07f8c492f545808a05c4a3738ad25910
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Oct 28 21:04:31 2024 -0700

    Clean up compiler warnings
    
    Lots of missing fall through annotations and a few bugs.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/builtin-command.c b/builtin-command.c
index 42c094c..833e6c9 100644
--- a/builtin-command.c
+++ b/builtin-command.c
@@ -18,7 +18,7 @@
 NamespacePtr CommandNamespace;
 
 void
-import_Command_namespace()
+import_Command_namespace(void)
 {
     ENTER ();
     static const struct fbuiltin_1 funcs_1[] = {
diff --git a/builtin-date.c b/builtin-date.c
index f29431f..db0e343 100644
--- a/builtin-date.c
+++ b/builtin-date.c
@@ -59,6 +59,7 @@ value_bool(Value s, Atom member, char *error, int def)
     return BoolPart(mem, error);
 }
 
+#ifdef HAVE_STRUCT_TM_TM_ZONE
 static const char *
 value_string(Value s, Atom member, char *error, const char *def)
 {
@@ -74,6 +75,7 @@ value_string(Value s, Atom member, char *error, const char *def)
 
     return StrzPart(mem, error);
 }
+#endif
 
 static Value
 to_date(struct tm *tm)
@@ -201,7 +203,7 @@ make_typedef (char	*name_str,
 }
 
 void
-import_Date_namespace()
+import_Date_namespace(void)
 {
     ENTER ();
     static const struct fbuiltin_1 funcs_1[] = {
diff --git a/builtin-debug.c b/builtin-debug.c
index 86c7839..1e6da25 100644
--- a/builtin-debug.c
+++ b/builtin-debug.c
@@ -23,7 +23,7 @@ do_Debug_dump_active (void);
 #endif
     
 void
-import_Debug_namespace()
+import_Debug_namespace(void)
 {
     ENTER ();
     static const struct fbuiltin_0 funcs_0[] = {
diff --git a/builtin-environ.c b/builtin-environ.c
index a4f965e..cd058f8 100644
--- a/builtin-environ.c
+++ b/builtin-environ.c
@@ -18,7 +18,7 @@
 NamespacePtr EnvironNamespace;
 
 void
-import_Environ_namespace()
+import_Environ_namespace(void)
 {
     ENTER ();
     static const struct fbuiltin_1 funcs_1[] = {
diff --git a/builtin-file.c b/builtin-file.c
index f70c267..577c1d7 100644
--- a/builtin-file.c
+++ b/builtin-file.c
@@ -21,7 +21,7 @@
 NamespacePtr FileNamespace;
 
 void
-import_File_namespace()
+import_File_namespace(void)
 {
     ENTER ();
     static const struct fbuiltin_0 funcs_0[] = {
diff --git a/builtin-foreign.c b/builtin-foreign.c
index fbc1dc4..664d573 100644
--- a/builtin-foreign.c
+++ b/builtin-foreign.c
@@ -71,7 +71,7 @@ do_Foreign_load (Value av)
 #endif
 
 void
-import_Foreign_namespace()
+import_Foreign_namespace(void)
 {
     ENTER ();
     static const struct fbuiltin_1 funcs_1[] = {
diff --git a/builtin-math.c b/builtin-math.c
index 5414d0d..46aefa7 100644
--- a/builtin-math.c
+++ b/builtin-math.c
@@ -18,7 +18,7 @@
 NamespacePtr MathNamespace;
 
 void
-import_Math_namespace()
+import_Math_namespace(void)
 {
     ENTER ();
     static const struct fbuiltin_1 funcs_1[] = {
diff --git a/builtin-semaphore.c b/builtin-semaphore.c
index 2ecc1b7..d05a188 100644
--- a/builtin-semaphore.c
+++ b/builtin-semaphore.c
@@ -18,7 +18,7 @@
 NamespacePtr SemaphoreNamespace;
 
 void
-import_Semaphore_namespace()
+import_Semaphore_namespace(void)
 {
     ENTER ();
     static const struct fbuiltin_1 funcs_1[] = {
diff --git a/builtin-sockets.c b/builtin-sockets.c
index 88ca1d8..d77f933 100644
--- a/builtin-sockets.c
+++ b/builtin-sockets.c
@@ -39,7 +39,7 @@ Value do_Socket_gethostname (void);
 Value do_Socket_getsockname (Value s);
 
 void
-import_Socket_namespace()
+import_Socket_namespace(void)
 {
     ENTER ();
 
diff --git a/builtin-string.c b/builtin-string.c
index f62ea29..fdee773 100644
--- a/builtin-string.c
+++ b/builtin-string.c
@@ -18,7 +18,7 @@
 NamespacePtr StringNamespace;
 
 void
-import_String_namespace()
+import_String_namespace(void)
 {
     ENTER ();
     static const struct fbuiltin_1 funcs_1[] = {
diff --git a/builtin-thread.c b/builtin-thread.c
index 9885746..cfd722c 100644
--- a/builtin-thread.c
+++ b/builtin-thread.c
@@ -18,7 +18,7 @@
 NamespacePtr ThreadNamespace;
 
 void
-import_Thread_namespace()
+import_Thread_namespace(void)
 {
     ENTER ();
     static const struct fbuiltin_0 funcs_0[] = {
diff --git a/builtin-toplevel.c b/builtin-toplevel.c
index 6a482da..946e234 100644
--- a/builtin-toplevel.c
+++ b/builtin-toplevel.c
@@ -16,7 +16,7 @@
 #include	"builtin.h"
 
 void
-import_Toplevel_namespace()
+import_Toplevel_namespace(void)
 {
     ENTER ();
     static const struct fbuiltin_0 funcs_0[] = {
@@ -326,6 +326,7 @@ do_string_to_integer (int n, Value *p)
 	case 8:
 	    if (!strncmp (s, "0o", 2) ||
 		!strncmp (s, "0O", 2)) s += 2;
+	    break;
 	case 10:
 	    if (!strncmp (s, "0t", 2) ||
 		!strncmp (s, "0T", 2)) s += 2;
diff --git a/builtin.c b/builtin.c
index 701999a..1c1bbed 100644
--- a/builtin.c
+++ b/builtin.c
@@ -201,7 +201,8 @@ BuiltinType (char *format, Type **type, Bool arg)
 	t = typeUserdef[i];
 	if (t)
 	    break;
-    default: 
+	__NICKLE_FALLTHROUGH;
+    default:
 	t = 0;
 	i = write (2, "Invalid builtin argument type\n", 30);
 	(void) i;
diff --git a/compile.c b/compile.c
index 37f5949..1ae4968 100644
--- a/compile.c
+++ b/compile.c
@@ -504,7 +504,7 @@ isName:
 		expr->base.type = typePoly;
 		break;
 	    }
-	    /* fall through ... */
+	    __NICKLE_FALLTHROUGH;
 	case class_global:
 	    BuildInst (obj, OpGlobalRef, inst, stat);
 	    inst->box.box = s->global.value;
@@ -619,6 +619,7 @@ isName:
 	    obj = CompileCall (obj, expr, TailNever, stat, code, True);
 	    break;
 	}
+	break;
     default:
 	if (auto_reference)
 	{
diff --git a/execute.c b/execute.c
index 9e73be9..6db11aa 100644
--- a/execute.c
+++ b/execute.c
@@ -468,7 +468,7 @@ ThreadArrayInit (Value thread, Value value, AInitMode mode,
 	array = Stack(ndim+1);
 	if (ValueInt(Stack(dim+1)) == ArrayDims(&array->array)[dim])
 	    break;
-	/* fall through ... */
+	__NICKLE_FALLTHROUGH;
     case AInitModeElement:
         ndim = ValueInt(Stack(0));
 	array = Stack(ndim+1);
@@ -1165,7 +1165,7 @@ ThreadsRun (Value thread, Value lex)
 		    break;
 		case OpReturnVoid:
 		    value = Void;
-		    /* fall through */
+		    __NICKLE_FALLTHROUGH;
 		case OpReturn:
 		    if (!thread->thread.continuation.frame)
 		    {
@@ -1195,7 +1195,7 @@ ThreadsRun (Value thread, Value lex)
 		    break;
 		case OpGlobalRef:
 		    ThreadBoxCheck (inst->box.box, 0);
-		    /* fall through... */
+		    __NICKLE_FALLTHROUGH;
 		case OpGlobalRefStore:
 		    value = NewRef (inst->box.box, 0);
 		    break;
@@ -1344,7 +1344,7 @@ ThreadsRun (Value thread, Value lex)
 			break;
 		    }
 		    value = RefValueGet(value);
-		    /* fall through ... */
+		    __NICKLE_FALLTHROUGH;
 		case OpDot:
 		case OpDotRef:
 		case OpDotRefStore:
diff --git a/file.c b/file.c
index bb933f5..cce24f0 100644
--- a/file.c
+++ b/file.c
@@ -460,7 +460,7 @@ sigchld (int sig)
 }
 
 void
-ProcessInterrupt ()
+ProcessInterrupt (void)
 {
     for (;;) {
 	pid_t		pid;
@@ -1391,6 +1391,7 @@ FilePutString (Value f, char *string, long length, char format)
 		    break;
 		case '\v':
 		    FilePuts (f, "\\v");
+		    break;
 		case '\0':
 		    FilePuts (f, "\\0");
 		    break;
diff --git a/gram.y b/gram.y
index 7edf07d..ecd7ba3 100644
--- a/gram.y
+++ b/gram.y
@@ -1915,11 +1915,11 @@ ParseCanonType (TypePtr type, Bool forwardAllowed)
     int		    n;
     CanonTypeResult ret = CanonTypeDefined, t;
     Bool	    anyResolved;
-    
+
     if (!type)
     {
 	ParseError ("Type missing inside compiler");
-	return False;
+	return CanonTypeUndefined;
     }
     switch (type->base.tag) {
     case type_prim:
diff --git a/lex.l b/lex.l
index d228d95..1957d05 100644
--- a/lex.l
+++ b/lex.l
@@ -19,6 +19,12 @@
 #endif
 #endif
     
+#ifdef __GNUC__
+#pragma GCC diagnostic ignored "-Wpragmas"
+#pragma GCC diagnostic ignored "-Wunknown-warning-option"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#endif
+
 typedef struct _lexInput {
     DataType		data;
     struct _lexInput	*next;
@@ -844,9 +850,11 @@ aetov (char *s)
 	case 'o':
 	    base = 8;
 	    s += 2;
+	    break;
 	case 'b':
 	    base = 2;
 	    s += 2;
+	    break;
 	}
     }
 
diff --git a/nickle.h b/nickle.h
index b6e8b85..f65cb69 100644
--- a/nickle.h
+++ b/nickle.h
@@ -1022,3 +1022,16 @@ Value	do_hash_del (Value, Value);
 Value	do_hash_test (Value, Value);
 Value	do_hash_set (Value, Value, Value);
 Value	do_hash_keys (Value);
+
+/*
+ * fall-through case statement annotations
+ */
+#if __cplusplus >= 201703L || __STDC_VERSION__ > 201710L
+/* Standard C++17/C23 attribute */
+#define __NICKLE_FALLTHROUGH [[fallthrough]]
+#elif __has_attribute(fallthrough)
+/* Non-standard but supported by at least gcc and clang */
+#define __NICKLE_FALLTHROUGH __attribute__((fallthrough))
+#else
+#define __NICKLE_FALLTHROUGH do { } while(0)
+#endif
diff --git a/pretty.c b/pretty.c
index d6cb503..b49cda9 100644
--- a/pretty.c
+++ b/pretty.c
@@ -431,7 +431,7 @@ PrettyExpr (Value f, Expr *e, int parentPrec, int level, Bool nest)
     case POW:
     case ASSIGNPOW:
 	e = e->tree.right;
-	/* fall through */
+	__NICKLE_FALLTHROUGH;
     case PLUS:
     case MINUS:
     case TIMES:
@@ -752,7 +752,7 @@ PrettyStatement (Value f, Expr *e, int level, int blevel, Bool nest)
 	break;
     case TYPEDEF:
 	e = e->tree.left;
-	/* fall through */
+	__NICKLE_FALLTHROUGH;
     case VAR:
 	PrettyIndent (f, e, level);
 	PrettyDecl (f, e, level, nest);
diff --git a/profile.c b/profile.c
index cd0e1de..15876c4 100644
--- a/profile.c
+++ b/profile.c
@@ -10,7 +10,7 @@
 
 #define TICK_MS	10
 
-volatile static unsigned long	currentTick;
+static volatile unsigned long	currentTick;
 volatile Bool			signalProfile;
 static unsigned long		previousTick;
 Bool				profiling;
diff --git a/rational.c b/rational.c
index 1729db7..1e4f96d 100644
--- a/rational.c
+++ b/rational.c
@@ -199,6 +199,7 @@ RationalLess (Value av, Value bv, int expandOk)
 	t = a;
 	a = b;
 	b = t;
+	__NICKLE_FALLTHROUGH;
     case BothPositive:
 	if (!NaturalEqual (a->den, b->den))
 	    ret = NaturalLess (NaturalTimes (a->num, b->den),
diff --git a/ref.c b/ref.c
index da379c8..d199553 100644
--- a/ref.c
+++ b/ref.c
@@ -120,6 +120,7 @@ RefTypeCheck (BinaryOp op, Value av, Value bv, int expandOk)
     case MinusOp:
 	if (ValueIsRef(av) && ValueIsRef(bv))
 	    return av->value.type;
+	__NICKLE_FALLTHROUGH;
     case PlusOp:
 	if (ValueIsInt(av))
 	    return bv->value.type;
diff --git a/symbol.c b/symbol.c
index 47e58b2..08cae9a 100644
--- a/symbol.c
+++ b/symbol.c
@@ -208,6 +208,6 @@ NewSymbolNamespace (Atom name, NamespacePtr namespace)
 }
 
 void
-SymbolInit ()
+SymbolInit (void)
 {
 }
diff --git a/type.c b/type.c
index 5ba9fa7..60c62ab 100644
--- a/type.c
+++ b/type.c
@@ -1020,7 +1020,7 @@ TypeCombineBinary (Type *left, int tag, Type *right)
     case ASSIGNPLUS:
 	if ((type = TypeBinaryString (left, right)))
 	    ret = TypeAdd (ret, type);
-	/* fall through ... */
+	__NICKLE_FALLTHROUGH;
     case MINUS:
     case ASSIGNMINUS:
 	if ((type = TypeBinaryRefOff (left, right)))
@@ -1030,7 +1030,7 @@ TypeCombineBinary (Type *left, int tag, Type *right)
 	if ((tag == MINUS || tag == PLUS) && 
 	    (type = TypeBinaryRefOff (right, left)))
 	    ret = TypeAdd (ret, type);
-	/* fall through ... */
+	__NICKLE_FALLTHROUGH;
     case TIMES:
     case MOD:
     case ASSIGNTIMES:
@@ -1376,6 +1376,7 @@ TypeCompatibleAssign (TypePtr a, Value b)
 		return (TypeIsOrdered (a->hash.type, b->hash.type) &&
 		        TypeIsOrdered (a->hash.keyType, b->hash.keyType));
 	}
+	break;
     case type_struct:
     case type_union:
 	if ((ValueIsStruct(b) && a->base.tag == type_struct) ||
@@ -1527,6 +1528,7 @@ ValueIsType (Value b, TypePtr a)
 		return (TypeIsSupertype (b->hash.type, a->hash.type) &&
 		        TypeIsSupertype (b->hash.keyType, a->hash.keyType));
 	}
+	break;
     case type_struct:
     case type_union:
 	if ((ValueIsStruct(b) && a->base.tag == type_struct) ||
commit b6f75398fd6484177f897033093e8ea4eebbc32c
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Oct 28 19:21:04 2024 -0700

    Switch from #if to #ifdef
    
    meson doesn't set config variables to 1
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/builtin-environ.c b/builtin-environ.c
index 9176984..a4f965e 100644
--- a/builtin-environ.c
+++ b/builtin-environ.c
@@ -92,11 +92,11 @@ do_Environ_unset (Value av)
 {
     ENTER ();
     char    *name = StrzPart (av, "invalid environment variable name");
-    
+
     if (!name)
 	RETURN (Void);
-    
-#if HAVE_UNSETENV
+
+#ifdef HAVE_UNSETENV
     if (getenv (name))
     {
 	unsetenv (name);
@@ -115,11 +115,11 @@ do_Environ_set (Value name, Value value)
 
     if (!n || !v)
 	RETURN (Void);
-#if HAVE_SETENV
+#ifdef HAVE_SETENV
     if (setenv (n, v, 1) >= 0)
 	RETURN (TrueVal);
 #else
-#if HAVE_PUTENV
+#ifdef HAVE_PUTENV
     {
 	Value	binding = Plus (name,
 				Plus (NewStrString ("="),
diff --git a/builtin-foreign.c b/builtin-foreign.c
index be5a392..fbc1dc4 100644
--- a/builtin-foreign.c
+++ b/builtin-foreign.c
@@ -12,9 +12,9 @@
 
 NamespacePtr	ForeignNamespace;
 
-#if HAVE_EXTERN_SYMS
+#ifdef HAVE_EXTERN_SYMS
 
-#if HAVE_DLFCN_H && HAVE_DLOPEN && HAVE_DLSYM
+#if defined(HAVE_DLFCN_H) && defined(HAVE_DLOPEN) && defined(HAVE_DLSYM)
 #define HAVE_FOREIGN_LOAD 1
 #include	<dlfcn.h>
 
@@ -29,13 +29,13 @@ do_Foreign_load (Value av)
 
     if (!name)
 	RETURN (Void);
-    
+
     lib = dlopen (name, RTLD_NOW);
     if (!lib)
     {
 	char	*err = 0;
 	int	e = errno;
-#if HAVE_DLERROR
+#ifdef HAVE_DLERROR
 	err = dlerror ();
 #endif
 	if (!err)
@@ -46,19 +46,19 @@ do_Foreign_load (Value av)
 				av);
 	RETURN (Void);
     }
-    
+
     init = (Value (*) (void)) dlsym (lib, "nickle_init");
     if (!init)
     {
 	char	*err = 0;
-#if HAVE_DLERROR
+#ifdef HAVE_DLERROR
 	err = dlerror ();
 #endif
 	if (!err)
 	    err = "missing nickle_init";
 	RaiseStandardException (exception_open_error, 3,
 				NewStrString (err), NewInt (0), av);
-#if HAVE_DLCLOSE
+#ifdef HAVE_DLCLOSE
 	dlclose (lib);
 #endif
 	RETURN (Void);
@@ -75,7 +75,7 @@ import_Foreign_namespace()
 {
     ENTER ();
     static const struct fbuiltin_1 funcs_1[] = {
-#if HAVE_EXTERN_SYMS && HAVE_FOREIGN_LOAD
+#if defined(HAVE_EXTERN_SYMS) && defined(HAVE_FOREIGN_LOAD)
 	{ do_Foreign_load, "load", "b", "s", "\n"
 	    " bool load (string name)\n"
 	    "\n"
diff --git a/compile.c b/compile.c
index 7d7bc59..37f5949 100644
--- a/compile.c
+++ b/compile.c
@@ -4515,7 +4515,7 @@ InstDump (InstPtr inst, int indent, int i, int *branch, int maxbranch)
     Bool    realBranch = False;
     
 #ifdef DEBUG
-    FilePrintf (FileStdout, "%x: ", (int) inst);
+    FilePrintf (FileStdout, "%p: ", inst);
 #endif
     ObjIndent (indent);
     FilePrintf (FileStdout, "%s%s %c ",
diff --git a/hash.c b/hash.c
index 32402c6..70335d5 100644
--- a/hash.c
+++ b/hash.c
@@ -138,7 +138,7 @@ Resize (HashTablePtr ht, const HashSetPtr hs)
     EXIT ();
 }
 
-#if HAVE_STDINT_H
+#ifdef HAVE_STDINT_H
 typedef uint32_t	crc32_t;
 #else
 typedef unsigned int	crc32_t;
diff --git a/lex.l b/lex.l
index e3d9878..d228d95 100644
--- a/lex.l
+++ b/lex.l
@@ -111,11 +111,11 @@ LexInit (void)
 {
     ENTER ();
 
-#if HAVE_LIBREADLINE
+#ifdef HAVE_LIBREADLINE
     rl_getc_function = ReadlineGetChar;
     rl_prep_term_function = (void *) my_prep_terminal;
     rl_deprep_term_function = my_deprep_terminal;
-#if HAVE_RL_CATCH_SIGNALS
+#ifdef HAVE_RL_CATCH_SIGNALS
     rl_catch_signals = 0;
 #endif
 #endif
diff --git a/main.c b/main.c
index 0787bee..f10d4d7 100644
--- a/main.c
+++ b/main.c
@@ -10,24 +10,24 @@
  *	main routine for nick
  */
 
+#define __USE_UNIX98 /* Get sigignore() and sigrelse()
+			prototype for Linux */
 #include	"nickle.h"
 #include	"gram.h"
 
 #include	<setjmp.h>
-#define __USE_UNIX98 /* Get sigignore() and sigrelse()
-			prototype for Linux */
 #include	<signal.h>
 #include	<stdio.h>
 
-#if HAVE_SYS_TIME_H
+#ifdef HAVE_SYS_TIME_H
 #include	<sys/time.h>
 #endif
 
-#if HAVE_SYS_RESOURCE_H
+#ifdef HAVE_SYS_RESOURCE_H
 #include	<sys/resource.h>
 #endif
 
-#if HAVE_LIBREADLINE
+#ifdef HAVE_LIBREADLINE
 #include READLINE_H
 #endif
 
@@ -43,7 +43,7 @@ setArgv (int argc, char **argv)
     args = NewArray (True, True, typePrim[rep_string], 1, &argc);
     for (i = 0; i < argc; i++)
 	ArrayValueSet (&args->array, i, NewStrString (argv[i]));
-    setVar (GlobalNamespace, "argv", args, 
+    setVar (GlobalNamespace, "argv", args,
 	    NewTypeArray (typePrim[rep_string],
 			   NewExprTree (COMMA, 0, 0), False));
     EXIT ();
@@ -57,7 +57,7 @@ try_nicklestart (void)
     if ((nicklestart = getenv ("NICKLESTART")) == 0)
 	nicklestart = NICKLELIBDIR "/builtin.5c";
     return LexFile (nicklestart, True, False);
-}    
+}
 
 void	intr(int), ferr(int);
 void	stop (int), die (int), segv (int);
@@ -76,7 +76,7 @@ releaseSignal(int sig) {
 int
 main (int argc, char **argv)
 {
-#if HAVE_GETRLIMIT && HAVE_SETRLIMIT
+#if defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT)
     /*
      * Allow stack to grow as large as possible to avoid
      * crashes during recursive datastructure marking in the
@@ -163,7 +163,7 @@ intr (int sig)
     if (signalInterrupt) {
 	int ret = write(2,"Double interrupt, exiting\n", 26);
 	(void) ret;
-#if HAVE_RL_CLEANUP_AFTER_SIGNAL
+#ifdef HAVE_RL_CLEANUP_AFTER_SIGNAL
 	if (stdin_in_readline)
 	    rl_cleanup_after_signal();
 #endif
@@ -178,10 +178,10 @@ stop (int sig)
     sigset_t	set, oset;
 
     if (stdin_in_readline) {
-#if HAVE_RL_ECHO_SIGNAL_CHAR
+#ifdef HAVE_RL_ECHO_SIGNAL_CHAR
 	rl_echo_signal_char(sig);
 #endif
-#if HAVE_RL_CLEANUP_AFTER_SIGNAL
+#ifdef HAVE_RL_CLEANUP_AFTER_SIGNAL
 	rl_cleanup_after_signal();
 #endif
     }
@@ -199,7 +199,7 @@ stop (int sig)
     catchSignal (sig, stop);
     IoStart ();
 
-#if HAVE_RL_RESET_AFTER_SIGNAL
+#ifdef HAVE_RL_RESET_AFTER_SIGNAL
     if (stdin_in_readline)
 	rl_reset_after_signal();
 #endif
@@ -209,10 +209,10 @@ void
 die (int sig)
 {
     if (stdin_in_readline) {
-#if HAVE_RL_FREE_LINE_STATE
+#ifdef HAVE_RL_FREE_LINE_STATE
 	rl_free_line_state();
 #endif
-#if HAVE_RL_CLEANUP_AFTER_SIGNAL
+#ifdef HAVE_RL_CLEANUP_AFTER_SIGNAL
 	rl_cleanup_after_signal();
 #endif
     }
@@ -224,7 +224,7 @@ void
 segv (int sig)
 {
     IoStop ();
-#if HAVE_RL_CLEANUP_AFTER_SIGNAL
+#ifdef HAVE_RL_CLEANUP_AFTER_SIGNAL
     if (stdin_in_readline)
 	rl_cleanup_after_signal();
 #endif
diff --git a/memp.h b/memp.h
index aa3b7f0..db8b946 100644
--- a/memp.h
+++ b/memp.h
@@ -25,7 +25,7 @@
 
 # define GARBAGETIME	1000
 
-#if HAVE_STDINT_H
+#ifdef HAVE_STDINT_H
 #include	<stdint.h>
 #define PtrToInt(p)	((int) (intptr_t) (p))
 typedef intptr_t	IntPtr;
diff --git a/nickle.h b/nickle.h
index fcfd7e1..b6e8b85 100644
--- a/nickle.h
+++ b/nickle.h
@@ -4,7 +4,7 @@
  * for licensing information.
  */
 
-#if LOCAL_BUILD
+#ifdef LOCAL_BUILD
 #include	"nickle-config.h"
 #include	"mem.h"
 #include	"value.h"
@@ -759,7 +759,7 @@ Bool	LexInteractive (void);
 Bool	LexResetInteractive (void);
 void	LexInit (void);
 void	NewLexInput (Value file, Atom name, Bool after, Bool interactive);
-#if HAVE_LIBREADLINE
+#ifdef HAVE_LIBREADLINE
 extern volatile int stdin_in_readline;
 #endif
 
diff --git a/value.h b/value.h
index 4700485..77a79b2 100644
--- a/value.h
+++ b/value.h
@@ -64,7 +64,7 @@ AtomListPtr  NewAtomList (AtomListPtr next, Atom atom);
  * still work correctly.
  */
 
-#if HAVE_STDINT_H
+#ifdef HAVE_STDINT_H
 
 # include <stdint.h>
 
@@ -73,7 +73,7 @@ AtomListPtr  NewAtomList (AtomListPtr next, Atom atom);
 #define IntToPtr(i)	((void *) (intptr_t) (i))
 #define UIntToPtr(u)	((void *) (uintptr_t) (u))
 
-# if HAVE_UINT64_T
+# ifdef HAVE_UINT64_T
 
 /*
  * If stdint.h defines a 64 bit datatype, use 32 bit
commit bffe58e7fbd650b27196a1126563391aec59a569
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Oct 28 15:03:54 2024 -0700

    Add Sort::gnomesort
    
    A variation of insertion sort without nested loops.
    See: https://en.wikipedia.org/wiki/Gnome_sort
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/sort.5c b/sort.5c
index 7844135..6c715dd 100644
--- a/sort.5c
+++ b/sort.5c
@@ -7,7 +7,7 @@
 autoload PRNG;
 
 namespace Sort {
-    
+
     /*
      * Quicksort with random pivot
      */
@@ -19,13 +19,13 @@ namespace Sort {
 		void exchange (int i, int j) {
 		    poly t = a[i]; a[i] = a[j]; a[j] = t;
 		}
-    
+
 		/* partition the array into two pieces and return the pivot */
 		int partition (int p, int r) {
 		    /* select a random element to pivot */
 		    int pivot = p + PRNG::randint(r-p);
 		    exchange (pivot, r);
-		    
+
 		    poly x = a[r];
 		    int i = p;
 		    for (int j = p; j < r; j++)
@@ -39,16 +39,16 @@ namespace Sort {
 		    exchange (i, r);
 		    return i;
 		}
-		
+
 		int q = partition (p, r);
 		quicksort (p, q-1);
 		quicksort (q+1, r);
 	    }
 	}
-    
+
 	quicksort (0, dim(a)-1);
     }
-    
+
     /*
      * Mergesort
      */
@@ -65,13 +65,13 @@ namespace Sort {
 		    poly[n1] L;
 		    for (int i = 0; i < n1; i++)
 			L[i] = a[p+i];
-		    
+
 		    /* temporary storage for right half of array */
 		    int n2 = r - q;
 		    poly[n2] R;
 		    for (int i = 0; i < n2; i++)
 			R[i] = a[q+i+1];
-    
+
 		    /* merge two halves back into main array */
 		    int i = 0, j = 0, k = p;
 		    while (i < n1 && j < n2)
@@ -81,7 +81,7 @@ namespace Sort {
 		    while (j < n2)
 			a[k++] = R[j++];
 		}
-		
+
 		int q = (p + r) // 2;
 		msort (p, q);
 		msort (q+1, r);
@@ -90,7 +90,23 @@ namespace Sort {
 	}
 	msort (0, dim(a)-1);
     }
-	
+
+    public void gnomesort(&poly[*] a, bool(poly, poly) gt)
+    {
+	int l = dim(a);
+	int pos = 0;
+	while (pos < l) {
+	    if (pos == 0 || !gt(a[pos-1], a[pos])) {
+		pos = pos + 1;
+	    } else {
+		poly t = a[pos];
+		a[pos] = a[pos-1];
+		a[pos-1] = t;
+		pos = pos - 1;
+	    }
+	}
+    }
+
     protected int[*] randomints (int n, int max) =
 	(int[n]) { [i] = PRNG::randint(max) };
 }
diff --git a/test/sorttest.5c b/test/sorttest.5c
index 255d211..5aa5fb4 100644
--- a/test/sorttest.5c
+++ b/test/sorttest.5c
@@ -32,8 +32,11 @@ for (int i = 0; i < 100; i++) {
     real[*] v = Sort::randomints(len, 1000000);
     real[*] qv = v;
     real[*] mv = v;
+    real[*] gv = v;
     Sort::qsort(&qv, int_gt);
     check(&qv, "qsort");
     Sort::mergesort(&mv, int_gt);
     check(&mv, "mergesort");
+    Sort::gnomesort(&gv, int_gt);
+    check(&gv, "gnomesort");
 }


More information about the Nickle mailing list