Compare commits

...

10 Commits

Author SHA1 Message Date
Jan Nieuwenhuizen 6b4a0ed8a2
core: Support string-set!
* src/string.c (string_set_x): New function.
* src/mes.c (mes_builtins): Add it.
* include/mes/builtins.h: Declare it.
* mes/module/mes/scm.mes (string-set!): Remove broken implementation.
2019-12-29 22:55:03 +01:00
Jan Nieuwenhuizen bafe4c81ef
Support generating Nyacc tables. WIP
* mes/module/nyacc/lang/c99/cppmach.mes: New file.
* mes/module/nyacc/lang/c99/mach.mes: New file.
* mes/module/nyacc/lang/lalr.mes: Resurrect.
* module/mes/pretty-print.scm: Rename from
mes/module/mes/pretty-print.scm.
2019-12-29 22:53:48 +01:00
Jan Nieuwenhuizen fdcdead857
doc: Release update.
* BOOTSTRAP: Release update.
* HACKING: Likewise.
* INSTALL: Likewise.
* NEWS: Likewise.
* PORTING: Likewise.
* README: Likewise.
* ROADMAP: Likewise.
* doc/mes.texi: Likewise.
2019-12-29 14:33:30 +01:00
Jan Nieuwenhuizen cca07aff2b
mescc: Mes C Library: Fix execlp, execvp for file names with slash.
Reported by mid-kid.

* lib/posix/execlp.c (execlp): Do not use search_path when file name
contains a slash (WAS: when file name starts with slash).
* lib/posix/execvp.c (execvp): Likewise.
2019-12-29 14:33:10 +01:00
Jan Nieuwenhuizen 575c177817
build: Support bootstrapping using build.sh.
* build-aux/build.sh.in: Oops, use $compiler = bootstrap concept does
not exist yet.  Gash cp does not support -p; drop it.
* configure.sh: Oops, set bootstrap to `true' instead of yes.
2019-12-19 09:11:14 +01:00
Jan Nieuwenhuizen 6a9154cd67
mescc: Mes C Library: lseek: Be careful clearing read buffer.
* lib/linux/lseek.c (_lseek): New function.
* lib/linux/lseek.c (lseek): Use it to check if we should reset read
buffer.
* lib/mes/__buffered_read.c (__read_buffer_max): New variable.
(__buffered_read_init): Add environment override: MES_READ_BUFFER.
(__buffered_read): Use it.
2019-12-19 07:14:35 +01:00
Jan Nieuwenhuizen 709176b247
build: Have configure respect GUILE_LOAD_PATH for mes to find Nyacc.
* configure: Substitute GUILE_LOAD_PATH from %load-path.
* configure.sh: Likewise.
* build-aux/config.make.in: Add GUILE_LOAD_PATH as subtitution variable.
* build-aux/config.sh.in: Likewise.
* mes/module/mes/guile.mes (%load-path): New variable.
2019-12-17 21:08:19 +01:00
Jan Nieuwenhuizen e7f151e126
build: Have configure prefer $CC over gcc; tcc over gcc, gcc over cc.
Reported by Vagrant Cascadian.

* configure (string->version): Prefer for most-dotted string.  Fixes
makeinfo version.
(check-program-version): Prefer displaying of command, if single word.
(main): Check for $CC --version, $CC -v.  Prefer $CC over gcc; tcc over
gcc, gcc over cc.
2019-12-17 21:08:18 +01:00
Jan Nieuwenhuizen b834c7877a
mescc: Opt for reproducible builds with Guile and MES.
* module/mescc/compile.scm (mes-or-reproducible?): New variable.
(ast->comment): Use it.
* module/mescc/preprocess.scm (mes-or-reproducible?): New variable.
(c99-input->full-ast): Use it.
2019-12-17 21:08:18 +01:00
Jan Nieuwenhuizen b041861c26
build: Resurrect compiling with TinyCC.
./configure CC=tcc --host=i686-unknown-linux-gnu --with-courage

* configure: Cater for tcc.
2019-12-17 21:08:18 +01:00
32 changed files with 583 additions and 204 deletions

View File

@ -8,24 +8,24 @@ Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
notice and this notice are preserved.
* What?
** Full source bootstrapping for GNU Guix
** Full source bootstrapping for the GNU System
A package in Guix is uniquely identified by the hash of its source code,
its dependencies, and its build recipe.
A package in GNU Guix is uniquely identified by the hash of its source
code, its dependencies, and its build recipe.
Every package can be built from source, except for the bootstrap
binaries.
*** From the Guix manual
*** From the GNU Guix manual
The distribution is fully “bootstrapped” and “self-contained”: each
The distribution is fully “bootstrapped” and “self-contained”: each
package is built based solely on other packages in the distribution.
The root of this dependency graph is a small set of “bootstrap
binaries”, provided by the (gnu packages bootstrap) module. For more
information on bootstrapping, *note Bootstrapping::.
**** Guix bootstrap tarballs
**** Guix v1.0 bootstrap binary seed
$ du -schx $(readlink $(guix build bootstrap-tarballs)/*)
2.1M /gnu/store/9623n4bq6iq5c8cwwdq99qb7d0xj93ym-binutils-static-stripped-tarball-2.28.1/binutils-static-stripped-2.28.1-x86_64-linux.tar.xz
@ -44,6 +44,42 @@ $ du -schx *
5.2M share
252M total
**** Guix Reduced Binary Seed bootstrap binary seed
$ du -schx $(readlink $(guix build bootstrap-tarballs)/*)
5.7M /gnu/store/9f8gi8raqfx9j3l9d00qrrc0jg3r1kyj-guile-static-stripped-tarball-2.2.6/guile-static-stripped-2.2.6-x86_64-linux.tar.xz
80K /gnu/store/b6rjl52hibhmvyw4dg8678pwryhla0h2-linux-libre-headers-stripped-tarball-4.19.56/linux-libre-headers-stripped-4.19.56-x86_64-linux.tar.xz
12K /gnu/store/d7zlxsjcnqilmvqwx7scija9x9bjw8cw-mescc-tools-static-stripped-tarball-0.5.2-0.bb062b0/mescc-tools-static-stripped-0.5.2-0.bb062b0-x86_64-linux.tar.xz
428K /gnu/store/n7zc4kpi8ny6jlfaikkzxlwhc5fvr1vr-mes-minimal-stripped-tarball-0.19/mes-minimal-stripped-0.19-x86_64-linux.tar.xz
6.0M /gnu/store/nv4djwlrljfqmynqr2cqvfwz0ydx7kxb-static-binaries-tarball-0/static-binaries-0-x86_64-linux.tar.xz
13M total
$ for i in $(readlink $(guix build bootstrap-tarballs)/*);\
do sudo tar xf $i; done
Password:
$ du -schx *
93M bin
700K include
38M lib
14M share
145M total
**** Guix Scheme-only bootstrap binary seed
$ du -schx $(readlink $(~/src/guix/wip-bootstrap/pre-inst-env guix build bootstrap-tarballs)/*)
5.7M /gnu/store/1mq2pcd2h7g54xpi2jrgj6ibbi4lgi3c-guile-static-stripped-tarball-2.2.6/guile-static-stripped-2.2.6-x86_64-linux.tar.xz
80K /gnu/store/bl1r2bpk6fam8r2gjvr5mvr48i3dm2hn-linux-libre-headers-stripped-tarball-4.19.56/linux-libre-headers-stripped-4.19.56-x86_64-linux.tar.xz
12K /gnu/store/w0dlz486dhb8aiq8pxm5akllz628fqin-mescc-tools-static-stripped-tarball-0.5.2-0.bb062b0/mescc-tools-static-stripped-0.5.2-0.bb062b0-x86_64-linux.tar.xz
428K /gnu/store/15j6l18q44ymlrh1cfp4s4hc9835xic5-mes-minimal-stripped-tarball-0.19/mes-minimal-stripped-0.19-x86_64-linux.tar.xz
6.2M total
$ for i in $(readlink $(~/src/guix/wip-bootstrap/pre-inst-env guix build bootstrap-tarballs)/*);\
do sudo tar xf $i; done
$ du -schx *
4.9M bin
700K include
38M lib
14M share
57M total
* Why?
** Reproducibility is essential to Software Freedom
@ -92,20 +128,22 @@ be source.
*** mes.c: a Scheme interpreter in ~5,000LOC of simple C
*** mescc: a C compiler written in Scheme (uses Nyacc C99 parser in Scheme)
*** mes.M2: this Scheme interpreter in preprocessed M2
*** mes.M2: this Scheme interpreter in bootstrappable M2
** TinyCC
https://gitlab.com/janneke/tinycc
* TODO
** merge scheme-only bootstrap into Guix.
** reduced binary seed bootstrap into NixOS, Debian.
** remove or upstream patches from tcc-boot
** prepare src/mes.c for M2-Planet transpiler.
** ARM, the Hurd
** fix bootstrap-loops: (Nyacc?, mes.M2, psyntax.pp?)
** make GNU gcc (8.0?) bootstrappable again, remove [need for] tcc stage
* DONE
** upstream mes-boot to Guix.
** reduced binary seed bootstrap into Guix.
** replace Guix bootstrap for x86_64.
** replace Guix bootstrap for x86.
** add full source gcc-4.7 package build.
@ -121,5 +159,6 @@ be source.
** tcc compiled with gcc is known to compile gcc
* Contact
** bug-mes@gnu.org
** #bootstrappable, #guix on freenode
** bootstrappable.org

70
HACKING
View File

@ -1,64 +1,31 @@
-*- org -*-
#+TITLE: Hacking GNU Mes
Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved.
* SETUP
guix environment -l guix.scm #64 bit + 32bit
CC=i686-unkown-linux-gnu-gcc ./configure
or
./configure
guix environment --system=i686-linux -l guix.scm #32 bit only
or
guix package --profile=~/.config/guix/mes --manifest=build-aux/manifest.scm
. ~/.config/guix/mes/etc/profile
The 64bit bootstrap is not supported; MesCC needs work to be able to
compile a functional tinycc.
* BUILD
There are two major modes to build Mes: true bootstrap and
development.
** DEVELOPMENT BUILD
To help development we assume ./configure sets these variables for make
GNU Guile can be used as a replacement for Mes. It's faster and has
much better error handling.
CC -- gcc (or i686-unknown-linux-gnu-gcc sans libc)
GUILE -- guile
HEX2 -- hex2
MES -- unset
M1 -- M1
prefix -- ""
#+BEGIN_SRC bash
make MES=guile
make check MES=guile
#+END_SRC
Mes is supposed to serve as a full equivalent for Guile, however Mes
is still about 2 to 10 times slower than Guile. That's why we usually
don't use Mes during development, configure --with-cheating.
Configure to compile with Tiny CC
Gcc is used to verify the sanity of our C sources.
i686-unknown-linux-gnu-gcc is used to compare hex/assembly, to test
the gcc variant of Mes C Libirary.
Target prefix: x86-mes-gcc.
gcc -nostdinc,-nostdlib is used to compare hex/assembly, to test the
64bit variant of Mes C Library. Target prefix: x86_64-mes-gcc.
Guile is used to develop MesCC, the C compiler in Scheme that during
bootstrapping will be executed by Mes.
** BOOTSTRAP BUILD
./configure.sh [--prefix=PREFIX]
./bootstrap.sh
./install.sh
In bootstrap mode, we don't have gcc (CC), we don't have a 32 bit gcc,
we have no guile (GUILE)...but we should have hex2, M1, and mes.M1.
That's a bootstrap problem which is currently ignored by using the
mes-seed package. mes.M1 will be produced by M2-Planet from mes.c.
#+BEGIN_SRC bash
./configure CC=tcc --host=i686-unknown-linux-gnu --with-courage
#+END_SRC
* DEBUG
MES_DEBUG=<level> mes
@ -83,7 +50,7 @@ mes-seed package. mes.M1 will be produced by M2-Planet from mes.c.
* Bugs
** mes: performance, Mes is now 2-10x slower than Guile.
** mes/mescc lack support for the Hurd.
** mes/mescc lack support for fork/exec on the Hurd.
** mes: gcc-x86_64 compiled mes segfaults with small arena, or gc_up_arena.
** mes: gcc-x86 compiled, tests/srfi-13.test number->string INT-MIN fails:
test: number->string INT-MIN: fail
@ -214,3 +181,10 @@ https://notabug.org/rain1/hex86/src/master/tests/hex0b3.hex86
https://jamey.thesharps.us/2016/07/15/testing-strategies-for-corrode/
("Randomized testing with Csmith and C-Reduce") [10:58]
** linux syscalls: https://fedora.juszkiewicz.com.pl/syscalls.html
* legalese
Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved.

23
INSTALL
View File

@ -41,6 +41,19 @@ similar way.
make
#+END_SRC
If you get something like
#+BEGIN_SRC bash
mes.c:(.text+0x8da0): undefined reference to `__stack_chk_fail'
#+END_SRC
then your compiler inserts stack protection code. The Mes C Library
does not support that. Turn it off lik this
#+BEGIN_SRC bash
./configure CFLAGS=-fno-stack-protector
#+END_SRC
** Check it
#+BEGIN_SRC bash
@ -86,3 +99,13 @@ https://git.savannah.gnu.org/cgit/guix.git/tree/gnu/packages/commencement.scm
#+BEGIN_SRC bash
sh install.sh
#+END_SRC
* Regular build and bootstrap combine
To build mes.c using MesCC, configure using --with-bootstrap:
#+BEGIN_SRC bash
./configure --with-bootstrap
make
#+END_SRC
This creates bin/mes-gcc and bin/mes-mescc.

36
NEWS
View File

@ -10,6 +10,41 @@ Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
Please send Mes bug reports to bug-mes@gnu.org.
* Changes in 0.22 since 0.21
** Core
*** Mes now builds reproducibly with MesCC, cross distribution
Using --with-bootstrap on x86, a bin/mes-mescc is compiled with
mes+mescc, that shall have sha256sum
9e0bcb1633c58e7bc415f6ea27cee7951d6b0658e13cdc147e992b31a14625fb bin/mes-mescc
This has been verified on GNU Guix, Debian GNU/Linux and NixOS.
*** Mes now builds reproducibly with Guile+MesCC vs Mes+MesCC.
*** Mes now builds reproducibly with Tiny CC-built MesCC.
*** configure now respects the user's CFLAGS, CPPFLAGS and LDFLAGS.
*** Mes now supports mescc-tools 0.5.2 next to 0.6.1.
This allows introducing the Scheme-only bootstrap without updating or
adding new bootstrap binary seeds into GNU Guix.
*** Mes now runs when configured --with-courage on the Hurd:
GNU debian 0.9 GNU-Mach 1.8+git20170609-486/Hurd-0.9 i686-AT386 GNU
Note that mescc does not run; fork and exec are not yet implemented.
*** Mes now configures --with-courage on x86-FreeBSD 12.1
The initial ELF scaffold tests: exit-42.S, 0exit-42.hex2,
body-exit-42.hex2, hello-mes.S, 0hello-mes.hex2, body-hello-mes.hex2
pass.
*** configure now has a --with-bootstrap option.
This adds the reproducible bootstrap build of bin/mes-mescc, using
mes+mescc.
*** configure prefers $CC over gcc; tcc over gcc, gcc over cc.
*** Mes now prints an error when attempting to read a file that does not exist.
*** Mes no longer depends on GIT.
** Noteworthy bug fixes
*** Several annoying build problems were fixed, for non-Guix systems.
*** A bug with buffered-read was fixed.
This means that bash-2.05 can now build glibc-2.2.5; notably it now
successfully executes make-syscall.sh.
*** A bug with execlp, execvp for file names containing a slash was fixed.
This should allow make-3.80 running scripts that have "#! ./move-if-change".
* Changes in 0.21 since 0.20
** Core
*** Mes can now be bootstrapped with Gash and Gash Core Utils.
@ -48,6 +83,7 @@ take-while.
*** 1 new function
__mesabi_uldiv.
** Noteworthy bug fixes
*** map and for-each now support lists with unequal length.
*** interger division has been fixed.
*** isatty now looks at terminfo.
*** signal now uses sigaction correctly for non-x86.

22
PORTING
View File

@ -54,6 +54,28 @@ bootstrap for x86_64 uses x86 mes and that is not expected to change.
The Hurd port can be found in wip-hurd on savannah. For development, we
use a Debian GNU/Hurd vm.
* Porting GNU Mes to FreeBSD
The FreeBSD port can be found in wip-freebsd on savannah.
* Porting the Reduced Binary Seed bootstrap to NixOS
The NixOS port of the Reduced Binary Seed bootstrap lives on the
mes-bootstrap branch in https://github.com/xwvvvvwx/nixpkgs
* Porting the Reduced Binary Seed bootstrap to Debian GNU/Linux
To port the Reduced Binary Seed bootstrap to a traditional distribution
such as Debian, two things need to happen: the bootstrap must be ported
and the distribution build process needs to change to start from a only
binary seed.
The porting aspect is probably easiest: we start by packaging GNU Mes as
a regular package. Having Mes built as a regular package, we can then
build a bootstrap Mes. This bootstrap Mes can be used to build tinycc,
and so on.
Once we have shown that the Debian base system can be bootstrapped from
a Reduced Binary seed, thus significantly reducing the Trusted Computing
Base (TCB), strategic decisions about the build process can start.
* Legalese
Copyright © 2019 Jan (janneke) Nieuwenhuizen <[[mailto:janneke@gnu.org][janneke@gnu.org]]>

12
README
View File

@ -4,11 +4,11 @@
#+SUBTITLE: Maxwell Equations of Software
[[https://www.gnu.org/software/mes][GNU Mes]] is a Scheme interpreter and C compiler for bootstrapping the GNU
system. Since version 0.20 it brings a [[https://guix.gnu.org/blog/2019/guix-reduces-bootstrap-seed-by-50/][Reduced Binary Seed bootstrap]] to
System. Since version 0.20 it brings a [[https://guix.gnu.org/blog/2019/guix-reduces-bootstrap-seed-by-50/][Reduced Binary Seed bootstrap]] to
[[https://www.gnu.org/software/guix][GNU Guix]]. This bootstrap has halved the size of opaque, uninspectable
binaries that were needed to bootstrap Guix 1.0. The final goal is to
help create a full source bootstrap as part of the [[http://bootstrappable.org][bootstrappable builds]]
effort for UNIX-like operating systems.
binary seeds that were needed to bootstrap Guix 1.0. The final goal is
to help create a full source bootstrap as part of the [[http://bootstrappable.org][bootstrappable
builds]] effort for UNIX-like operating systems.
Mes consists of a mutual self-hosting Scheme interpreter written in
~5,000 LOC of simple C, and a C compiler written in Scheme. This mes.c
@ -16,8 +16,8 @@ is [[https://github.com/oriansj/mes-m2][being simplified]] to be transpiled by [
The Scheme interpreter has a Garbage Collector, a library of loadable
Scheme modules-- notably Dominique Boucher's [[https://github.com/schemeway/lalr-scm][LALR]], Pre-R6RS [[https://www.cs.indiana.edu/chezscheme/syntax-case/old-psyntax.html][portable
syntax-case]] with R7RS ellipsis, Matt Wette's [[https://www.nongnu.org/nyacc][Nyacc]] --and test suite just
enough to support a REPL and a C99 compiler: MesCC.
syntax-case]] with R7RS ellipsis, Matt Wette's [[https://www.nongnu.org/nyacc][Nyacc]] --and test suite,
just enough to support a REPL and a C99 compiler: mescc.
Mes+MesCC can compile an only [[http://gitlab.com/janneke/tinycc][lightly patched TinyCC]] that is
self-hosting. Using this tcc and the Mes C library we now have a

31
ROADMAP
View File

@ -9,7 +9,7 @@ Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
The goals of the GNU Mes project are two-fold:
- to bootstrap the GNU system purely from source, without using any binary
- to bootstrap the GNU System purely from source, without using any binary
seeds.
- to aid the Reproducible-Builds.org effort; demonstrate the impact and
@ -23,23 +23,32 @@ on Freenode!
* TODO
** release 0.x, unsorted
- Merge the Scheme-only bootstrap which uses Gash and Gash Core
Utilities to remove from bootstrap-binary seed : Awk, Bash, Core
Utilities, Grep, Gzip, Sed, Tar.
- Introduce the Reduced Binaries Seed bootstrap to NixOS (Debian,
Gentoo, ...?)
- Full Source Bootstrap: compile Mes.c using M2-Planet. Jeremiah
Arch, Gentoo, ...?)
- Full Source Bootstrap: compile mes.c using M2-Planet. Jeremiah
branched-out from mes; see https://github.com/oriansj/mes-m2, also see the
branches: wip-m2-merge and wip-m2.
- Scheme-only bootstrap bootstrap-binaries with Gash and Gash Core
Utilities: Awk, Bash, Core Utilities, Grep, Gzip, Make, Sed, Tar.
branches: wip-full-source-bootstrap, wip-m2-merge and wip-m2.
- Full Guile-compatible module support: define-module, define-public,
export, use-modules, ...
- ARMv7/AArch64 support: Mes C Library and MesCC.
- Simplify eval-apply and other core functionality (see mes-m2).
** after release 1.0
- Replace the initial gcc-2.95.3 with gcc-4.6.4.
- Support native x86_64 bootstrap.
- Simplify MesCC ``MesCC should optimize ease of convincing us of its
correctness''
- tcc: remove or upstream patches from tcc-boot.
- tcc: build 0.9.27 directly instead of via 0.9.26, see tinycc
** after release 1.0
- Build Guix packages using Mes: run or simplify (guix build utils),
(guix build gnu-build-system).
- Build Guix packages without guix-daemon. See Ludovic's initrd build
work.
- Bootstrap support for the Hurd. Most needed now are fork and exec.
- Replace the initial gcc-2.95.3 with gcc-4.6.4.
- FreeBSD, *BSD?
wip-bootstrappable@0.9.27 branch
- Bootstrap a `bootstrap-Guile' before bootstrapping tcc?
- Skip tcc: Build gcc using MesCC.
- better garbage collector.
- mes/mescc: proper docstrings, api reference documentation.
@ -51,9 +60,9 @@ on Freenode!
+ get full source syntax-case up (Andre van Tonder?)
https://srfi.schemers.org/srfi-72/srfi-72.html, or
+ ... drop it?
- Support the Hurd. There is a wip-hurd branch; most needed now are fork
and exec.
* DONE
- 0.22 GNU Mes now builds reproducibly cross-platform, runs on the
Hurd and has better support for other distributions and kernels.
- 0.21 GNU Mes now supports a Scheme-only bootstrap and is packaged in
Debian GNU/Linux.
- 0.20 GNU Mes brings the Reduced Binary Source bootstrap to Guix.

View File

@ -97,7 +97,7 @@ fi
-I ${srcdest}include
-I ${srcdest}include/$mes_kernel/$mes_cpu
"
if test "$compiler" != bootstrap; then
if test $compiler = gcc; then
${SHELL} ${srcdest}build-aux/build-mes.sh
fi
)
@ -108,13 +108,16 @@ fi
cd mescc-lib
sed -i s,mes_libc=system,mes_libc=mes, config.sh
mkdir -p include/mes
cp -p ../include/mes/config.h include/mes/config.h
cp ../include/mes/config.h include/mes/config.h
sed -i 's,#define SYSTEM_LIBC 1,#undef SYSTEM_LIBC,' include/mes/config.h
if test -z "$srcdest"; then
srcdest=../
srcdir=../
fi
AM_CPPFLAGS="
ln -sf ${srcdest}mes .
ln -sf ${srcdest}module .
ln -sf ${srcdest}src .
AM_CPPFLAGS="
-D HAVE_CONFIG_H=1
-I ${srcdest}lib
-I include
@ -122,8 +125,8 @@ fi
-I ${srcdest}include/$mes_kernel/$mes_cpu
"
compiler=mescc
AR="${srcdest}pre-inst-env mesar"
CC="${srcdest}pre-inst-env mescc -m $mes_bits"
AR=${MESAR-"${srcdest}pre-inst-env mesar"}
CC=${MESCC-"${srcdest}pre-inst-env mescc -m $mes_bits"}
# No user overrides for MesCC, they are probably intended for GCC
CFLAGS=
CPPFLAGS=

View File

@ -28,6 +28,7 @@ GIT:=@GIT@
GUILD:=@GUILD@
GUILE:=@GUILE@
GUILE_EFFECTIVE_VERSION:=@GUILE_EFFECTIVE_VERSION@
GUILE_LOAD_PATH:=@GUILE_LOAD_PATH@
GUIX:=@GUIX@
HELP2MAN:=@HELP2MAN@
HEX2:=@HEX2@

View File

@ -29,6 +29,7 @@ GIT="@GIT@"
GUILD="@GUILD@"
GUILE="@GUILE@"
GUILE_EFFECTIVE_VERSION="@GUILE_EFFECTIVE_VERSION@"
GUILE_LOAD_PATH="@GUILE_LOAD_PATH@"
GUIX="@GUIX@"
HELP2MAN="@HELP2MAN@"
HEX2="@HEX2@"

79
build-aux/gen-cppmach.scm Normal file
View File

@ -0,0 +1,79 @@
#! /bin/sh
# -*-scheme-*-
exec ${GUILE-guile} --no-auto-compile -L $(dirname $0) -C $(dirname $0) -e '(mes-snarf)' -s "$0" "$@"
!#
;;; GNU Mes --- Maxwell Equations of Software
;;; Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
;;;
;;; This file is part of GNU Mes.
;;;
;;; GNU Mes is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Mes is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Mes. If not, see <http://www.gnu.org/licenses/>.
;; Usage:
;; GUILE_LOAD_PATH=~/src/nyacc/module MES_ARENA=2000000 MES_MAX_ARENA=$MES_ARENA ./pre-inst-env mes build-aux/gen-cppmach.scm
(cond-expand
(mes
(mes-use-module (mes misc))
(warn 'boo)
(mes-use-module (mes pretty-print))
(mes-use-module (nyacc lang c99 cppmach)))
(guile
(use-modules (mes pretty-print))
(module-define! (resolve-module '(nyacc lalr)) 'pretty-print pretty-print)
(use-modules (nyacc lang c99 cppmach))))
(define (reverse-string-append lst)
(apply string-append (reverse lst)))
(define (call-with-output-file file-name proc)
(let ((port (open-output-file file-name)))
(if (= port -1)
(error 'cannot-open file-name)
(proc port))))
(define (string-every-pred-start-end pred s start end)
(cond ((= start end) #t)
((> start end) (throw 'value-out-of-range "string-every" s start end))
(else (and (string-every-pred-start-end pred s (1+ start) end)
(pred (string-ref s start))))))
(define (string-every pred s . rest)
(let ((start (if (null? rest) 0
(car rest)))
(end (if (or (null? rest) (null? (cdr rest))) (string-length s)
(cadr rest)))
(pred (if (char? pred) (lambda (c) (eq? c pred)) pred)))
(string-every-pred-start-end pred s start end)))
(define (vector-fold proc init vec1 . rest)
(if (null? rest)
(let ((len (vector-length vec1)))
(let loop ((i 0) (result init))
(if (= i len) result
(loop (1+ i) (proc i result (vector-ref vec1 i))))))
(error "VECTOR-FOLD-2-NOT-SUPPORTED")))
(define F_OK 0)
(define (rename-file old new)
(system* "mv" old new)) ;; FIXME: rename is in libc+gnu.
(define (move-if-changed src-file dst-file . rest)
(rename-file src-file dst-file))
(gen-cpp-files ".")

88
configure vendored
View File

@ -3,23 +3,23 @@
MES_ARENA=100000000 exec ${SCHEME-guile} -L . --no-auto-compile -e '(configure)' -s "$0" ${1+"$@"}
!#
;;; GNU Mes --- Maxwell Equations of Software
;;; GNU MES --- Maxwell Equations of Software
;;; Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
;;;
;;; configure: This file is part of GNU Mes.
;;; configure: This file is part of GNU MES.
;;;
;;; GNU Mes is free software; you can redistribute it and/or modify it
;;; GNU MES is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Mes is distributed in the hope that it will be useful, but
;;; GNU MES is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Mes. If not, see <http://www.gnu.org/licenses/>.
;;; along with GNU MES. If not, see <http://www.gnu.org/licenses/>.
(define-module (configure)
#:use-module (srfi srfi-1)
@ -155,7 +155,7 @@ MES_ARENA=100000000 exec ${SCHEME-guile} -L . --no-auto-compile -e '(configure)'
(data dependency-data)
(version-found dependency-version-found))
(define* (make-dep name #:key (version '(0)) optional? (version-option "--version") (commands (list name)) file-name data)
(define* (make-dep name #:key (version '()) optional? (version-option "--version") (commands (list name)) file-name data)
(let* ((env-var (getenv (name->shell-name name)))
(commands (if env-var (cons env-var commands) commands)))
(make-dependency name version optional? version-option commands file-name data #f)))
@ -186,7 +186,12 @@ MES_ARENA=100000000 exec ${SCHEME-guile} -L . --no-auto-compile -e '(configure)'
(let ((split (string-tokenize string
(char-set-adjoin char-set:digit #\.))))
(and (pair? split)
(let* ((version (sort split (lambda (a b) (> (string-length a) (string-length b)))))
(let* ((version (sort split (lambda (a b)
(let ((len-a (length (string-split a #\.)))
(len-b (length (string-split b #\.))))
(cond ((> len-a len-b) #t)
((< len-a len-b) #f)
(else (> (string-length a) (string-length b))))))))
(version (car version))
(version (string-tokenize version
(char-set-complement (char-set #\.)))))
@ -198,16 +203,17 @@ MES_ARENA=100000000 exec ${SCHEME-guile} -L . --no-auto-compile -e '(configure)'
(version-option (dependency-version-option dependency))
(commands (dependency-commands dependency)))
(let loop ((commands commands))
(if (null? commands) dependency
(if (or (null? commands)
(not (car commands))) dependency
(let ((command (car commands)))
(stdout "checking for ~a~a... " name
(stdout "checking for ~a~a... " (if (string-index command #\space) name command)
(if (null? expected) ""
(format #f " [~a]" (version->string expected))))
(let* ((output (gulp-pipe (string-append command " " (if version-option version-option ""))))
(actual (string->version output))
(pass? (and actual (tuple< expected actual)))
(dependency (set-field dependency (dependency-version-found) actual)))
(stdout "~a ~a\n" (if pass? (if (pair? actual) "" " yes")
(stdout "~a ~a\n" (if pass? (if (pair? actual) "" "yes")
(if actual " no, found" "no"))
(or (version->string actual) ""))
(if pass? (let ((file-name (or (PATH-search-path command)
@ -273,7 +279,7 @@ MES_ARENA=100000000 exec ${SCHEME-guile} -L . --no-auto-compile -e '(configure)'
(define (check-compile-string-c cc string)
(with-output-to-file ".config.c"
(cut display string))
(let ((test (lambda _ (apply system* `(,cc "--std=gnu99" "-c" "-o" ".config.o" ,@(cflags-list) ".config.c")))))
(let ((test (lambda _ (apply system* `(,cc "-std=gnu99" "-c" "-o" ".config.o" ,@(cflags-list) ".config.c")))))
(zero? (if %verbose? (test)
(with-error-to-file "/dev/null"
test)))))
@ -281,7 +287,7 @@ MES_ARENA=100000000 exec ${SCHEME-guile} -L . --no-auto-compile -e '(configure)'
(define (check-link-string-c cc string)
(with-output-to-file ".config.c"
(cut display string))
(let ((test (lambda _ (apply system* `(,cc "--std=gnu99" "-o" ".config" ,@(cflags-list) ,@(ldflags-list) ".config.c")))))
(let ((test (lambda _ (apply system* `(,cc "-std=gnu99" "-o" ".config" ,@(cflags-list) ,@(ldflags-list) ".config.c")))))
(zero? (if %verbose? (test)
(with-error-to-file "/dev/null"
test)))))
@ -382,6 +388,7 @@ Some influential environment variables:
LDFLAGS C linker flags
GUILE guile command
GUILD guild command
GUILE_LOAD_PATH guile load path; where to find Nyacc
MES_FOR_BUILD build system MES [can be mes or guile]
" PACKAGE VERSION (getenv "prefix")))
@ -404,6 +411,8 @@ Some influential environment variables:
(includedir (option-ref options 'includedir "${prefix}/include"))
(libdir (option-ref options 'libdir "${prefix}/lib"))
(pkgdatadir (string-append datadir "/mes"))
(guile-load-path (if (and (pair? %load-path) (equal? (car %load-path) ".")) (cdr %load-path)
%load-path))
(guile-effective-version (effective-version))
(guile-site-dir (if (equal? prefix ".") (canonicalize-path ".")
(string-append prefix "/share/guile/site/" guile-effective-version)))
@ -436,12 +445,10 @@ Some influential environment variables:
(when %verbose?
(stderr "configure args=~s\n" args))
(for-each (lambda (v) (apply setenv (string-split v #\=))) vars)
(let* ((tinycc-prefix (or (getenv "TINYCC_PREFIX")
(string-append srcdest "../tinycc-prefix")))
(cross? (not (equal? host-type build-type)))
(gcc (or (getenv "CC") (if cross? (string-append host-type "-" "gcc") "gcc")))
(tcc (or (getenv "TCC") "tcc"))
(mescc (or (getenv "MESCC") "mescc"))
(let* ((cross? (not (equal? host-type build-type)))
(gcc (if cross? (string-append host-type "-" "gcc") "gcc"))
(tcc (if cross? (string-append host-type "-" "tcc") "tcc"))
(mescc (if cross? (string-append host-type "-" "mescc") "mescc"))
(deps (fold (lambda (program results)
(cons (check-program-version program) results))
'()
@ -453,12 +460,18 @@ Some influential environment variables:
(make-dep "mes" #:version '(0 20) #:optional? #t)
(make-dep "guix" #:version '(0 13) #:optional? #t)
(make-dep "ar" #:version '(2 10) #:optional? #t)
(make-dep "sh" #:version '(0) #:optional? #t)
(make-dep "sh" #:optional? #t)
(make-dep "bash" #:version '(2 0) #:optional? #t)
(make-dep "guild" #:version '(2 0) #:commands '("guild" "guile-tools" "true"))
(make-dep "cc" #:commands (list gcc "cc" tcc mescc) #:optional? #t)
(make-dep "CC" #:commands `(,(getenv "CC")) #:optional? #t)
(make-dep "CC-v" #:commands `(,(getenv "CC")) #:optional? #t #:version-option "-v")
(make-dep "cc" #:commands '("cc") #:optional? #t)
(make-dep "gcc" #:commands `(,gcc "gcc") #:optional? #t)
(make-dep "mescc" #:commands `(,mescc "mescc") #:optional? #t)
(make-dep "tcc" #:commands `(,tcc "tcc") #:optional? #t #:version-option "-v")
(make-dep "cc-v" #:commands '("cc") #:optional? #t #:version-option "-v")
(make-dep "make" #:optional? #t #:commands '("gmake" "make"))
(make-dep "makeinfo" #:optional? #t)
(make-dep "makeinfo" #:version '(6) #:optional? #t)
(make-dep "dot" #:version-option "-V" #:optional? #t)
(make-dep "help2man" #:version '(1 47) #:optional? #t)
(make-dep "perl" #:version '(5) #:optional? #t))))
@ -467,15 +480,18 @@ Some influential environment variables:
deps)
deps))
(guile (or guile "guile"))
(cc (file-name "cc" deps))
(cc (or (file-name "CC" deps)
(file-name "CC-v" deps)
(file-name "tcc" deps)
(file-name "gcc" deps)
(file-name "cc" deps)
(file-name "cc-v" deps)
(file-name "mescc" deps)))
(deps (if cc
(cons* (check-header-c cc (make-dep "limits.h"))
(check-header-c cc (make-dep "stdio.h" #:optional? #t))
deps)
deps))
(deps (cons (check-file (make-dep "tinycc-prefix" #:optional? #t
#:file-name tinycc-prefix))
deps))
(missing (filter (conjoin (negate dependency-file-name)
(negate dependency-optional?)) deps))
(deps (if cc
@ -493,21 +509,22 @@ Some influential environment variables:
"))
deps)
deps))
(mesc? (file-name "cc is Mes C" deps))
(mesc? (file-name "cc is MES C" deps))
(deps (if cc
(cons (check-compile-c cc (make-dep "cc is Tiny CC" #:data "#if !defined (__TINYCC__)
(cons (check-compile-c cc (make-dep "cc is Tiny C" #:data "#if !defined (__TINYC__)
#error no tinycc
#endif
"))
deps)
deps))
(tcc? (file-name "cc is Tiny CC" deps))
(tcc? (file-name "cc is Tiny C" deps))
(deps (if cc
(cons (check-link-c cc (make-dep "if cc can create executables" #:data "int main () {return 0;}"))
(cons (check-link-c cc (make-dep "whether cc can create executables" #:data "int main () {return 0;}"))
deps)
deps))
(system-libc? (and with-system-libc? (file-name "if cc can create executables" deps)))
(host-type (or (and cc (gulp-pipe* cc "-dumpmachine")) host-type))
(host-type (or (and cc (let ((dump (gulp-pipe* cc "-dumpmachine")))
(and (not (string-null? dump)) dump))) host-type))
(host-type-list (string-split host-type #\-))
(mes-cpu (car host-type-list))
(mes-cpu (cond ((member mes-cpu '("i386" "i486" "i586" "i686")) "x86")
@ -521,7 +538,7 @@ Some influential environment variables:
(cut member <> '("pc" "portbld" "unknown")))
(cdr host-type-list))))
(mes-kernel (if (string-prefix? "freebsd" mes-kernel) "freebsd" mes-kernel))
(compiler (if gcc? "gcc" "mescc"))
(mes-compiler (cond (gcc? "gcc") (tcc? "gcc") (else "mescc")))
(mes-system (string-join (list mes-cpu mes-kernel "mes") "-"))
(bash (or (and (file-exists? "/bin/bash") "/bin/bash")
(file-name "bash" deps)
@ -572,7 +589,7 @@ See \"Porting GNU Mes\" in the manual, or try --with-courage\n" mes-system)
("@bootstrap@" . ,(if with-bootstrap? "true" "false"))
("@courageous@" . ,(if with-courage? "true" "false"))
("@compiler@" . ,compiler)
("@compiler@" . ,mes-compiler)
("@mes_bits@" . ,mes-bits)
("@mes_kernel@" . ,mes-kernel)
("@mes_cpu@" . ,mes-cpu)
@ -600,17 +617,18 @@ See \"Porting GNU Mes\" in the manual, or try --with-courage\n" mes-system)
("@mandir@" . ,mandir)
("@sysconfdir@" . ,sysconfdir)
("@GUILE_EFFECTIVE_VERSION@" . ,(effective-version))
("@colors@" . ,(if disable-colors? "no" "yes"))
("@V@" . ,(if disable-silent-rules? "1" "0"))
("@AR@" . ,(or (file-name "ar" deps) ""))
("@BASH@" . ,bash)
("@CC@" . ,(or (file-name "cc" deps) ""))
("@CC@" . ,cc)
("@DIFF@" . ,(or (file-name "diff" deps) (string-append abs-top-builddir "/pre-inst-env diff.scm")))
("@DOT@" . ,(or (file-name "dot" deps) ""))
("@GIT@" . ,(or (file-name "git" deps) ""))
("@GUILE@" . ,guile)
("@GUILE_EFFECTIVE_VERSION@" . ,(effective-version))
("@GUILE_LOAD_PATH@" . ,(string-join guile-load-path ":"))
("@GUIX@" . ,(or (file-name "guix" deps) ""))
("@HELP2MAN@" . ,(or (file-name "help2man" deps) ""))
("@MAKEINFO@" . ,(or (file-name "makeinfo" deps) ""))
@ -682,7 +700,7 @@ See \"Porting GNU Mes\" in the manual, or try --with-courage\n" mes-system)
(let ((make (and=> (file-name "make" deps) basename)))
(display (string-append "
GNU Mes is configured for
compiler: " compiler "
compiler: " mes-compiler "
cpu: " mes-cpu "
bits: " mes-bits "
libc: " mes-libc "

View File

@ -122,7 +122,7 @@ subst () {
-e s,"@PACKAGE_NAME@,$PACKAGE_NAME,"\
-e s,"@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,"\
-e s,"@VERSION@,$VERSION,"\
-e s,"@bootstrap@,yes,"\
-e s,"@bootstrap@,true,"\
-e s,"@build@,$build,"\
-e s,"@host@,$host,"\
-e s,"@compiler@,$compiler,"\
@ -151,6 +151,7 @@ subst () {
-e s,"@pkgdatadir@,$pkgdatadir,"\
-e s,"@sysconfdir@,$sysconfdir,"\
-e s,"@GUILE_EFFECTIVE_VERSION@,$GUILE_EFFECTIVE_VERSION,"\
-e s,"@GUILE_LOAD_PATH@,$GUILE_LOAD_PATH,"\
-e s,"@V@,$V,"\
-e s,"@AR@,$AR,"\
-e s,"@BASH@,$BASH,"\

View File

@ -37,18 +37,18 @@ Packages are available in Guix master.
GNU Mes[0] brings a Reduced Binary Seed bootstrap[1] to GNU Guix[2].
This bootstrap has halved the size of opaque, uninspectable binaries
that were needed to bootstrap Guix. The final goal is to help create
a full source bootstrap as part of the bootstrappable builds[3] effort
for any interested UNIX-like operating system.
that were needed to bootstrap Guix 1.0. The final goal is to help
create a full source bootstrap as part of the bootstrappable builds[3]
effort for any interested UNIX-like operating system.
It consists of a mutual self-hosting Scheme interpreter written in
~5,000 LOC of simple C and a Nyacc-based C compiler written in Scheme.
This mes.c is being simplified[4] to be transpiled by M2-Planet[5].
Mes consists of a mutual self-hosting Scheme interpreter written in
~5,000 LOC of simple C, and a C compiler written in Scheme. This
mes.c is being simplified[4] to be transpiled by M2-Planet[5].
The Scheme interpreter has a Garbage Collector, a library of loadable
Scheme modules-- notably Dominique Boucher's LALR[6], Pre-R6RS
[portable syntax-case[7] with R7RS ellipsis, Matt Wette's Nyacc[8]
--and test suite just enough to support a REPL and a C99 compiler:
--and test suite, just enough to support a REPL and a C99 compiler:
MesCC.
Mes+MesCC can compile an only lightly patched TinyCC[9] that is

View File

@ -29,7 +29,7 @@ Documentation License''.
* mes: (mes)Invoking mes. Running Mes, a minimalist Guile lookalike.
* mescc: (mes)Invoking MesCC. Running the MesCC bootstrap compiler.
* mescc: (mes)Invoking mescc. Running the MesCC bootstrap compiler.
@end direntry
@titlepage
@ -48,7 +48,7 @@ Edition @value{EDITION} @*
@contents
@c *********************************************************************
@node Top
@node Top, Introduction, (dir), (dir)
@top GNU Mes
This document describes GNU Mes version @value{VERSION}, a bootstrappable
@ -73,6 +73,7 @@ Software Freedom
* Reproducible Builds:: Reproducibility and free software.
* Bootstrappable Builds:: The freedom to build a software without binary seed.
* Full Source Bootstrap:: Software dependencies worthy of GNU.
* LISP as Maxwell's Equations of Software:: Auditable elegance.
Installation
@ -83,15 +84,15 @@ Installation
Bootstrapping
* The Mes Bootstrap Process:: How Mes will make you yogurt from pure milk.
* Invoking Mes:: Running Mes, a minimalist Guile lookalike.
* Invoking MesCC:: Running the MesCC bootstrap compiler.
* Invoking mes:: Running Mes, a minimalist Guile lookalike.
* Invoking mescc:: Running the MesCC bootstrap compiler.
* Invoking mesar::
Invoking Mes
Invoking mes
* Environment Variables:: If the bits won't change, change their habitat.
Invoking MesCC
Invoking mescc
* MesCC Environment Variables:: There's no NIX like POSIX.
@ -108,7 +109,7 @@ Contributing
@end menu
@c *********************************************************************
@node Introduction
@node Introduction, Installation, Top, Top
@chapter Introduction
@quotation
@ -187,9 +188,10 @@ Freedom 1.
* Reproducible Builds:: Reproducibility and free software.
* Bootstrappable Builds:: The freedom to build a software without binary seed.
* Full Source Bootstrap:: Software dependencies worthy of GNU.
* LISP as Maxwell's Equations of Software:: Auditable elegance.
@end menu
@node Reproducible Builds
@node Reproducible Builds, Bootstrappable Builds, Introduction, Introduction
@section Reproducible Builds
The current Reproducible Builds effort incubated in the Debian
@ -238,7 +240,7 @@ packages could be rebuild bit-identical from source.
@author Martin Uecker
@end quotation
@node Bootstrappable Builds
@node Bootstrappable Builds, Full Source Bootstrap, Reproducible Builds, Introduction
@section Bootstrappable Builds
Software distributions that take reproducible builds seriously are
@ -250,14 +252,14 @@ opaque ascii or binary @emph{seeds} that are injected during build
time. Yes, a package may build reproduciblly from all inspectable
sourcess...but what functionality is programmed in the opaque seed?
@subsection Bootstrap Binaries
@subsection Bootstrap Binary Seed
Possibly one of the most harmless, but certainly by far the biggest
binary seed that all software distributions inject are the so called
@emph{bootstrap binaries}. Bootstrap binaries are the initial binary
@emph{bootstrap binary seed}. Bootstrap binaries are the initial binary
seeds that are used to start building the distribution.
The GNU Guix operating system, version 1.0 had a relatively small
closure of bootstrap binaries: GNU binutils, GNU gcc, GNU Libc, GNU
closure of bootstrap binary seed: GNU binutils, GNU gcc, GNU Libc, GNU
Guile, and ``Static binaries'' (think: bash, bzip2, coreutils, gawk,
grep, gzip, patch, sed, tar, xz).
@ -287,17 +289,17 @@ $ du -schx *
@end example
During the Guix 1.1 development series we managed to create the first
reduction by 50% of the Guix @emph{bootstrap binaries}@footnote{See
reduction by 50% of the Guix @emph{bootstrap binary seed}@footnote{See
@url{https://guix.gnu.org/blog/2019/guix-reduces-bootstrap-seed-by-50/}}.
This was a very important step because the ~250MB @emph{seed} of binary
code was practically non-auditable, which makes it hard to establish
what source code produced them.
@node Full Source Bootstrap
@node Full Source Bootstrap, , Bootstrappable Builds, Introduction
@section Full Source Bootstrap
There is an obvious solution: we cannot allow any binary seeds in our
software stack. Not even in the bootstrap binaries. Maybe that is a
software stack. Not even in the bootstrap binary seed. Maybe that is a
bit too strong: we want to have the absolute minimum of binary seeds and
all binary seeds need to be inspectable and must be reviewed. How big
would the absolute minimal set be?
@ -321,8 +323,8 @@ of the @var{hex} function
@end example
All computer programs look like this: an opaque list of computer codes.
The initial programs that we take for granted---the bootstrap
binaries---are about 250MB of such numbers: think 250,000 pages full of
The initial programs that we take for granted---the bootstrap binary
seed---are about 250MB of such numbers: think 250,000 pages full of
numbers.
Most computers work pretty well so apparently there is not a pressing
@ -407,7 +409,8 @@ nothing to all of the programs that our computer runs. Something that
seemed to be an impossible dream is suddenly starting to look like
``just a couple years of work''.
@subsection LISP as Maxwell's Equations of Software
@node LISP as Maxwell's Equations of Software
@section LISP as Maxwell's Equations of Software
As fate would have it, I stumbled upon this
@url{https://queue.acm.org/detail.cfm?id=1039523, interview with Alan
@ -426,7 +429,7 @@ over.
@end quotation
Our starting point is @file{hex0}, a 500 byte hex assembler and we need
to somehow close the gap to building the bootstrap binaries, esp. GNU
to somehow close the gap to building the bootstrap binary seed, esp. GNU
Gcc and the GNU C Library. What better way to do that than by
leveraging the powers of LISP?
@ -435,8 +438,49 @@ will be indirectly bootstrapped from @file{hex0} and that wields the
magical powers of LISP to close the bootstrap gap, asserting we can
enjoy software Freedom 1.
@subsection Auditable Elegance
@code{eval} and @code{apply} are mutual recursing functions that---using
a few helper functions---describe the core of the universe of computing.
@lisp
(define (apply fn x a)
(cond
((atom fn)
(cond
((eq fn CAR) (caar x))
((eq fn CDR) (cdar x))
((eq fn CONS) (cons (car x) (cadr x)))
((eq fn ATOM) (atom (car x)))
((eq fn EQ) (eq (car x) (cadr x)))
(#t (apply (eval fn a) x a))))
((eq (car fn) LAMBDA)
(eval (caddr fn) (pairlis (cadr fn) x a)))
((eq (car fn) LABEL)
(apply (caddr fn) x
(cons (cons (cadr fn) (caddr fn)) a)))))
@end lisp
@lisp
(define (eval e a)
(cond
((atom e) (cdr (assoc e a)))
((atom (car e))
(cond ((eq (car e) QUOTE) (cadr e))
((eq (car e) COND) (evcon (cdr e) a))
(#t (apply (car e) (evlis (cdr e) a) a))))
(#t (apply (car e) (evlis (cdr e) a) a))))
@end lisp
It will be a big day when our computers are fully bootstrapped from
source. It would be nice if that source code were readable, auditable
and elegant. To be honest, the elegance displayed above that we
achieved at the very start of the Mes project is currently hard to find.
It is our sincerest hope to bring back this level of quality and
elegance..
@c *********************************************************************
@node Installation
@node Installation, Bootstrapping, Introduction, Top
@chapter Installation
@cindex installing Mes
@ -452,7 +496,7 @@ to use it.
* Running the Test Suites:: Testing Mes.
@end menu
@node Regular Requirements
@node Regular Requirements, Bootstrap Requirements, Installation, Installation
@section Regular Requirements
This section lists requirements when building Mes from source. The
@ -476,7 +520,7 @@ Mes is compatible with GNU Guile, so it is possible to share the same
Scheme code between both. Currently Mes only supports the minimal
subset of R5RS and Guile extensions to run MesCC.
@node Bootstrap Requirements
@node Bootstrap Requirements, Running the Test Suites, Regular Requirements, Installation
@section Bootstrap Requirements
This section lists requirements when building Mes as a bootstrap
@ -501,7 +545,7 @@ Bootstrapping Mes depends on the following packages:
@item @url{https://savannah.gnu.org/projects/nyacc/, NYACC}, 0.93.0 or later, including 0.99.0.
@end itemize
@node Running the Test Suites
@node Running the Test Suites, , Bootstrap Requirements, Installation
@section Running the Test Suites
@cindex test suites
@ -544,7 +588,7 @@ CC=gcc CC32=i686-unknown-linux-gnu-gcc MES=guile \
build-aux/test.sh scaffold/tests/00-exit-0
@end example
@node Bootstrapping
@node Bootstrapping, Contributing, Installation, Top
@chapter Bootstrapping
@quotation
@ -584,12 +628,12 @@ responsibility.
@menu
* The Mes Bootstrap Process:: How Mes will make you yogurt from pure milk.
* Invoking Mes:: Running Mes, a minimalist Guile lookalike.
* Invoking MesCC:: Running the MesCC bootstrap compiler.
* Invoking mes:: Running Mes, a minimalist Guile lookalike.
* Invoking mescc:: Running the MesCC bootstrap compiler.
* Invoking mesar::
@end menu
@node The Mes Bootstrap Process
@node The Mes Bootstrap Process, Invoking mes, Bootstrapping, Bootstrapping
@section The Mes Bootstrap Process
The Reduced Binary Seed bootstrap currently adopted by Guix@footnote{See
@ -667,8 +711,8 @@ Although we think these are less essential and thus less interesting
than the GNU toolchain triplet that we focussed on initially, our next
priority is to eleminate these one by one.
@node Invoking Mes
@section Invoking Mes
@node Invoking mes, Invoking mescc, The Mes Bootstrap Process, Bootstrapping
@section Invoking mes
@cindex repl
The @command{mes} command is the Scheme interpreter whose prime
@ -687,13 +731,13 @@ The @var{option}s can be among the following:
@item -s @var{script} @var{arg}@dots{}
@cindex script mode
By default, Mes will read a file named on the command line as a script.
By default, mes will read a file named on the command line as a script.
Any command-line arguments @var{arg}@dots{} following @var{script}
become the script's arguments; the @code{command-line} function returns
a list of strings of the form @code{(@var{script} @var{arg}@dots{})}.
Scripts are read and evaluated as Scheme source code just as the
@code{load} function would. After loading @var{script}, Mes exits.
@code{load} function would. After loading @var{script}, mes exits.
@item -c @var{expr} @var{arg}@dots{}
@cindex evaluate expression, command-line argument
@ -701,7 +745,7 @@ Evaluate @var{expr} as Scheme code, and then exit. Any command-line
arguments @var{arg}@dots{}) following @var{expr} become command-line
arguments; the @code{command-line} function returns a list of strings of
the form @code{(@var{guile} @var{arg}@dots{})}, where @var{mes} is the
path of the Mes executable.
path of the mes executable.
@item -- @var{arg}@dots{}
Run interactively, prompting the user for expressions and evaluating
@ -709,7 +753,7 @@ them. Any command-line arguments @var{arg}@dots{} following the
@option{--} become command-line arguments for the interactive session;
the @code{command-line} function returns a list of strings of the form
@code{(@var{guile} @var{arg}@dots{})}, where @var{mes} is the path of the
Mes executable.
mes executable.
@item -L,--load-path=@var{directory}
Add @var{directory} to the front of Mes module load path. The given
@ -732,10 +776,10 @@ and the command-line arguments---the list provided by the
@code{command-line} function.
@item -h@r{, }--help
Display help on invoking Mes, and then exit.
Display help on invoking mes, and then exit.
@item -v@r{, }--version
Display the current version of Mes, and then exit.
Display the current version of mes%, and then exit.
@end table
@ -743,7 +787,7 @@ Display the current version of Mes, and then exit.
* Environment Variables:: If the bits won't change, change their habitat.
@end menu
@node Environment Variables
@node Environment Variables, , Invoking mes, Invoking mes
@subsection Environment Variables
@cindex environment variables
@cindex shell
@ -752,13 +796,13 @@ Display the current version of Mes, and then exit.
@c Hmm, I expected this paragraph in the Guix manual?
Here are the environment variables (see @pxref{Environment Variables,,,
guile, Guile Reference}) that affect the run-time behavior of
Mes:
mes:
@table @env
@item MES_BOOT
@vindex MES_BOOT
Set @env{MES_BOOT} to change the initial Scheme program that Mes runs.
Set @env{MES_BOOT} to change the initial Scheme program that mes runs.
@item MES_ARENA
@vindex MES_ARENA
@ -821,8 +865,8 @@ Mes uses @var{@strong{GUILE}_LOAD_PATH} for compatibility with Guile.
@end table
@node Invoking MesCC
@section Invoking MesCC
@node Invoking mescc, Invoking mesar, Invoking mes, Bootstrapping
@section Invoking mescc
@example
mescc @var{option}@dots{} @file{FILE}@dots{}
@ -902,14 +946,14 @@ specify LANGUAGE of the following input files
* MesCC Environment Variables:: There's no NIX like POSIX.
@end menu
@node MesCC Environment Variables
@node MesCC Environment Variables, , Invoking mescc, Invoking mescc
@subsection MesCC Environment Variables
@table @env
@item MES
@vindex MES
Setting @env{MES} to a mes-compatible Scheme will run MesCC using that
Setting @env{MES} to a mes-compatible Scheme will run mescc using that
@example
MES=guile mescc -c scaffold/main.c
@end example
@ -931,7 +975,7 @@ during the parsing phase.
@end table
@node Invoking mesar
@node Invoking mesar, , Invoking mescc, Bootstrapping
@section Invoking mesar
@example
@ -961,7 +1005,7 @@ display version and exit
@end table
@c *********************************************************************
@node Contributing
@node Contributing, Acknowledgments, Bootstrapping, Top
@chapter Contributing
@menu
@ -973,7 +1017,7 @@ display version and exit
* Submitting Patches:: Share your work.
@end menu
@node Building from Git
@node Building from Git, Running Mes From the Source Tree, Contributing, Contributing
@section Building from Git
If you want to hack GNU Mes itself, it is recommended to use the latest
@ -997,7 +1041,7 @@ Finally, you have to invoke @code{make check} to run tests
installation instructions (@pxref{Installation}) or send a message to
the @email{bug-mes@@gnu.org} mailing list.
@node Running Mes From the Source Tree
@node Running Mes From the Source Tree, Porting GNU Mes, Building from Git, Contributing
@section Running Mes From the Source Tree
First, you need to have an environment with all the dependencies
@ -1005,7 +1049,7 @@ available (@pxref{Building from Git}), and then simply prefix each
command by @command{./pre-inst-env} (the @file{pre-inst-env} script
lives in the top build tree of Mes).
@node Porting GNU Mes
@node Porting GNU Mes, The Perfect Setup, Running Mes From the Source Tree, Contributing
@section Porting GNU Mes
Mes was written for x86-linux. A 64 bit (x86_64) is almost done, only a
@ -1017,13 +1061,13 @@ An ARM (armv4/armv7l) linux port is underway. A port to GNU/Hurd
Initial scaffold, built by @file{build-aux/build-scaffold.sh}:
@example
@file{lib/x86-mes-gcc/exit-42.S}
@file{lib/x86-mes/elf32-0exit-42.hex2}
@file{lib/x86-mes/elf32-body-exit-42.hex2}
@file{lib/linux/x86-mes-gcc/exit-42.S}
@file{lib/linux/x86-mes/elf32-0exit-42.hex2}
@file{lib/linux/x86-mes/elf32-body-exit-42.hex2}
@file{lib/x86-mes-gcc/hello-mes.S}
@file{lib/x86-mes/elf32-0hello-mes.hex2}
@file{lib/x86-mes/elf32-body-hello-mes.hex2}
@file{lib/linux/x86-mes-gcc/hello-mes.S}
@file{lib/linux/x86-mes/elf32-0hello-mes.hex2}
@file{lib/linux/x86-mes/elf32-body-hello-mes.hex2}
@end example
Porting MesCC:
@ -1038,7 +1082,7 @@ Porting MesCC:
@file{mes/module/mescc/i386/info.mes}
@end example
@node The Perfect Setup
@node The Perfect Setup, Coding Style, Porting GNU Mes, Contributing
@section The Perfect Setup
The Perfect Setup to hack on Mes is basically the perfect setup used
@ -1053,7 +1097,7 @@ on-line documentation (docstrings), context-sensitive completion,
@kbd{M-.} to jump to an object definition, a REPL to try out your code,
and more (@pxref{Introduction,,, geiser, Geiser User Manual}).
@node Coding Style
@node Coding Style, Submitting Patches, The Perfect Setup, Contributing
@section Coding Style
In general our code follows the GNU Coding Standards (@pxref{Top,,,
@ -1089,7 +1133,7 @@ Additionally, in Mes we prefer to format @code{if} statements like this
else))
@end example
@node Submitting Patches
@node Submitting Patches, , Coding Style, Contributing
@section Submitting Patches
Development is done using the Git distributed version control system.
@ -1139,7 +1183,7 @@ Join us on @code{#bootstrappable} on the Freenode IRC network or on
Please send bug reports with full details to @email{bug-mes@@gnu.org}.
@c *********************************************************************
@node Acknowledgments
@node Acknowledgments, Resources, Contributing, Top
@chapter Acknowledgments
We would like to thank the following people for their help: Jeremiah
@ -1151,7 +1195,7 @@ LISP-1.5 and Alan Kay for their inspiring comment on
@url{https://queue.acm.org/detail.cfm?id=1039523, Page 13}.
@c *********************************************************************
@node Resources
@node Resources, GNU Free Documentation License, Acknowledgments, Top
@chapter Resources
@itemize
@ -1185,17 +1229,17 @@ at the freenode IRC network.
@end itemize
@c *********************************************************************
@node GNU Free Documentation License
@node GNU Free Documentation License, Concept Index, Resources, Top
@appendix GNU Free Documentation License
@cindex license, GNU Free Documentation License
@include fdl-1.3.texi
@c *********************************************************************
@node Concept Index
@node Concept Index, Programming Index, GNU Free Documentation License, Top
@unnumbered Concept Index
@printindex cp
@node Programming Index
@node Programming Index, , Concept Index, Top
@unnumbered Programming Index
@syncodeindex tp fn
@syncodeindex vr fn

View File

@ -399,6 +399,7 @@ SCM read_string (SCM port);
SCM string_append (SCM x);
SCM string_length (SCM string);
SCM string_ref (SCM str, SCM k);
SCM string_set_x (SCM str, SCM k, SCM v);
// src/struct.mes
SCM make_struct (SCM type, SCM fields, SCM printer);
SCM struct_length (SCM x);

View File

@ -24,9 +24,21 @@
#include <stdio.h>
#include <sys/types.h>
#if !__MESC__ /* FIXME: We want bin/mes-mescc's x86-linux sha256sum to stay the same. */
off_t
_lseek (int filedes, off_t offset, int whence)
{
return _sys_call3 (SYS_lseek, (int) filedes, (long) offset, (int) whence);
}
#endif
off_t
lseek (int filedes, off_t offset, int whence)
{
#if !__MESC__ /* FIXME: We want bin/mes-mescc's x86-linux sha256sum to stay the same. */
if (_lseek (filedes, 0, SEEK_CUR) == -1)
return -1;
#endif
size_t skip = __buffered_read_clear (filedes);
if (whence == SEEK_CUR)
offset -= skip;

View File

@ -22,7 +22,13 @@
#include <stdlib.h>
#include <string.h>
#if !__MESC__
#define __READ_BUFFER_MAX 128
int __read_buffer_max;
#else /* FIXME: We want bin/mes-mescc's x86-linux sha256sum to stay the same. */
#define __READ_BUFFER_MAX 100
#define __read_buffer_max 100
#endif
struct __read_buffer
{
@ -36,7 +42,21 @@ void
__buffered_read_init (int filedes)
{
if (!__read_cache)
__read_cache = (struct __read_buffer *) malloc (sizeof (struct __read_buffer) * __FILEDES_MAX);
{
__read_cache = (struct __read_buffer *) malloc (sizeof (struct __read_buffer) * __FILEDES_MAX);
#if !__MESC__
__read_buffer_max = __READ_BUFFER_MAX;
char *p = getenv ("MES_READ_BUFFER");
if (p)
{
__read_buffer_max = atoi (p);
if (__read_buffer_max < 0)
__read_buffer_max = 0;
if (__read_buffer_max > __READ_BUFFER_MAX)
__read_buffer_max = __READ_BUFFER_MAX;
}
#endif
}
}
size_t
@ -55,23 +75,33 @@ __buffered_read (int filedes, void *buffer, size_t size)
__buffered_read_init (filedes);
struct __read_buffer *cache = &__read_cache[filedes];
char *p = buffer;
if (!cache->size && size > __READ_BUFFER_MAX)
if (!cache->size && size > __read_buffer_max)
return _read (filedes, buffer, size);
while (cache->size > 0 && todo)
{
todo--;
*p++ = cache->string[__READ_BUFFER_MAX - cache->size--];
*p++ = cache->string[__read_buffer_max - cache->size--];
}
if (todo)
{
ssize_t bytes = _read (filedes, cache->string, __READ_BUFFER_MAX);
#if !__MESC__
if (todo > __read_buffer_max)
return size - todo + _read (filedes, p, todo);
if (__mes_debug () > 4)
{
eputs ("__buffered_read: ");
eputs (itoa (__read_buffer_max));
eputs ("\n");
}
#endif
ssize_t bytes = _read (filedes, cache->string, __read_buffer_max);
if (bytes < 0)
return -1;
if (bytes)
{
cache->size = bytes;
if (bytes < __READ_BUFFER_MAX)
memmove (cache->string + __READ_BUFFER_MAX - bytes, cache->string, bytes);
if (bytes < __read_buffer_max)
memmove (cache->string + __read_buffer_max - bytes, cache->string, bytes);
return size - todo + __buffered_read (filedes, p, todo);
}
}

View File

@ -21,6 +21,7 @@
#include <mes/lib.h>
#include <errno.h>
#include <stdarg.h>
#include <string.h>
int
execlp (char const *file_name, char const *arg, ...)
@ -28,7 +29,7 @@ execlp (char const *file_name, char const *arg, ...)
va_list ap;
int r;
va_start (ap, arg);
if (file_name[0] != '/')
if (!strchr (file_name, '/'))
file_name = search_path (file_name);
if (__mes_debug () > 2)
{

View File

@ -20,12 +20,13 @@
#include <mes/lib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
int
execvp (char const *file_name, char *const argv[])
{
if (file_name[0] != '/')
if (!strchr (file_name, '/'))
file_name = search_path (file_name);
if (!file_name)
{

View File

@ -42,5 +42,5 @@ open (char const *file_name, int flags, ...)
return r;
}
else
return _open2(file_name, flags);
return _open2 (file_name, flags);
}

View File

@ -45,7 +45,7 @@ fopen (char const *file_name, char const *opentype)
int flags = O_RDWR;
if (opentype[0] == 'a')
flags |= O_APPEND;
fd = open (file_name, flags, mode);
fd = _open3 (file_name, flags, mode);
}
else if (opentype[0] == 'w' || opentype[0] == 'a' || !strcmp (opentype, "r+"))
{
@ -72,5 +72,3 @@ fopen (char const *file_name, char const *opentype)
fd = 0;
return (FILE *) (long) fd;
}
#undef open

View File

@ -32,6 +32,8 @@
(mes-use-module (mes display))
(mes-use-module (mes simple-format))
(define %load-path (or (and=> (getenv "GUILE_LOAD_PATH") (lambda (x) (string-split x #\:))) '()))
(define (drain-input port) (read-string))
(define (read-line . rest)

View File

@ -205,9 +205,6 @@
(define (make-string n . fill)
(list->string (apply make-list n fill)))
(define (string-set! s k v)
(list->string (list-set! (string->list s) k v)))
(define (substring s start . rest)
(let* ((end (and (pair? rest) (car rest)))
(lst (list-tail (string->list s) start)))

View File

@ -22,8 +22,9 @@
;;; Code:
(mes-use-module (mes pretty-print))
(mes-use-module (mes psyntax))
(mes-use-module (srfi srfi-1))
(mes-use-module (srfi srfi-9-psyntax))
(mes-use-module (srfi srfi-9))
(mes-use-module (srfi srfi-43))
(include-from-path "nyacc/lalr.scm")

View File

@ -0,0 +1,33 @@
;;; -*-scheme-*-
;;; GNU Mes --- Maxwell Equations of Software
;;; Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
;;;
;;; This file is part of GNU Mes.
;;;
;;; GNU Mes is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Mes is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Mes. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;;; Code:
(mes-use-module (mes guile))
(mes-use-module (rnrs arithmetic bitwise))
(mes-use-module (srfi srfi-43))
(mes-use-module (nyacc lalr))
(mes-use-module (nyacc parse))
(mes-use-module (nyacc lex))
(mes-use-module (nyacc lang util))
(include-from-path "nyacc/lang/c99/cppmach.scm")

View File

@ -0,0 +1,34 @@
;;; -*-scheme-*-
;;; GNU Mes --- Maxwell Equations of Software
;;; Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
;;;
;;; This file is part of GNU Mes.
;;;
;;; GNU Mes is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Mes is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Mes. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;;; Code:
(mes-use-module (mes guile))
(mes-use-module (srfi srfi-43))
(mes-use-module (nyacc lang c99 cpp))
(mes-use-module (nyacc lang util))
(mes-use-module (nyacc lalr))
(mes-use-module (nyacc parse))
(mes-use-module (nyacc lex))
(mes-use-module (nyacc util))
(include-from-path "nyacc/lang/c99/mach.scm")

View File

@ -20,9 +20,9 @@
;;; Taken from GNU Guile
(define-module (ice-9 pretty-print)
:use-module (ice-9 optargs)
:export (pretty-print))
(define-module (mes pretty-print)
#:use-module (ice-9 optargs)
#:export (pretty-print))
;; From SLIB.

View File

@ -42,6 +42,7 @@
c99-input->object))
(define mes? (pair? (current-module)))
(define mes-or-reproducible? #t)
(define (cc-amd? info) #f) ; use AMD calling convention?
;; (define %reduced-register-count #f) ; use all registers?
(define %reduced-register-count 2) ; use reduced instruction set
@ -581,7 +582,7 @@
(wrap-as `((#:comment ,o))))
(define (ast->comment o)
(if mes? '()
(if mes-or-reproducible? '()
(let* ((source (with-output-to-string (lambda () (pretty-print-c99 o))))
;; Nyacc fixups
(source (string-substitute source "\\" "\\\\"))
@ -1514,7 +1515,7 @@
info))
((or ,a ,b)
(let* ((here (number->string (length (if mes? (.text info)
(let* ((here (number->string (length (if mes-or-reproducible? (.text info)
(filter (negate comment?) (.text info))))))
(skip-b-label (string-append label "_skip_b_" here))
(b-label (string-append label "_b_" here))

View File

@ -31,6 +31,8 @@
#:use-module (mes guile)
#:export (c99-input->ast))
(define mes-or-reproducible? #t)
(when (getenv "MESC_DEBUG")
(format (current-error-port) "*nyacc-version*=~a\n" *nyacc-version*))
@ -97,7 +99,7 @@
"SYSTEM_LIBC=0"
"__STDC__=1"
"__MESC__=1"
,(if mes? "__MESC_MES__=1" "__MESC_MES__=0")
,(if mes-or-reproducible? "__MESC_MES__=1" "__MESC_MES__=0")
,@defines)))
(when (and verbose? (> verbose? 1))
(stderr "includes: ~s\n" includes)

View File

@ -1729,6 +1729,7 @@ mes_builtins (SCM a) ///((internal))
a = init_builtin (builtin_type, "string-append", -1, (function1_t) & string_append, a);
a = init_builtin (builtin_type, "string-length", 1, (function1_t) & string_length, a);
a = init_builtin (builtin_type, "string-ref", 2, (function1_t) & string_ref, a);
a = init_builtin (builtin_type, "string-set!", 3, (function1_t) & string_set_x, a);
// src/struct.mes
a = init_builtin (builtin_type, "make-struct", 3, (function1_t) & make_struct, a);
a = init_builtin (builtin_type, "struct-length", 1, (function1_t) & struct_length, a);

View File

@ -252,3 +252,18 @@ string_ref (SCM str, SCM k)
char const *p = CSTRING (str);
return MAKE_CHAR (p[i]);
}
SCM
string_set_x (SCM str, SCM k, SCM v)
{
assert (TYPE (str) == TSTRING);
assert (TYPE (k) == TNUMBER);
assert (TYPE (v) == TCHAR);
size_t size = LENGTH (str);
size_t i = VALUE (k);
if (i > size)
error (cell_symbol_system_error, cons (MAKE_STRING0 ("value out of range"), k));
char *p = CSTRING (str);
p[i] = VALUE (v);
return cell_unspecified;
}