Add environments
authorDavid Kerkeslager <kerkeslager@gmail.com>
Sat, 24 Aug 2019 10:11:11 +0000 (06:11 -0400)
committerDavid Kerkeslager <kerkeslager@gmail.com>
Sat, 24 Aug 2019 10:11:11 +0000 (06:11 -0400)
c/environment.c [new file with mode: 0644]
c/environment.h [new file with mode: 0644]

diff --git a/c/environment.c b/c/environment.c
new file mode 100644 (file)
index 0000000..f55567d
--- /dev/null
@@ -0,0 +1,51 @@
+#ifndef ENVIRONMENT_C
+#define ENVIRONMENT_C
+
+#include<assert.h>
+
+struct EnvironmentNode;
+typedef struct EnvironmentNode EnvironmentNode;
+struct EnvironmentNode {
+  Symbol* key;
+  Object* value;
+  EnvironmentNode* next;
+};
+
+struct Environment {
+  Environment* parent;
+  EnvironmentNode* root;
+};
+
+Environment* Environment_create(Environment* parent) {
+  Environment* result = malloc(sizeof(Environment));
+  result->parent = parent;
+  result->root = NULL;
+  return result;
+}
+
+EnvironmentGetResult Environment_get(Environment* self, Symbol* key) {
+  if(self == NULL) return (EnvironmentGetResult) { false, NULL };
+
+  for(EnvironmentNode* search = self->root; search != NULL; search = search->next) {
+    if(search->key == key) return (EnvironmentGetResult) { true, search->value };
+  }
+
+  return Environment_get(self->parent, key);
+}
+
+bool Environment_set(Environment* self, Symbol* key, Object* value) {
+  assert(self != NULL);
+
+  for(EnvironmentNode* search = self->root; search != NULL; search = search->next) {
+    if(search->key == key) return false;
+  }
+
+  EnvironmentNode* node = malloc(sizeof(EnvironmentNode));
+  node->key = key;
+  node->value = value;
+  node->next = self->root;
+  self->root = node;
+  return true;
+}
+
+#endif
diff --git a/c/environment.h b/c/environment.h
new file mode 100644 (file)
index 0000000..ee4f784
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef ENVIRONMENT_H
+#define ENVIRONMENT_H
+
+#include <stdbool.h>
+#include "symbol.h"
+#include "object.h"
+
+struct Environment;
+typedef struct Environment Environment;
+
+Environment* Environment_create(Environment*);
+
+struct EnvironmentGetResult;
+typedef struct EnvironmentGetResult EnvironmentGetResult;
+struct EnvironmentGetResult {
+  bool found;
+  Object* value;
+};
+
+EnvironmentGetResult Environment_get(Environment*, Symbol*);
+bool Environment_set(Environment*, Symbol*, Object*);
+
+#endif