preparing major changes for objects
Merge branch 'dev' into objects
Changed the Object model to use pseudo-inheritance.

Objects now contain a base struct (LuciObject) as their first
struct member, and so can be passed as LuciObjects. Each object
then contains type-specific values after the base object (e.g.

typedef struct {
    LuciObject base;
    long i;
} LuciInt...

This is essentially how Python implements its object-orientation.

I also fixed a bug which occurred when a user specifies to
print a Dot graph, and simultaneously not execute the code. Printing
the Dot graph inherently prevents execution of the code.

Fixed the builtin `range` function to work properly with reverse
ranges.

Added a compile-time link to the system math library (for Linux).
Removed all unnecessary copies and destroys.

Now objects are only copied with a instructions that require it.
Object refcounts are only incremented when "stored" in a symbol,
and decremented when overwritten in a symbol by another object.

These changes have the effect of "leaking" memory for all objects
that allocate memory outside of the garbage collector (e.g. strings
allocate a `char *`, function frames allocate `Frame *`.
crude interactive mode is now functional.

I changed the default functionality when no input file
is specified. Now a prompt is printed and user input will be
executed when the scanner sees and EOF (Ctrl+D/Z). After executing
a snippet, control returns to the user to allow them to run
more code (interactively). One issue is that "Fatal Errors"
currently exit the program entirely. In interactive mode they should
probably get cleaned up and the session should continue.
added "labels as values" utilization to interpreter.

Other bytecode interpreted languages like Python and Ruby
use GCC's "labels as values" extension (computed gotos).
It can improve the speed of the interpreter by up to 20%.
I describe the changes in interpet.c and provide links to both
Python's notes and notes from Eli Bendersky on the subject.

I am currently using macros to allow the code to compile as
a switch/case loop with compilers that don't support the
computed goto.
first step in implementing a map type.

The map type shares many similarities with the list type.
This allows both types to share some syntax and vm instructions.
I've implemented the lexer/parser rules, the AST nodes and functions,
the instructions for making maps, as well as "get"/"set" of values
using keys.
The actual implementation (using symbol tables) is the next step.
Then I'll clean up stragglers like "printing" maps, and map-related
things in the AST graphiz/dot generator.
initial implementation of hash table for Map type.

The Map type's hash table uses open-addressing
(unlike the current symbol table). Still need to make
modifications to the interpreter to actually use this
implementation for MKMAP, CPUT, CGET, etc...

I also cleaned up a few warnings from '-Wall'.
Working Map type...

The entirety of the map type is defined in map.h/map.c, rather
than in object.h/object.c like the rest of the types.

Much works remains to be completed to get map iteration and
map printing working (and I'm sure many more things).

One outstanding issue is that of using map/list accesses as
function calls e.g. `m["key"]();` or `l[0](arg1, arg2);`.
Map printing/iteration now works.

Also fixed the shift/reduce problem by allowing
container assigments (i.e. c[x] = ...) to work for any
expression... e.g. `fn()["key"] = 42`... which obviously does nothing
useful. Things are still leaking memory everywhere since the garbage
collector does not yet actually collect garbage.
Major documentation commit.

Obviously I should have been documenting my code as I
wrote it. Lots of doxygen documentation added to all files.