Mercurial > lbo > hg > ylisp
changeset 147:1e9d534b903d
eval: Return type errors for undefined functions; test recursion
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Tue, 03 Sep 2019 12:16:23 +0200 |
parents | aa551e42de49 |
children | 1620bde57dcb |
files | src/eval.c src/eval_test.c |
diffstat | 2 files changed, 38 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/src/eval.c Tue Sep 03 12:15:51 2019 +0200 +++ b/src/eval.c Tue Sep 03 12:16:23 2019 +0200 @@ -117,6 +117,14 @@ // resolve as normal below; this seems to be a "data // list". } else { + yexpr_t exc = yexpr_new(); + ystr_t msg = ystr_new(NULL); + ystr_build(&msg, "possibly undefined function: "); + ystr_t dbg = yref_debug(&first->value.ref); + ystr_append(&msg, &dbg); + ystr_destroy(&dbg); + yexpr_set_exception(&exc, msg); + return exc; assert(val->typ == YVALUE_FUNC || val->typ == YVALUE_EXPR); } }
--- a/src/eval_test.c Tue Sep 03 12:15:51 2019 +0200 +++ b/src/eval_test.c Tue Sep 03 12:16:23 2019 +0200 @@ -55,9 +55,39 @@ yexpr_destroy(&result); } +void test_eval_recursion(void) { + fprintf(stderr, "test_eval_recursion ===========\n"); + + // Calculate faculty values from 1 to 10. + ystr_t input = ystr_new( + "(defn fac (n) (if (== n 0) 1 ((* n (fac (- n 1))))))" + "(for i (1 2 3 4 5 6 7 8 9 10) (fac i))"); + yexpr_t program = yexpr_new(); + ystr_t error = ystr_new(NULL); + assert(yparse_str(&input, &program, &error)); + yexpr_debug(&program); + ypreprocess(&program); + yexpr_debug(&program); + + yeval_state_t state; + state.call_stack = YVEC_NEW(NULL, 4, yexpr_t); + yexpr_t result = yeval_list_return_last(&state, &program.value.list, 0); + yexpr_debug(&result); + assert(YEXPR_LIST == result.typ); + assert(362880 == YVEC_AT(&result.value.list, 8, yexpr_t)->value.n); + + yexpr_destroy(&program); + yvec_destroy(&state.call_stack); + ystr_destroy(&error); + yexpr_destroy(&result); + ystr_destroy(&input); +} + int main(void) { test_eval_edge_cases(); test_eval_func_wrong_call(); + test_eval_recursion(); yvalue_free_all(); + yatom_free_all(); return 0; }