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);