Commit graph

55 commits

Author SHA1 Message Date
3ec6aeb106 Fixing uninitialized vars etc found by building with -O2 2024-08-25 18:16:36 +02:00
e5c4f32126 refactor 2023-11-24 21:57:57 +01:00
396c5ad866 gc: Tighter coupling to full context
We'll soon need the whole apfl_ctx in the garbage collector.
2023-11-23 21:30:51 +01:00
0361000e7c apflc: Use an apfl_ctx for compilation
We'll soon need the full apfl_ctx, where we previously only needed the
gc. apflc was the only place manually constructing a struct gc without
an apfl_ctx, so lets change that.
2023-11-23 21:03:40 +01:00
ddd39f19ef Implement global slice and splice functions
This also adds the apfl_list_splice() function for manipulating lists.
2023-10-26 21:31:27 +02:00
63d64b0778 Add regex module "re"
This uses the PCRE2 library to implement regexes in apfl
2023-07-03 23:53:09 +02:00
1650a8f8be Fix NDEBUG builds 2023-07-03 23:45:43 +02:00
35a3c808c4 Add code to debug errors when initialiting globals 2023-07-03 23:45:43 +02:00
c07caa9aa2 Implement the registry and a agrv getter to test it
The registry is a global dictionary accessible from C that stores arbitrary
apfl values.
2023-03-31 21:31:07 +02:00
1cff056e53 Implement symbol values 2023-03-23 23:44:54 +01:00
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
1634b9439b Implement for / loop / [k]each loops 2023-03-07 21:40:07 +01:00
25c872f4ee Define globals in apfl itself
We're now first building a standalone bytecode compiler `apflc` that will
compile `globals.apfl` into bytecode and write it out as a C source file.
When initializing a new context, that embedded bytecode will then get
evaluated and the global scope will be populated from the dictionary
returned by that bytecode.
2023-03-07 21:40:07 +01:00
2666c0f148 Implement bytecode (de)serialization 2023-03-07 21:40:07 +01:00
a4f7f0884d Make line and column size_t 2023-02-16 21:41:02 +01:00
f4841ff2cd Use stdnoreturn instead of our own APFL_NORETURN 2023-02-16 20:52:27 +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
0b44878fcd Remove TODO to allow const variable names
I made it possible for variable names to be const strings, only to discover
this actually used *more* heap memory instead of less. Also only very low
performance gains. So let's not do that and keep things a bit simpler.
2023-02-10 20:37:47 +01:00
3f6e1f14a9 Implement loading other scripts 2023-01-31 22:07:28 +01:00
607da73c62 Add functions for reading/writing files and introduce native objects 2023-01-29 16:46:00 +01:00
bd19f689b9 Add backtraces to errors 2023-01-28 21:44:56 +01:00
3cc2a83226 Add functions to get information about the call stack 2023-01-28 21:42:40 +01:00
1afec3c7a0 Add named functions
An `name = {}` assignment now sets the name of the function to `name`.
Also the globally defined functions are named too now.
2023-01-24 22:16:27 +01:00
dd580a1519 Improve a bunch of error messages 2023-01-24 21:30:05 +01:00
5e9ac36a39 Get rid of fatal errors and report allocation error directly 2023-01-13 22:54:06 +01:00
57cd32dfa5 Fix apfl_join_strings accessing invalid addresses
Previously we were getting a pointer into the value stack for the parts
list. However, that pointer would not necessarily be a valid pointer later
any more, as we're also manipulating the value stack.

This introduces the higher level API apfl_set_list_member_by_index to
modify a list and also adds an option for our test suite to run the tests
with valgrind --tool=memcheck. This should catch such errors in the future.
2022-11-29 23:13:10 +01:00
e4f2053ca6 Fix apfl_join_strings manipulating the parts list 2022-11-26 23:06:55 +01:00
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
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
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
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
363334967a Implement tostring and use it in print 2022-10-30 22:51:51 +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
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
9b84a52f77 Make sure the currently loaded matcher is rooted 2022-08-04 22:23:21 +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
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
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
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
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
29d9c75c4e Add functions for creating nil/bool/number/string values 2022-04-22 21:39:03 +02:00