changeset 82:7f331aa5abd1

func, doc: Describe in-place evaluation
author Lewin Bormann <lbo@spheniscida.de>
date Mon, 26 Aug 2019 09:41:13 +0200
parents e5d39401bc29
children b86bc111f4a4
files doc/execution.md doc/syntax.md src/eval.h
diffstat 3 files changed, 36 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/doc/execution.md	Mon Aug 26 08:45:27 2019 +0200
+++ b/doc/execution.md	Mon Aug 26 09:41:13 2019 +0200
@@ -115,11 +115,30 @@
 Arguments are passed by value, so expressions are cloned into the arguments'
 slots. The arguments are described in the `yfunc_t` struct.
 
-The return value is the value of the last expression. It is pushed onto the call
-stack; it will be popped from there after the function's execution.
+The return value is the value of the last expression.
+
+All this logic happens within `yeval()`; it binds arguments when calling
+functions and handles the return value.
 
 ## Evaluation
 
 -> see `yeval()` in `eval.h`.
 
-Evaluation happens recursively.
+Evaluation happens recursively. Each evaluation results in a new `yexpr_t`
+value.
+
+### In-place evaluation
+
+Often, the result of an evaluation is not needed afterwards, because all that
+was wanted are the side effects. In this case, it is not sensible to allocate
+memory for the resulting expression.
+
+The `in_place` option can be set in `yeval()` to avoid allocating memory to
+store the result in. The evaluated expression remains untouched.
+
+It may ONLY be set if
+
+* `yeval()` evaluates expressions within a function that are not the last
+expression (and thus don't need to be returned to the caller).
+* `yeval()` is called with `in_place` already set.
+
--- a/doc/syntax.md	Mon Aug 26 08:45:27 2019 +0200
+++ b/doc/syntax.md	Mon Aug 26 09:41:13 2019 +0200
@@ -23,11 +23,11 @@
 #### `let`: Assign variable
 
 ```
-(let var val)
+(let var exprs.. expr)
 ```
 
 The name is visible in the same and all lower scopes, where a scope is an
-s-expr.
+s-expr. The value of the last `expr` will be assigned to the variable.
 
 ### Control structures
 
--- a/src/eval.h	Mon Aug 26 08:45:27 2019 +0200
+++ b/src/eval.h	Mon Aug 26 09:41:13 2019 +0200
@@ -10,10 +10,14 @@
  * @{
  */
 
-/// Evaluation state passed to invocations of `yeval`.
+/// Evaluation state passed to invocations of `yeval`. There only exists one
+/// instance of this value per program, so per-eval-call information should be
+/// passed directly to yeval.
 typedef struct {
-    /// A vector of yexpr_t that is used by called functions to take arguments from.
+    /// A vector of yexpr_t that is used by called built-in functions to take
+    /// arguments from. Normal functions use pre-bound references.
     yvec_t call_stack;
+
     // TODO: Maybe move value and atom tables in here? For now, it doesn't make
     // a difference.
 } yeval_state_t;
@@ -26,8 +30,13 @@
  * ownership of the supplied expression.
  *
  * `yeval` calls itself recursively during program execution.
+ *
+ * If in_place is set, yeval will evaluate the given expression without
+ * returning its result. This reduces memory allocations to where they are
+ * needed, namely at the end of function calls, where an expression is returned.
+ * If set, the return value should be ignored.
  */
-yexpr_t yeval(yeval_state_t* state, yexpr_t* expr);
+yexpr_t yeval(yeval_state_t* state, yexpr_t* expr, bool in_place);
 
 /**
  * @}