From ba71a9d0596cabedb68bde81a882f9505f401900 Mon Sep 17 00:00:00 2001 From: Benjamin Vedder Date: Thu, 3 Nov 2022 15:44:43 +0100 Subject: [PATCH] Squashed 'lispBM/lispBM/' changes from 7392b499..0242183a 0242183a Eval-program destructively updated the program to evaluate. This is OK only if there are no other references to this program. 712714d3 fix typo lbmref e3c7b29a update lbmref entry on eval-program git-subtree-dir: lispBM/lispBM git-subtree-split: 0242183af30661ba58d9616a35419403b14b4560 --- doc/lbmref.md | 19 ++++++++++++------- src/eval_cps.c | 19 +++++++++++-------- src/heap.c | 2 +- tests/test_eval_program_1.lisp | 5 +++++ tests/test_eval_program_2.lisp | 4 ++++ tests/test_eval_program_3.lisp | 4 ++++ tests/test_eval_program_4.lisp | 5 +++++ 7 files changed, 42 insertions(+), 16 deletions(-) create mode 100644 tests/test_eval_program_1.lisp create mode 100644 tests/test_eval_program_2.lisp create mode 100644 tests/test_eval_program_3.lisp create mode 100644 tests/test_eval_program_4.lisp diff --git a/doc/lbmref.md b/doc/lbmref.md index b1fdd3ea..3ed66302 100644 --- a/doc/lbmref.md +++ b/doc/lbmref.md @@ -458,13 +458,18 @@ Example that evaluates to 3. Evaluate a list of data where each element represents an expression. -This function interacts with the continuation passing style -of the evaluator in a slightly non-intuitive way and should -be avoided in programs. It is used internally by the c-interoperation -code to start evaluation of newly loaded program. +Example that results in the value 15: +``` +(define prg '( (+ 1 2) (+ 3 4) (+ 10 5))) +(eval-program prg) +``` + +Example that prints the strings "apa", "bepa" and "cepa": +``` +(define prg '( (print "apa") (print "bepa") (print "cepa"))) +(eval-program prg) +``` -If you want to evaluate a program you can always use `eval` and -put the program you wish to evaluate in a `progn` form. --- @@ -547,7 +552,7 @@ The example below evaluates to 0 if a is less than or equal to 4. Otherwise it e ### cond `cond` is a generalization of `if` to discern between n different cases -based on boolean expression. The form of a `cond` expression is: +based on boolean expressions. The form of a `cond` expression is: `(cond ( cond-expr1 expr1) (cond-expr2 expr2) ... (cond-exprN exprN))`. The conditions are checked from first to last and for the first `cond-exprN` that evaluates to true, the corresponding `exprN` is evaluated. diff --git a/src/eval_cps.c b/src/eval_cps.c index 746e565d..bdad5937 100644 --- a/src/eval_cps.c +++ b/src/eval_cps.c @@ -1746,17 +1746,20 @@ static void apply_eval_program(lbm_value *args, lbm_uint nargs, eval_context_t * lbm_value app_cont; lbm_value app_cont_prg; lbm_value new_prg; - if (ctx->K.sp > nargs+2) { // if there is a continuation - WITH_GC(app_cont, lbm_cons(ENC_SYM_APP_CONT, ENC_SYM_NIL)); - WITH_GC_1(app_cont_prg, lbm_cons(app_cont, ENC_SYM_NIL), app_cont); - new_prg = lbm_list_append(app_cont_prg, ctx->program); - new_prg = lbm_list_append(prg, new_prg); - } else { - new_prg = lbm_list_append(prg, ctx->program); - } + lbm_value prg_copy; + + WITH_GC(prg_copy, lbm_list_copy(prg)); lbm_stack_drop(&ctx->K, nargs+1); + if (ctx->K.sp > nargs+2) { // if there is a continuation + WITH_GC_1(app_cont, lbm_cons(ENC_SYM_APP_CONT, ENC_SYM_NIL), prg_copy); + WITH_GC_2(app_cont_prg, lbm_cons(app_cont, ENC_SYM_NIL), app_cont, prg_copy); + new_prg = lbm_list_append(app_cont_prg, ctx->program); + new_prg = lbm_list_append(prg_copy, new_prg); + } else { + new_prg = lbm_list_append(prg_copy, ctx->program); + } if (lbm_type_of(new_prg) != LBM_TYPE_CONS) { error_ctx(ENC_SYM_EERROR); return; diff --git a/src/heap.c b/src/heap.c index 6e39554d..05bcdd61 100644 --- a/src/heap.c +++ b/src/heap.c @@ -862,7 +862,7 @@ lbm_value lbm_list_copy(lbm_value list) { curr = lbm_cdr(curr); } - return lbm_list_reverse(res); + return lbm_list_destructive_reverse(res); } // Append for proper lists only diff --git a/tests/test_eval_program_1.lisp b/tests/test_eval_program_1.lisp new file mode 100644 index 00000000..c6362139 --- /dev/null +++ b/tests/test_eval_program_1.lisp @@ -0,0 +1,5 @@ + +(define prg '( (+ 1 2) (+ 3 4) (+ 10 5))) + + +(= (eval-program prg) 15) diff --git a/tests/test_eval_program_2.lisp b/tests/test_eval_program_2.lisp new file mode 100644 index 00000000..a020b266 --- /dev/null +++ b/tests/test_eval_program_2.lisp @@ -0,0 +1,4 @@ +(define prg '( (eval-program '( (+ 1 2) (+ 2 3) (+ 10 5))))) + + +(= (eval-program prg) 15) diff --git a/tests/test_eval_program_3.lisp b/tests/test_eval_program_3.lisp new file mode 100644 index 00000000..7c7bd0b9 --- /dev/null +++ b/tests/test_eval_program_3.lisp @@ -0,0 +1,4 @@ +(define prg (list (eval-program (list (+ 1 2) (+ 2 3) (+ 10 5))))) + + +(= (eval-program prg) 15) diff --git a/tests/test_eval_program_4.lisp b/tests/test_eval_program_4.lisp new file mode 100644 index 00000000..a4995e3d --- /dev/null +++ b/tests/test_eval_program_4.lisp @@ -0,0 +1,5 @@ +(define prg (list (eval-program (list (+ 1 2) (+ 2 3) (+ 10 5))))) +(define r (+ 100 (eval-program prg))) + + +(= (eval-program prg) 15)