Mercurial > lbo > hg > ylisp
changeset 148:1620bde57dcb
expr: Implement yexpr_equal
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Tue, 03 Sep 2019 12:16:44 +0200 |
parents | 1e9d534b903d |
children | df0e17d18c80 |
files | src/expr.c src/expr.h |
diffstat | 2 files changed, 42 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/src/expr.c Tue Sep 03 12:16:23 2019 +0200 +++ b/src/expr.c Tue Sep 03 12:16:44 2019 +0200 @@ -76,12 +76,14 @@ break; case YEXPR_LIST: // Recursively copy list... - yvec_init(©.value.list, orig->value.list.size, orig->value.list.len); + yvec_init(©.value.list, orig->value.list.size, + orig->value.list.len); yvec_resize(©.value.list, orig->value.list.len); #define _list (&orig->value.list) #define _newlist (©.value.list) for (size_t i = 0; i < _list->len; i++) - *YVEC_AT(_newlist, i, yexpr_t) = yexpr_copy(YVEC_AT(_list, i, yexpr_t)); + *YVEC_AT(_newlist, i, yexpr_t) = + yexpr_copy(YVEC_AT(_list, i, yexpr_t)); #undef _list #undef _newlist break; @@ -152,6 +154,39 @@ YVEC_PUSH(&v->value.list, &new_val); } +bool yexpr_equal(yexpr_t* a, yexpr_t* b) { + if (a->typ != b->typ) return false; + switch (a->typ) { + case YEXPR_UNDEF: + return true; + case YEXPR_ATOM: + return a->value.atom == b->value.atom; + case YEXPR_BUILTIN: + return a->value.builtin == b->value.builtin; + case YEXPR_NUMBER: + return a->value.n == b->value.n; + case YEXPR_STRING: + case YEXPR_EXCEPTION: + return 0 == ystr_cmp(&a->value.str, &b->value.str); + case YEXPR_REF: + if (yref_eq(&a->value.ref, &b->value.ref)) return true; + yvalue_t* aexpr = yvalue_get(a->value.ref); + yvalue_t* bexpr = yvalue_get(b->value.ref); + if (aexpr->typ != bexpr->typ) return false; + return yexpr_equal(&aexpr->value.expr, &bexpr->value.expr); + case YEXPR_LIST: + if (a->value.list.len != b->value.list.len) return false; + for (size_t i = 0; i < a->value.list.len; i++) { + if (!yexpr_equal(YVEC_AT(&a->value.list, i, yexpr_t), + YVEC_AT(&b->value.list, i, yexpr_t))) + return false; + } + return true; + default: + assert(false /* missing expression type! */); + } +} + void yexpr_init_or_extend(yexpr_t* expr, yexpr_t arg) { if (expr->typ == YEXPR_UNDEF) { yexpr_append_value(expr, arg);
--- a/src/expr.h Tue Sep 03 12:16:23 2019 +0200 +++ b/src/expr.h Tue Sep 03 12:16:44 2019 +0200 @@ -88,6 +88,11 @@ */ void yexpr_append_value(yexpr_t* v, yexpr_t new_val); +/** + * Check if two expressions are equal. + */ +bool yexpr_equal(yexpr_t* a, yexpr_t* b); + /****** helpers for parsing ******/ /**