This adds a `--autotest` flag. Quoting the (new) manpage section:
> Insert automatic test assertions in the compiled program. This
> detects all scopes that have no input or context variables, runs
> the interpreter to pre-compute their values, then adds runtime
> assertions to the program that ensure that the actual output of the
> scopes match their pre-computed values. If used on a testing
> program with a given backend, this guarantees consistency between
> the backend and the interpreter.
The lexing context uses a global reference. This patch ensures it is handled
carefully for the lifetime of lexing a given file.
Before that, very weird bugs could happen, for example when a file ended with an
unclosed verbatim block, the parsing of module interfaces done later on would
start in verbatim context and fail to parse e.g. module use definitions.
The patch additionally adds checks and warns about unclosed blocks at EOF, which
before that would be silently accepted (with the above pitfall).
This happens when there are two branches that are bound to an existing struct,
and to a literal one that needs a malloc+non-const;
the fix refines the handling of `no_struct_literals` in scalc, to ensure that
`SLocalInit` is used on a local temporary variable for the constructs needing
malloc.
we want our pointers to "const" (in the C sense, i.e. read-only) values in
general; but structures need to be initialised field by field. We handle the
absence of `const` in this case (the pointer target will be made `const` upon
function return).
When we compile with `-O`, though, intermediate variables are removed, and we
have branchings with one side getting an already allocated (`const`) structure,
while the other one will need to init through allocation of individual fields.
In the current state of this patch, we define the structure as non-const and
malloc it when this happens, like in the basic definition case. It works, but in
the branch of the already allocated structure, the malloc is discarded (wasted),
and there is a legitimate warning because we strip the `const` flag from the
source pointer.
I see only two solutions:
- remove all consts (beh, they are very good for understanding what's going on,
and I'm sure that without them we'll fall into more traps later)
- in the branch(es) needing malloc, allocate and initialise to a temporary
non-const structure, then affect it to the return pointer ("sealing" it as
const after initialisation). This basically what happens without `-O` because
we have more intermediate variables... But we want to target that specifically
at cases that need malloc.
A variant of the 2nd option could be to define initialiser functions for all
structs, but we loose in readability since the arguments would be unlabelled.
The cleaner way to do it would probably be at the scalc level, depending on the
`--no-struct-literals` flag.
The c runtime is now compiled into a `.a` static library.
it's now picked up by the Python backend as well, but the corresponding runtime
hasn't been updated to use it.