view src/eval.h @ 132:bad34d9a4443

eval: Implement function calls (with stack-refs)
author Lewin Bormann <lbo@spheniscida.de>
date Sun, 01 Sep 2019 19:24:24 +0200
parents 63650268d006
children 3ec2b2edb977
line wrap: on
line source

#ifndef src_eval_h
#define src_eval_h

#include "base/vec.h"
#include "types.h"

/**
 * @file eval.h
 * @brief Evaluating ylisp expressions.
 * @addtogroup execution
 * @{
 */

/// 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 vec of expressions that can be used for storing intermediate values in
    /// a quick way (push/pop is fast on pre-allocated memory).
    yvec_t call_stack;

    // TODO: Maybe move value and atom tables in here? For now, it doesn't make
    // a difference.
} yeval_state_t;

/**
 * @brief Evaluate a list of expressions starting at off, but only return the
 * last one. Used to run functions or other constructs that evaluate expressions
 * for their side-effects.
 */
yexpr_t yeval_list_return_last(yeval_state_t* state, yvec_t* list, size_t off);

/**
 * @brief The core of ylisp: Evaluate an expression, resulting in a new
 * expression.
 *
 * The caller takes ownership of the returned expression. `yeval` does not take
 * ownership of the supplied expression and does not modify or destroy any
 * children of it (this is important for recursive evaluation).
 *
 * `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, bool in_place);

/**
 * @}
 */

#endif