Commit graph

123 commits

Author SHA1 Message Date
9b84a52f77 Make sure the currently loaded matcher is rooted 2022-08-04 22:23:21 +02:00
19a5191e59 compile: Make sure the matcher is not overridden in nested assignments 2022-08-04 21:42:46 +02:00
d731fa828a eval: Guard against matcher being NULL when matching 2022-07-31 22:04:59 +02:00
41d0ee6132 bytecode: Add a function to dump bytecode
This also exposes it as a global function and removes the debug statements
in the compiler.
2022-07-28 20:49:29 +02:00
1630314dc7 Implement matching assignments
This allows the destructuring of lists into individual values.
We can have arbitrarily nested lists, can check for constant values and can
have up to one '~'-prefixed variable per list, that will capture the
remaining elements of the list.

It is implemented as a second set of bytecode instructions, which define a
matcher. These matchers should also enable us to implement the same pattern
matching capabiities for function parameters.

Not all matching features are implemented yet, predicate matching and
matching into a dictionary key is not implemented yet.
2022-07-28 20:46:32 +02:00
e61caea2ff README: Fix typos 2022-07-27 23:48:44 +02:00
b033983d52 main: Make eval the default mode 2022-07-15 21:57:35 +02:00
55fb3c6345 gc: Add some optional debugging features 2022-07-15 21:56:30 +02:00
7e592cdb96 gc: Prevent recursive garbage collection 2022-07-14 22:08:50 +02:00
1a41df2389 format: Don't try (and fail) to write an empty buffer
We failed at dumping empty strings, because the file writer reported 0
bytes written as an error. Let's just not write empty buffers in the first
place, this fixes the bug and also avoids some pointless function calls.
2022-07-14 21:51:41 +02:00
3fcf4f4c49 GC+context: Fix GC reaching some invalid pointers / dead objects 2022-07-14 21:13:43 +02:00
7c63a6b189 globals: Add if, ==, dump and basic math ops 2022-07-12 23:24:19 +02:00
4f9a33628c Implement first global function "print"
This introduces the globals and moves some previously non-public functions
into apfl.h.
2022-07-12 22:13:07 +02:00
a4f7f0f2ff Implement functions and function calls
We can now define and call functions. Lexical closure scopes are also
working :).

It's limited to simple functions or complex functions with a single
argument list of only variable names for now.
2022-07-11 21:41:05 +02:00
eb7cb0baf7 gc+context: Make stack no longer a gc object
The new roots callback mechanism makes it possible to traverse the gc
objects on the stack without needing the stack to be an gc object.

This also uncovered a nasty bug in apfl_stack_pop where we passed in a
wrong mem pointer into apfl_resizable_splice. We should probably find a way
to make the apfl_resizable_* functions a bit safer, the need for casting
stuff to void** easily hides errors.
2022-07-01 22:40:43 +02:00
1a23c63ec6 gc+bytecode: Fully visit all instruction_list children
We accidentally stopped at the first child before m(
2022-07-01 22:03:52 +02:00
c974b675e1 gc: Use a callback to get the (non-tmp) roots
This let's us get rid of that awkward hashmap in the GC that was used as a
set, makes determining the roots more flexible and now gc_init can't even
fail any more, as there are no allocations happening here any more :)
2022-07-01 22:00:58 +02:00
8d947244c9 Implement exceptions-like error handling
Most functzions will no longer return an enum apfl_result, but will raise
an error that bubbles up.
2022-06-26 16:06:14 +02:00
4b9170969b compile.c: Extract common ilist put code into macro 2022-06-17 20:22:05 +02:00
2c04e57a0c Implement a simple web playground REPL with emscripten 2022-06-05 22:31:02 +02:00
64f2be5afc Move variable out of switch
This doesn't complie with emcc
2022-06-05 22:30:18 +02:00
09f7df79bb apfl_debug_print_val: Use format writer abstraction 2022-06-05 22:06:33 +02:00
a773e929bf Fix checking type of wrong value
We already checked dst_val, we need to check src_val too!
2022-04-24 16:45:25 +02:00
ad141a86fb Push some errors as const strings onto the stack 2022-04-24 16:13:39 +02:00
24c283c85f compile: Use apfl_string_move_into_new_gc_string 2022-04-23 22:46:27 +02:00
bb89b2ae49 Add constant string values 2022-04-23 22:15:10 +02:00
0de243995b Ditch that weird internal.h header 2022-04-22 23:17:28 +02:00
d1b2ba7a53 Use formatter for printing values 2022-04-22 23:13:01 +02:00
a4fd3acfac Use formatter for expr printing 2022-04-22 22:52:53 +02:00
b4a7dfe1f6 Move allocation macros from internal.h to alloc.h 2022-04-22 21:43:19 +02:00
29d9c75c4e Add functions for creating nil/bool/number/string values 2022-04-22 21:39:03 +02:00
7c3a760ebf gitignore: Ignore make dist/distcheck generated files 2022-04-21 22:57:22 +02:00
0f6f136873 Push formatted parser error on stack during evaluation
This way we can see the parse errors again in evaluation mode

Not fully fleshed out yet: We simply use apfl_debug_print_val to dump the
top of the stack (the formatted error) to stderr but don't nicely handle
if there is nothing on the stack (apfl_debug_print_val will print a rather
cryptic "stack index invalid" error). Also the whole dance we need to do to
put the formatted error onto the stack feels rather awkward (there should
probably a function for this) and we also should probably try to push an
error description on the stack in case this moving-string-to-stack business
fails.

Now "only" all other errors need to be put on the stack as a string :)
2022-04-21 22:55:11 +02:00
f8bab311d7 Add formatter abstraction for errors
This will allow us to format errors as strings later by implementing a
different format writer.
2022-04-21 22:14:37 +02:00
9ce5c20736 No longer evaluate exprs directly 2022-04-21 21:17:17 +02:00
b7c88635d9 Redo source reader interface
The callback and the opaque data are now grouped together in a struct
instead of being passed individually into the tokenizer.

This also exposes the string source reader struct and therefore removes
the need of heap allocating it. Neat!
2022-04-15 22:35:36 +02:00
70c3d6e3e4 README: Fix spelling mistakes 2022-04-15 17:13:30 +02:00
82a9858902 apfl_value_hash: Return directly instead of "goto ok" 2022-04-15 14:49:28 +02:00
b3322c93e9 Move scope functions/structs out of context.[ch] 2022-04-15 14:41:22 +02:00
6add5e47b9 hashmap: Improve cursor / peek API
- peek functions will now return pointers directly
- cursor access methods can now return an error, if the cursor is already
  at the end

Also rewrote some cursor loops to use the HASHMAP_EACH macro.
2022-04-11 23:31:20 +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
4088fdd1c3 Fix typo 2022-02-25 21:54:27 +01:00
bb464d8226 Hashmap: Implement prepared setting
With a prepared set, the potential allocation, which can fail, is split
from the actual setting, which can not fail.
2022-02-25 20:50:43 +01:00
40320aaa4a Fix copying dicts
We didn't properly copy the opaque value before (a heap-allocated allocator
pointer), resulting in a use-after-free of the opaque on the copied map if
the old map was destroyed.
2022-02-15 22:32:15 +01:00
8df0991415 eval.c: Don't create copy of already refcounted string 2022-02-14 21:56:36 +01:00
5f8462fe34 Add apfl_stackidx typedef
This makes it clear that a value of that type is meant as an index into the
stack.
2022-02-10 22:39:39 +01:00
09c6459565 Fix typo 2022-02-10 22:04:48 +01:00
d86c9375a4 Shorter name for internal enum apfl_value_type 2022-02-10 21:56:48 +01:00
dd314c5abb Shorter name for internal enum get_item_result 2022-02-10 21:56:30 +01:00