Build instructions for Oaklisp
==============================

The build system uses autotools (autoconf/automake) so a simple build
would be:

	autoreconf --install    (to install the autotools support files)
	./configure             (to configure the system)
	make                    (to compile everything)
	make install            (to install everything)

For further details read INSTALL generated by running autoreconf.

Bootstrapping
=============

The only unusual aspect here is that Oaklisp is written in Oaklisp,
i.e., is self-hosting.  This causes a bootstrap issue.

There are only two files required to actually run Oaklisp:

file          | purpose
--------------|----------------------------------------------
oaklisp       | the executable / emulator / virtual machine
oakworld.bin  | pre-built oaklisp (read in by the executable)

The file oakworld.bin contains the pre-built, pre-compiled Oaklisp
system: the parts that are written in Oaklisp itself.  This means you
need an existing oakworld.bin in order to run "oaklisp" in order to
build a new oakworld.bin.  Oaklisp *cannot* run without an existing
oakworld.bin file.  You can however build the executable "oaklisp"
(which is written in C) without a working Oaklisp.  So all you really
need is oakworld.bin.  The executable "oaklisp" will look for
oakworld.bin at a compile-time-specified location, but can be
instructed to look elsewhere.

The ./configure script will look for oakworld.bin in a few places, and
use it in the build.  If it cannot find oakworld.bin automatically,
you can give an explicit location

    ./configure --with-world=/complete/path/to/oakworld.bin

See ./configure --help for details of these options.

Alternative Bootstrapping Interfaces
====================================

There are other ways to pass this information to the compiled emulator
at build time, e.g.,

    make OAKWORLD=$(pwd)/prebuilt/src/world/oakworld.bin

or

    make OAKWORLD=/usr/local/lib/oaklisp/oakworld.bin

If you already have Oaklisp installed, you can just use that:

    make OAK=/usr/local/bin/oaklisp

CPU Architecture Issues
=======================

Endianity
=========

Oaklisp is sensitive to the endianness of the CPU
<http://en.wikipedia.org/wiki/Endianness>.  There are oakworld.bin
files included in the git branch containing prebuilt files, or
available for download as a separate files, for both little-endian and
big-endian architectures.  The subdirectory is el32/ for little-endian
and eb32/ for big-endian.

However Oaklisp can easily be made to cross build an oakworld.bin for
a big-endian or little-endian architecture, given an opposite-endian
prebuilt world as well as access to systems of both endianities:

On machine with endianity of prebuilt world:

	$ autoreconf --install
	$ ./configure
	$ make -C src

Copy tree to other-endian machine, and there:

	$ ./configure
	$ make -C src/emulator clean
	$ make -C src/emulator
	$ rm src/world/*.bin
	$ touch src/world/system-version.oa
	$ touch src/world/new.cold
	$ make -C src/world

You should now be the proud possessor of an opposite-endian
src/emulator/oaklisp and src/world/oakworld.bin.

32-Bit Pointers
===============

The executable "oaklisp" currently only works in 32-bit mode.  It can
be built as a 32-bit executable on a 64-bit machines, assuming that a
32-bit-pointer executable model is available and that an appropriate
toolchain exists to target that model: compiler and development
libraries.

A 32-bit memory model is available for on most amd64-based systems,
sometimes as an optional package.  E.g., on Debian or Debian-derived
distributions like Ubuntu, the correct package is gcc-multilib.
Compiling using GCC or clang on an x86_64 aka amd64 architecture
machine, one should use the -m32 which builds an i386 architecture
executable.  A similar situation holds with many 64-bit architectures.
The appropriate GCC options will be added automatically by ./configure
when necessary on many 64-bit architectures, thanks to an exhaustive
list of appropriate options for all applicable Debian architectures
provided by James Cowgill <james410@cowgill.org.uk> in discussion of
his bug report https://bugs.debian.org/780353/.  These options also
seem to work, in many cases, with the clang compiler.  New
architectures can be added to configure.ac as clauses in the
AS_CASE([${host_cpu}],...) statement.

On x86_64 the -mx32 flag, which uses the x86_64 instruction set with
32-bit pointers, also works provided that x32 kernel support is
enabled and the x32 development files are available.  Initial
benchmarks showed that an src/emulator/oaklisp built with -m32 was
slightly faster than one built with -mx32.

To Do
=====

64-Bit Port
===========

It would be great if someone were to do a 64-bit port.  In order to
port the system to 64-bit pointers and therefore 64-bit cells, a
number of 32-bit-cell assumptions need to be dealt with.

 - The bytecode engine has 16-bit instructions, packed two/cell.  This
   becomes four/cell when cells go 64-bit.  This requires changes to
   the bytecode interpreter in src/emulator/ as well as to the
   assembler which may need to insert extra padding before inline
   literal references.  The compiler proper might not need to be
   touched at all.

 - Characters in strings would become packed seven/cell instead of
   three/cell, but that's pretty minor, and they could certainly be
   left three/cell until the system is otherwise converted.  This
   impacts src/emulator/ where Oaklisp strings are converted to C
   strings for, e.g., passing to fopen(), and the string
   packing/unpacking code in src/world/.

 - The cold world builder (generates new.cold) might need attention.

 - Bignums are stored in base 10,000, the largest power of ten less
   than (sqrt (expt 2 (- 32 3))), where the 3 bits subtracted there
   are for the tag (2 bits) and the sign (1 bit).  These would become
   base 1,000,000,000, the largest power of ten less than (sqrt (expt
   2 (- 64 3))).  Also the arithmetic overflow code in src/emulator/
   would need to be looked at.  But, bignums could wait until the
   system is otherwise up and running.

This would all be facilitated by the fact that a working 32-bit
oaklisp could be used during the bootstrap, and due to bignums its
word size should not affect its ability to generate 64-bit bootstrap
files.

Binary World Format
===================

Currently the system is started by executing the emulator, which loads
a binary world.  Different varieties of the system can be obtained by
booting different worlds, and by passing various options like the
desired locale.  Another option would be to make a new world format
which can be directly executed.  This could be accomplished in one of
three ways.  (1) The binary world could have a magic number recognized
by the OS kernel, allowing it to be executed in a special
idiosyncratic fashion.  (2) The binary world could start with

	#! /usr/bin/env oaklisp

or

	#! /usr/bin/oaklisp

and the emulator would recognize this situation and load the
apppropriate world.  (3) The world could be an ELF executable which
could be executed in native mode, and the binary data for the world
itself could live in its own ELF segment or even be bound to a symbol
in the ELF file.

