Commit graph

19 commits

Author SHA1 Message Date
dd314c5abb Shorter name for internal enum get_item_result 2022-02-10 21:56:30 +01:00
78bd057c37 eval.c: Free the stack with FREE_LIST instead of FREE_OBJ
This way we pass the correct oldsize to the allocator.
2022-02-09 20:44:21 +01: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
2966d6dc7c hashmap: Don't hide hashmap struct behind a pointer any more
Since the hashmap is meant for internal use only, there is no need to hide
the internal data. This also allows us to save some malloc() calls.
2022-01-22 15:55:56 +01:00
21efc85dba Convert to Lua-style stack API
Only for evaluating expressions for now and right now the only exposed
operation is to debug print a value on the stack, this obviously needs to
be expanded.

I've done this for two reasons:

1. A Lua-style stack API is much nicer to work with than to manually manage
   refcounts.
2. We'll soon need a more sophisticated garbage collector (if you even want
   to count the refcounting as garbage collection). For this, the GC will
   need root objects to start tracing for live objects, the stack will be
   one of these roots.
2022-01-20 22:45:09 +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
c9a935b161 Support assigning into dictionaries
You can now set keys in dictionaries to a value. If a key in a key path is
missing, we automatically create an empty dictionary. Otherwise setting
deeply nested keys becomes annoying.
2022-01-15 23:09:24 +01:00
a14b490dfe Partially implement pattern matching assignments
We're still missing predicates (need to be able to call functions for that
one) and assignments into dictionaries. But we now can deconstruct a list
and check against constants.

So things like this work now:

	[1 foo ~bar [a b]] = [1 "Hello" 2 3 4 [5 6]]
	# foo is: "Hello"
	# bar is: [2 3 4]
	# a is: 5
	# b is: 6

Pretty cool :)
2022-01-14 23:25:57 +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
ac3af0baf1 apfl_ctx_destroy: Do nothing on NULL input 2022-01-08 22:09:43 +01:00
e928f40da4 Implement simple variable support
We can now assign to variables and retrieve their values. Not all
assignables are implemented yet, but still pretty cool :).
2022-01-06 22:53:26 +01:00
721d2d2d21 Implement evaluating container member access 2022-01-05 00:25:41 +01:00
0384875ef3 values: Split lists into read-only lists and editable lists
This is analogous to dictionaries and ensures that no circular references
can be created when using the exported API in apfl.h.

This also changes apfl_value_copy into apfl_value_incref to better reflect
what it does and to reflect that it is no longer an operation that can
fail.
2022-01-04 23:11:38 +01:00
f3d0bbed17 Implement evaluating dictionary literals
We can now have dictionaries with keys and values of arbitrary types.
Very cool! :)
2022-01-04 21:51:44 +01:00
eaa6b723bc Fix refcounted strings
Increasing the refcount (confusingly called copy before, fixed that too)
didn't work properly, as the object was copied and the refcount was only
updated in one of the copies.
2022-01-04 21:22:46 +01:00
4cd95d32c5 eval.c: Handle errors during evaluating string constants 2022-01-02 21:20:08 +01:00
b29219af25 Make strings in apfl_value refcounted
This avoids copying the string every time we pass it around. Not too
important right now, but will become important onve we're able to evaluate
more complex expressions.
2022-01-02 17:55:44 +01:00
649607ce50 Start work on evaluating expressions
Right now we're only evaluating bool/nil/number/string/list literals, but
it's a start :).
2022-01-02 17:22:22 +01:00