Commit graph

22 commits

Author SHA1 Message Date
6056e3a450 Implement pairs
Pairs are 2-tuples of values that are constructed and matched with the `::`
operator. They can also be matched with a `:` operator, the LHS is an
expression then, the pair will then only match, if the LHS matches the
result of that expression.

Pairs should be useful to do something similar what sum types / tagged
unions do in statically typed languages, e.g. you could write something
like:

    some := (symbol) # Somthing that creates a unique value
    filter-map := {
      _ [] -> []
      f [x ~xs] ->
        {
          some:y -> [y ~(filter-map f xs)]
          nil -> filter-map f xs
        } (f x)
    }
    filter-map {
      x?even -> some :: (* x 10)
      _ -> nil
    } some-list
2023-03-22 23:54:03 +01:00
55c95f99ad Rename format => io_writer
To make it clearer that this can be used for writing binary data too.
2023-02-10 21:48:31 +01:00
0de243995b Ditch that weird internal.h header 2022-04-22 23:17:28 +02:00
a4fd3acfac Use formatter for expr printing 2022-04-22 22:52:53 +02:00
f26759b3f0 expr: Remove refcount in body elements 2022-04-11 22:44:04 +02:00
90a80152e1 Implement mark&sweep garbage collection and bytecode compilation
Instead of the previous refcount base garbage collection, we're now using
a basic tri-color mark&sweep collector. This is done to support cyclical
value relationships in the future (functions can form cycles, all values
implemented up to this point can not).

The collector maintains a set of roots and a set of objects (grouped into
blocks). The GC enabled objects are no longer allocated manually, but will
be allocated by the GC. The GC also wraps an allocator, this way the GC
knows, if we ran out of memory and will try to get out of this situation by
performing a full collection cycle.

The tri-color abstraction was chosen for two reasons:

- We don't have to maintain a list of objects that need to be marked, we
  can simply grab the next grey one.
- It should allow us to later implement incremental collection (right now
  we only do a stop-the-world collection).

This also switches to a bytecode based evaluation of the code: We no longer
directly evaluate the AST, but first compile it into a series of
instructions, that are evaluated in a separate step. This was done in
preparation for inplementing functions: We only need to turn a function
body into instructions instead of evaluating the node again with each call
of the function. Also, since an instruction list is implemented as a GC
object, this then removes manual memory management of the function body and
it's child nodes. Since the GC and the bytecode go hand in hand, this was
done in one (giant) commit.

As a downside, we've now lost the ability do do list matching on
assignments. I've already started to work on implementing this in the new
architecture, but left it out of this commit, as it's already quite a large
commit :)
2022-04-11 22:24:22 +02:00
ebf3fc89ff Introduce allocator abstraction
We now no longer call malloc/free/... directly, but use an allocator object
that is passed around.

This was mainly done as a preparation for a garbage collector: The
collector will need to know, how much memory we're using, introducing the
collector abstraction will allow the GC to hook into the memory allocation
and observe the memory usage.

This has other potential applications:

- We could now be embedded into applications that can't use the libc
  allocator.
- There could be an allocator that limits the total amount of used memory,
  e.g. for sandboxing purposes.
- In our tests we could use this to simulate out of memory conditions
  (implement an allocator that fails at the n-th allocation, increase n by
  one and restart the test until there are no more faked OOM conditions).

The function signature of the allocator is basically exactly the same as
the one Lua uses.
2022-02-08 22:53:13 +01:00
ad80ff8f85 Remove dead code 2022-02-08 21:42:54 +01:00
db0fb2aee4 expr: Make body objects refcounted
We'll soon need this, once we implement function definitions
2022-01-22 17:16:28 +01:00
d81bef9184 parser/tokenizer: Save textual data as refcounted strings
This avoids creating refcounted strings during evaluation and makes it
easier to use the same parsed string in multiple places (should be
useful once we implement functions).
2022-01-18 21:18:27 +01:00
ae45aeebe2 parser+expr: Handle blank identifier (_) 2022-01-08 23:20:29 +01:00
50cd2c18d2 expr+parser: Restrict what an assignable can be
If you assign into a member access (`foo.bar = baz` or `foo@bar = baz`), it
is no longer permitted that the LHS of the at/dot is an arbitrary
assignable. It now must be a variable, at or dot. This disallows some silly
constructs (e.g. `[foo]@bar = baz`), increases the similarity to function
parameters and should make writing the evaluation code for these more easy.
2022-01-08 23:06:22 +01:00
4eea93ff97 Improve AST representation of expansion in assignables / parameters
The previous representation didn't properly model the fact that an
assignable / parameter can only be expanded, if it's a list element. This
now better models this. Other than being more correct, this should also
make evaluating these a bit easier.

While I was at it, I also improved the error message for multiple
expansions on the same level and added tests for these.
2022-01-07 23:08:25 +01:00
92dc89d3ca Move {=>apfl_}print_indented out of expr.c
We'll soon need it elsewhere.
2022-01-02 16:53:26 +01:00
f685214abe Add apfl_string_eq macro
It's easy to forget the `== 0` after the apfl_string_cmp() call, so let's
add a macro that does the job for us.
2022-01-02 16:51:19 +01:00
0995739ca8 Parser: Do a better job at cleaning up temporary allocations
-fsanitize=memory no longer finds any memory leak in the parser test suite.
We don't yet test error cases, but still pretty good :).
2021-12-18 21:42:48 +01:00
4908386435 expr: Also print position on variables and constants 2021-12-17 21:07:45 +01:00
10a99d0b1e expr: Fix silly bug in equality check 2021-12-16 23:42:11 +01:00
808219f9c7 expr: Fix printing assignments 2021-12-15 23:11:54 +01:00
fd3c5702ca expr: More consistent and easier to read printing 2021-12-15 21:47:17 +01:00
ade0972d67 expr: Fix moving listlike structures 2021-12-15 21:47:17 +01:00
d094ed7bd5 Initial commit 2021-12-15 21:47:17 +01:00