Commit graph

155 commits

Author SHA1 Message Date
874638748b Make iterative runner not panic on OOM
The iterative runner used functions that could throw errors on OOM before
protecting itself using apfl_call_protected. An error at that point would
have resulted in calling the panic handler as a last resort.

This now introduces the apfl_do_protected function which allows running C
code protected without needing to wrap it in a cfunc value, thus removing
the need for the functions that could throw in the iterative runner.
2022-11-20 21:44:00 +01:00
e8a92a18b4 Implement functions for concatenating strings 2022-11-20 21:44:00 +01:00
f9878b43d8 Implement comparison operators 2022-11-20 13:47:38 +01:00
3bbd0e79a1 Implement predicates
This implements the last remaining feature of the language syntax! :)

The implementation of this was delightfully simple, since all the heavy
lifting is done by already implemented functions.
2022-11-19 23:26:59 +01:00
3d7bef187c Matchers: Don't return twice when value to capture is missing
We called return_from_matcher once inside
matcher_evaluate_capturing_instruction and outside of it. That way we
returned not to the parent call stack entry but to the grandparent.
2022-11-19 23:26:59 +01:00
20c2880f4c Implement assigning into dictionaries
It's now possible to assign to a key of a dictionary and even to a nested
key path.

This patch changes the way matchers work a bit:
First, a function call stack frame now has a stack of matchers that are
manipulateable instead of a single matcher.
Second, the matcher is now in charge of setting the matched values to the
variables (previously the caller of the matcher needed to extract the
matched values and assign them itself). This change simplifies code
generation, especially for chained assignments and dictionary key paths.

This removes the last usage of APFL_ERR_NOT_IMPLEMENTED :)
2022-11-19 23:26:52 +01:00
f0811ba8fe Implement global "gc" function
To dump the current GC state and do a manual collection
2022-11-19 22:21:32 +01:00
7c5465d266 Add a test for chained assignments 2022-11-19 21:27:08 +01:00
0267faede3 Rename matcher_stack -> matcher_state_stack
It's not a stack of matchers, a thing we'll soon need. So let's rename
this.
2022-11-08 22:03:05 +01:00
0682b5464d Add test for == function 2022-11-08 22:03:05 +01:00
369a94cbca compile: Remove dead code 2022-11-08 22:03:05 +01:00
97d79754dd Implement while 2022-11-08 22:03:05 +01:00
742bd66b46 context: Fix apfl_is_truthy not popping the input off the stack 2022-11-08 22:02:57 +01:00
18ae382414 Add test for if 2022-10-31 15:50:51 +01:00
0836b8c97c Implement global functions not, len and type 2022-10-31 15:29:01 +01:00
154cc42740 globals: Fix math operations returning argument list on single arg 2022-10-30 23:08:41 +01:00
39578c9478 Add more functional tests 2022-10-30 23:07:53 +01:00
363334967a Implement tostring and use it in print 2022-10-30 22:51:51 +01:00
4ecfeabded main+playground: Don't print nil values in repl
This makes the output of `print` in the repl nicer :)
2022-10-30 22:51:51 +01:00
c18df0ab19 Make apfl_string_builder_init easier to use
It was a bit silly that you've first had to declare a string builder
variable and then pass a reference to that into the init function, which
could not fail. Instead just return a ready to use string builder :)
2022-10-30 22:51:51 +01:00
b7015e7b13 Implement a simple test runner for functional tests 2022-10-30 22:51:51 +01:00
145fcddbed format: Use %G to print numbers
This avoids appending .000[...] on integer numbers
2022-10-30 22:51:51 +01:00
9f7c823103 Don't ignore result type in iterative runner
-.-
2022-10-30 21:21:40 +01:00
62e859638e Fix web playground includes 2022-10-30 21:21:40 +01:00
fa4ed7bf83 Abstract away stdout
Instead of using stdout directly, we're now using a configurable
apfl_format_writer.
2022-10-30 21:21:40 +01:00
136a6da06b value: Fix equality check for list
m(
2022-10-04 22:33:00 +02:00
3aabadbf6d Switch to CMake 2022-09-16 23:04:20 +02:00
8ca24bcd49 Implement subfunctions and argument matching
A function can now have multiple subfunctions with their own parameter
list. These parameters are now no longer constrained to variables and
blanks only, but can also be consts and list destructurings (predicates
are also already compiled but don't get evaluated yet). The first
subfunction that matches the argument list gets evaluated.
2022-08-13 00:50:26 +02:00
0474a85c6f gc: New debug flag to log oject creation/destruction 2022-08-12 14:50:28 +02:00
42fe4f6b33 matcher: Fix relying on GC'ed milist in deinit function
When the GC calls the matchers deinit function, the milist (also an GC-able
object) might already have been deinitialized, so we can't use the count
values from there.

Maybe milist should actually be refcounted? It doesn't build cycles and
doesn't reference other GC objects. This would simplify it and remove the
now duplicated count data.
2022-08-12 14:42:49 +02:00
6d77715e0d eval: Set returning_from_matcher while cse ist still valid
matcher_init_matching appends an element of the call stack, so the cse
pointer into the stack is no longer valid.
2022-08-06 12:53:24 +02:00
a160dea021 compile: Move milist into compile_assignable_ilists
This makes the function signatures a bit smaller.
2022-08-04 22:25:04 +02:00
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