Mercurial > lbo > hg > ylisp
changeset 178:d9c942e7f1ad
expr: Integrate YEXPR_FUNC into expr functions (copy, destroy, debug...)
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Thu, 12 Sep 2019 08:24:52 +0200 |
parents | e55251d97380 |
children | 53dc68a0488d |
files | src/expr.c |
diffstat | 1 files changed, 41 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/src/expr.c Thu Sep 12 08:24:29 2019 +0200 +++ b/src/expr.c Thu Sep 12 08:24:52 2019 +0200 @@ -45,6 +45,13 @@ yvec_destroy(list); #undef list break; + case YEXPR_FUNC: + for (size_t i = 0; i < v->value.closure->captured.len; i++) + yexpr_destroy(YVEC_AT(&v->value.closure->captured, i, yexpr_t)); + yvec_destroy(&v->value.closure->captured); + yref_destroy(&v->value.closure->id); + free(v->value.closure); + break; default: assert(false /* handle all cases!! */); } @@ -74,6 +81,17 @@ copy = *orig; copy.value.ref = yref_clone(&orig->value.ref); break; + case YEXPR_FUNC: + copy.value.closure = malloc(sizeof(yclosure_t)); + copy.value.closure->captured = + yvec_clone(&orig->value.closure->captured); + yvec_t* captured = ©.value.closure->captured; + for (size_t i = 0; i < captured->len; i++) { + *YVEC_AT(captured, i, yexpr_t) = yexpr_copy( + YVEC_AT(&orig->value.closure->captured, i, yexpr_t)); + } + copy.value.closure->id = yref_clone(&orig->value.closure->id); + break; case YEXPR_LIST: // Recursively copy list... yvec_init(©.value.list, orig->value.list.size, @@ -144,6 +162,15 @@ v->value.str = message; } +void yexpr_set_closure(yexpr_t* v, yref_t funcref, yvec_t captured) { + yexpr_destroy(v); + v->typ = YEXPR_FUNC; + v->value.closure = malloc(sizeof(yclosure_t)); + yclosure_t* closure = v->value.closure; + closure->id = funcref; + closure->captured = captured; +} + void yexpr_append_value(yexpr_t* v, yexpr_t new_val) { assert(v->typ == YEXPR_UNDEF || v->typ == YEXPR_LIST); @@ -243,6 +270,20 @@ case YEXPR_EXCEPTION: ystr_build(&tmp, "EXCEPTION<%s>", ystr_str(&expr->value.str)); break; + case YEXPR_FUNC: + ystr_build(&tmp, "CLOSURE"); + yvalue_t* funcval = yvalue_get(expr->value.closure->id); + if (funcval == NULL) { + ystr_build(&tmp, "<INVALID-REF>"); + break; + } + if (funcval->typ != YVALUE_FUNC) { + ystr_build(&tmp, "<INVALID-VALUE-REF>"); + break; + } + yfunc_t* func = &funcval->value.func; + ystr_build(&tmp, "<%s>", ystr_str(&func->name)); + break; default: assert(false /* Unhandled YEXPR_TYPE */); }