Mercurial > lbo > hg > ylisp
changeset 34:e2ef3dd81205
expr: Add reference type and yexpr_destroy
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Wed, 21 Aug 2019 10:51:14 +0200 |
parents | 4f7fdf333a42 |
children | 8ac9f39db10f |
files | src/expr.c src/expr.h |
diffstat | 2 files changed, 71 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/src/expr.c Wed Aug 21 10:50:50 2019 +0200 +++ b/src/expr.c Wed Aug 21 10:51:14 2019 +0200 @@ -1,8 +1,14 @@ #include "expr.h" #include <assert.h> +#include <stdbool.h> #include <stdio.h> +void yref_destroy(yref_t* ref) { + if (ref == NULL) return; + if (ref->typ == YREF_SYM) ystr_destroy(&ref->ref.sym); +} + void yexpr_set_number(yexpr_t* v, long long n) { v->typ = YEXPR_NUMBER; v->value.n = n; @@ -18,6 +24,32 @@ memset(&v->value, 0, sizeof(v->value)); } +void yexpr_destroy(yexpr_t* v) { + if (v == NULL) return; + switch (v->typ) { + case YEXPR_UNDEF: + case YEXPR_NUMBER: + case YEXPR_ATOM: + return; + case YEXPR_STRING: + ystr_destroy(&v->value.str); + return; + case YEXPR_REF: + // TODO: maybe reference-count the reference here. + yref_destroy(&v->value.ref); + return; + case YEXPR_LIST: +#define list (&v->value.list) + for (size_t i = 0; i < list->len; i++) + yexpr_destroy(YVEC_AT(list, i, yexpr_t)); + yvec_destroy(list); +#undef list + return; + default: + assert(false /* handle all cases!! */); + } +} + void yexpr_set_atom(yexpr_t* v, const char* atom_name) { v->typ = YEXPR_ATOM; v->value.atom = yatom_get_or_add(atom_name);
--- a/src/expr.h Wed Aug 21 10:50:50 2019 +0200 +++ b/src/expr.h Wed Aug 21 10:51:14 2019 +0200 @@ -2,6 +2,7 @@ #define src_expr_h #include <src/atom.h> + #include <stdio.h> #include <string.h> @@ -14,6 +15,31 @@ * @{ */ +typedef uint64_t yvalue_id_t; + +enum YREF_TYPE { + YREF_UNDEF = 0, + YREF_ID = 1, + YREF_SYM = 2, +}; + +/** + * @brief A reference to a stored function or value. To be used as value (not + * pointer). + */ +typedef struct { + union { + ystr_t sym; + yvalue_id_t id; + } ref; + enum YREF_TYPE typ; +} yref_t; + +/** + * @brief Deallocate memory used by the reference itself. + */ +void yref_destroy(yref_t* ref); + /** * Type of an yexpr_t value. */ @@ -23,6 +49,7 @@ YEXPR_STRING = 2, YEXPR_ATOM = 3, YEXPR_LIST = 4, + YEXPR_REF = 5, } YEXPR_TYPE; /** @@ -30,13 +57,19 @@ * of values. */ struct yexpr_t { - YEXPR_TYPE typ; union { + /// A literal string. ystr_t str; + /// A list of yexpr_t. yvec_t list; + /// A number. long long n; + /// An atom. yatom_t atom; + /// A named reference (to a value or function described by yvalue_t). + yref_t ref; } value; + YEXPR_TYPE typ; }; typedef struct yexpr_t yexpr_t; @@ -46,6 +79,11 @@ void yexpr_init(yexpr_t* v); /** + * Deallocate all memory occupied by expr and any subexpressions. + */ +void yexpr_destroy(yexpr_t* v); + +/** * Initialize a yexpr_t with a number. */ void yexpr_set_number(yexpr_t* v, long long n);