Mercurial > lbo > hg > ylisp
changeset 115:1d1f29d0954d
eval: Fix in-place evaluation of lists and strings
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Thu, 29 Aug 2019 22:48:22 +0200 |
parents | 4107207b761d |
children | 3267a9631763 |
files | src/eval.c |
diffstat | 1 files changed, 10 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/src/eval.c Thu Aug 29 22:48:04 2019 +0200 +++ b/src/eval.c Thu Aug 29 22:48:22 2019 +0200 @@ -4,8 +4,6 @@ #include <src/expr.h> #include <src/value.h> -static void nothing(void){/* labels need to be followed by statement */}; - yexpr_t yeval_call_func(yvalue_t* ref, yexpr_t* call) { return yexpr_new(); } yexpr_t yeval_list_return_last(yeval_state_t* state, yvec_t* list, size_t off) { @@ -23,19 +21,22 @@ switch (expr->typ) { case YEXPR_ATOM: case YEXPR_NUMBER: - case YEXPR_STRING: case YEXPR_EXCEPTION: case YEXPR_BUILTIN: if (in_place) break; // values can't have side effects // Flat copy is enough. return *expr; + case YEXPR_STRING: + if (in_place) break; + result = *expr; + result.value.str = ystr_new(ystr_str(&expr->value.str)); + return result; case YEXPR_REF: // Reference is resolved if expr-ref. func-refs are not resolved. // NOTE: Can this result in infinite recursion? - nothing(); + if (in_place) break; // values can't have side effects yvalue_t* val = yvalue_get(expr->value.ref); if (val->typ == YVALUE_EXPR) { - if (in_place) break; // values can't have side effects result = yexpr_copy(&val->value.expr); return result; } else if (val->typ == YVALUE_FUNC) { @@ -78,6 +79,8 @@ } } + result = *expr; + // Don't store results if (in_place) { for (size_t i = 0; i < result.value.list.len; i++) { @@ -89,7 +92,8 @@ return result; } - result = *expr; + // Store results; input list is copied shallowly, and assigned with + // copied values from yeval. result.value.list = yvec_clone(&expr->value.list); for (size_t i = 0; i < result.value.list.len; i++) { yexpr_t* elem = YVEC_AT(&result.value.list, i, yexpr_t);