To Nix, or not to Nix - that is the question

I think the idea of Nix is a cool one. It would be awesome to have a way
of ensuring a consistent development environment wherever I will happen
to work on the project. Nix seems a bit arcane at the moment, though...

Anyway, let's explore.

What I would like to have is a script to build and test the VM in a
nix-shell--with both GCC and Clang--that would be independent of the
machine on which it is running. This should be doable, and provide a
really convenient process:

    ]$ git clone .../viuavm
    ]$ cd viuavm
    # This would build the VM's toolchain using gcc.
    ]$ bash ./nix-build.sh gcc
    # This would test the result.
    ]$ bash ./nix-test.sh

No messing around with dependencies if you only want to build, test, and
work on the code. You would only have to provide the dependencies if you
wanted to install the VM on your machine. The only things that would be
needed to work on the VM without would be Git, Nix, and BASH.
Update copyright notice
Describe the build process with a little more verbosity

The most important thing are the presets. Everything else can be
inferred from the Makefile. It is a pretty standard setup: CXX,
CXXFLAGS, etc. I tried to keep it relatively simple and clean, but the
Makefile.d containing the presets and warnings can be surprising.
Fix test suite crash when all tests failed
Add test for IF with a prepared target
Expand IF pseudoinstructions using ATXTP

See commit 6fbae81b5a3b8ae7e9d42e02e1820e2fbf6f0c17.
Use pointers as targets for CALL and ACTOR

The same should be done for jumps.
Expand CALL and ACTOR pseudoinstructions using ATXTP

Instead of doing


the sequence is now


Why? To force CALL and ACTOR to use a pointer instead of a raw integer
as their input.
Gather stats from the test run and cache them

The "stats" are just lists of cases tagged with "ok", "fail", etc. This
simple feature allows me to use

    ]$ make test TESTS=@fail

to rerun only the failed tests.
Improve build and test scripts

A better "clean" production (that also picks up the cache emitted by the
test suite now).

Different build presets for testing ("test") and debugging ("debug"),
with the difference between them being that the "debug" preset does not
include sanitisers as they do not play nice with GDB.
Enable the "indirect call" test
Implement ATXTP instruction

However, the situation of symbol-address loads right now is a mess.

Call using a pseudoinstruction? Have a LUI, LLI, CALL.
Call using a pre-filled address? Have a ATXTP, CALL.
Need an atom? One LUI, LLI, ATOM coming right up!

And it also complicates the relocation table preparation logic.

It NEEDS to be simplified. I will probably go with what RISC-V is doing
instead of innovating too much ie,

    auipc $x, high-half
    addi $x, low-half
    foo ..., $x

with foo being ATOM, CALL, etc. The AUIPC instruction would create a
pointer and then the ADDI would be used to add any extra bits necessary
to form the full address.

However, I still think that it would be useful to have two distinct
instructions for loading data and text addresses:

 - LDA (Load Data Address): create a pointer into .rodata or .data
   section which would only be useful for M operations
 - LTA (Load Text Address): create a pointer into .text section which
   would only be useful for flow operations

The VM could use the data in .symtab and in DWARF to see if the pointers
being used by the program with M and flow operations are really correct.

Yeah. Something to think about, I guess.
Remove stale stage file

It will have to be re-added anyway for the REPL, but let's leave that
for later.
Add a test for indirect calls

This is basically testing the ability to load an address of a label
pointing at an instruction in the .text section and use that as a jump
target. But an "indirect call" sounds way nicer.
Refactor test-case function

The number of source lines did not decrease much, but this is because
the code is now better documented. Logic lines were cut, and comment
lines were added.

This should make it easier to understand what is happening during the
next refactoring, or when I need to add some features to the test suite.
Enable the "io_echo" test
Handle two-case runs better

"Handle better" in this case means "don't crash".
Pipe stdin for test cases which require it
Enable the "io_print" test