Mercurial > lbo > hg > ylisp
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); /** * @}