General
-------
The C sources contain sections of code that is conditionally compiled. See
your compiler manual how to specify options on the command line or in a
"project" to set these options.

Both the compiler and the abstract machine contain assertions to help me
catch bugs while maintaining the code. In the retail versions, you will want
to compile without assertions, because this code slows down the operation of
the tools. To do so, compile the compiler or the abstract machine with the
NDEBUG definition set.


Compiling the Abstract Machine
------------------------------
Compiling the AMX is fairly easy, because it was set up to be small and
portable. The abstract machine was intended to be linked with an application.
The file AMXDEMO is the most primitive application that I could come up with.

I compile the 16-bit version of AMXDEMO with Borland C++ using the command:

        bcc amxdemo.c amx.c amx_core.c amx_cons.c

and the 32-bit version with Watcom C/C++ using the command:

        wcl386 /l=nt amxdemo.c amx.c amx_core.c amx_cons.c


The "core" AMX routines do not use or depend on dynamic memory allocation or
console IO. The "property" functions in AMX_CORE.C use malloc()/free(); you
can remove these property set/retrieval functions by compiling the AMX_CORE.C
file with the definition NOPROPLIST.

The console IO functions in AMX_CONS.C try to use standard C as much as
possible, but some of the functions also rely on ANSI terminal codes (ANSI.SYS
under DOS). In any case, in a "real" environment, you will probably want to
replace AMX_CONS.C with an alternative that fits your application or operating
system.

Summary of definitions
    NDEBUG              compile without assertions
    NOPROPLIST          remove the get/set property functions from AMX_CORE.C


Compiling the Small compiler
----------------------------
The Small language is case sensitive, but you can make a case insensitive
version by adding the definition NO_CASE_SENSITIVE.

If you want a 16-bit version, add the definition BIT16 to the compiler options.
The header file boldly assumes that a "short int" is 16-bits and a "long int"
is 32-bits. If this is not true for your compiler, you must change the
definition of the cell type in SC.H, but you must also check the locations
where there is an "#if defined(BIT16)" around some code, because I use the
constants INT_MAX and LONG_MAX from LIMITS.H as well.
N.B. I have not ever tested, or even tried to compile, a 16-bit version of
     any of the Small tools.

The basic code generation is followed by a simple peephole optimizer. If you
stumble on a code generation bug, one of the first things that you may want
to find out is whether this bug is in the code generation or in the optimizer.
For that purpose, you can compile the compiler without peephole optimizer,
using the definition NO_OPTIMIZE.

In Small, one creates symbolic constants with the "const" keyword. But Small
also supports "#define" to provide sime level of compatibility with C or other
C like tools. The "#define" directive of Small can only declare numeric
constants, it is much more limited than C's #define. Therefore, may may find
this "portability" clumsy and rather confusing. If so, compiling with option
NO_DEFINE removes the support for the #define directive in the Small compiler.

I have compiled and tested the compiler with:
* Borland C++ 3.1, 16-bit in small and large memory models
* Microsoft C 6.0, 16-bit in small and large memory models
* Watcom C/C++ 11.0, 32-bit flat mode (Executable for Windows NT)
Both 16-bit compilers are old, but this should not matter. The code is
intended to be ANSI C as much as possible.

Summary of definitions
    BIT16               cell is 16-bits, rather than 32-bits
    NDEBUG              compile without assertions
    NO_CASE_SENSITIVE   set compiler to case insensitive
    NO_DEFINE           remove support for #define directive
    NO_OPTIMIZE         remove the peephole optimizer step

