This turns splices that are ignored into compiler errors. Other
alternatives here should also be considered, for example making this
a compiler warning rather than an error. For example, the latest
spork as of a3ee63c137ee3234987dbbca71b566994ff8ae8c has an error of this
kind, but the resulting program does work correctly.
Also disallow splice propagation - code of the
form (+ 1 (do ;[2 3 4]) 5).
When peg/replace or peg/replace-all are given a function to serve as the text
replacement, any captures produced by the PEG are passed as additional
arguments to that function.
Functions will be invoked with the matched text, and their result will be
coerced to a string and used as the new replacement text.
This also allows passing non-function, non-byteviewable values, which will be
converted into strings during replacement (only once, and only if at least
one match is found).
These functions are designed to make it easier to properly preserve the
sourcemap and tuple type in macros. This commit also modifies the threading
macros to make use of these functions.
Comparison between different bracket and normal tuples
will now take into account the delimiter type. This solves strange
non-locality issues in the compiler due to this false equality, and is
more consistent with Janet's otherwise strong equality philosophy.
buffer/blit is difficult to use, and while buffer/push is the easiet
buffer manipulation function to use it only appends to the buffer.
buffer/push-at lets users manipulate buffers at any index - useful
for buffers used as an in-memory databases, for example.
The issue is that there was no synchronization on writes.
The stability of the test relied on the fact that the server
would read in an entire message in one call to ev/read, which
would _almost_ always happen since the messages are so small.
For to and thru, we need to restore eveytime through the loop since rules need
run with the right captures on the stack, especially if they have any
sort of backrefs.
Buffers make more sense for this function because one of their primary
use cases is working with bytes.
The tuple implementation was an array of floats, which is less
performant and ergonomic for common operations. (i.e: bit manipulation)
Buffers also have the advantage they are mutable, meaning the user
can write ints to an existing buffer.