Starting a fresh rewrite from scratch.
Add symbol functions.
Starting a fresh rewrite from scratch.
Added parse functions.

Define symbol as (struct sym *).
Parse quote_string and tilde_string.  Include syntax error in parse result.

Qsym now takes name as a string instead of a value.
Finish all the parsing rules and clean up error_line.
Compress parse_string tests.
Added parse_file.
The parse routine now returns a purely functional form.
Added is_num and is_str.

Eliminated separate type_convert module, moving its functions into type_num and
type_str.
Fix seg fault problem related to the (S (C x) I) rule.

I did this by making the parse_exp function return a safe +1 on the reference
count, so the the f->R returned from the rule did not get reclaimed from under
our feet in certain cases.
Did the main routine in fexl.c.

Add type "bad" to represent malformed data.

Rearrange test in new_memory to avoid any overflow with large num_words.

Move conversion between string and number to separate convert.c module.

Simplify how we use the forms returned from parse.

In value.c I now check the right side before calling the type routine to clear
an atom.  I found this by experimenting with a simple "type_ping" combinator
which simply printed "ping".  When it was recycled, it was calling ping a
second time.  Now it doesn't do that because there's no atom value on the right
side.

I streamlined the eval routine.  Testing for (g != f) saves about 300 bytes of
executable size, and presumably runs faster as well.

Using Qboolean in more places, reducing code size.
Avoid int size incompatibility on calls to Qboolean.
The slice function now returns bad on out of bounds.

Added an extra type cast to a buf_add call for compatibility with some stricter
compile optionsi (e.g. -Wconversion etc.)  I'm not using those options in this
release though because I still need it to compile on an older machine with a
gcc that doesn't yet support them.
Clean up parsing apparatus.
Go to +1 reference accounting.

The V routine now returns a new value with 1 reference count instead of 0.
I bubbled this through the whole program, and it makes things much more sure
and reliable.

Checking time stamps in build script again.  Added handy "fexl" script.

Removed internal check program test/run.c in factor of fexl-based test/a1.fxl.
You still use test/run and test/check though.

No more replacement inside forms during evaluation.  Evaluation is now purely
functional.  The '=' form of lambda definition does eager evaluation, and '=='
does lazy.

Added more built-in functions.  Reporting errors in a very slick way.

Among the new functions is put_to_error, which allows you to wrap a function so
that all its output goes to stderr.
Supporting delayed and single evaluation with "later" and "once".

Eliminated '==' syntax because we can use the "later" function instead.

The "get" function now simply returns the next input char as its value instead
of passing it to a handler function.

Merged test/utf8.fxl into test/a1.fxl.
Added eval_file function.
Eliminated the "bad" concept and replaced with more powerful "catch".

That streamlines the implementation of new built-in functions considerably,
since you can just return 0 if anything goes wrong, e.g. type errors like
trying to add a number and a string, or slicing a string out of bounds.

Simplified the error_code diagnosis and eliminated global "exit_code".

The parse.c module now calls the out_of_memory and out_of_time functions so we
see an error message in certain degenerate cases, such as an infinite stream
of 'a', '(', ')', or white space.