stdlib: Implement (list-{tail,ref-set})

These are all implemented on top of a native lliby_list_tail function.
A Scheme implementation still doesn't generate ideal code; this needs to
be addressed separately.
compiler: Static planning for (list-tail)

This allows for compile time evaluation and bounds checking for static
indexes to known lists. This gets static planning for (list-ref) for
free because it can be statically evaluated in terms in (list-tail).
compiler: Partial tail call support

If a ps.Invoke is followed immediately by a ps.Return we can fuse it in
to a new ps.TailCall step. This allows us to remove our shadow stack
entry (for GC using functions) and pass a tail call hint to LLVM. This
allows many recursive procedures to use bounded space as required by
Scheme.

R7RS is very specific about the situations which must use tail calls;
this hasn't been validated to work correctly in all those cases. There
is likely more work to do but this should catch many important cases.