diff options
| author | Oskari Timperi <oskari.timperi@iki.fi> | 2014-05-15 22:51:16 +0300 |
|---|---|---|
| committer | Oskari Timperi <oskari.timperi@iki.fi> | 2014-05-15 22:51:16 +0300 |
| commit | 043cddd93a65930c534f4170ed517bb1f76fd3ae (patch) | |
| tree | 3686922f08845bb53b5a80557bd62133ee86bdbb | |
| parent | a2ed9c63f26f5cd767ac6c1d4073cdaa08a168b4 (diff) | |
| download | lispish-043cddd93a65930c534f4170ed517bb1f76fd3ae.tar.gz lispish-043cddd93a65930c534f4170ed517bb1f76fd3ae.zip | |
add env functions
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | env.c | 134 | ||||
| -rw-r--r-- | env.h | 16 |
3 files changed, 151 insertions, 1 deletions
@@ -1,4 +1,4 @@ -SOURCES = parse.c list.c atom.c eval.c tokens.c +SOURCES = parse.c list.c atom.c eval.c tokens.c env.c OBJECTS = $(SOURCES:.c=.o) CFLAGS = -Wall -g @@ -0,0 +1,134 @@ +#include "env.h" +#include "list.h" +#include "atom.h" + +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> + +struct kv +{ + const char *symbol; + struct atom *value; +}; + +struct list *env_new() +{ + return list_new(NULL); +} + +struct atom *env_lookup(struct list *env, const char *symbol) +{ + env = env->next; + while (env) + { + struct kv *kv = (struct kv *) env->data; + + if (strcmp(kv->symbol, symbol) == 0) + { + return kv->value; + } + + env = env->next; + } + return NULL; +} + +int env_set_(struct list *env, const char *symbol, + struct atom *atom, int force) +{ + struct list *first = env; + struct kv *kv; + + env = env->next; + while (env) + { + kv = (struct kv *) env->data; + + if (strcmp(symbol, kv->symbol) == 0) + { + if (!force) + return 0; + + kv->value = atom; + + return 1; + } + + if (!env->next) + break; + + env = env->next; + } + + if (!env) + env = first; + + kv = calloc(1, sizeof(*kv)); + kv->symbol = strdup(symbol); + kv->value = atom; + + list_append(env, kv); + + return 1; +} + +struct list *env_extend(struct list *env, int count, ...) +{ + va_list ap; + int i; + + struct list *result = env_clone(env); + + va_start(ap, count); + + for (i = 0; i < count; ++i) + { + const char *symbol = va_arg(ap, const char *); + struct atom *atom = va_arg(ap, struct atom *); + env_set_(result, symbol, atom, 1); + } + + va_end(ap); + + return result; +} + +// struct list *env_extend_env(struct list *enva, struct list *envb) +// { + +// } + +int env_set(struct list *env, const char *symbol, + struct atom *value) +{ + return env_set_(env, symbol, value, 0); +} + +void env_free(struct list *env) +{ + +} + +struct list *env_clone(struct list *env) +{ + struct list *clone = env_new(); + struct list *last = clone; + + env = env->next; + while (env) + { + struct kv *kv = (struct kv *) env->data; + + struct kv *kv_clone = malloc(sizeof(*kv_clone)); + + kv_clone->symbol = strdup(kv->symbol); + kv_clone->value = atom_clone(kv->value); + + last = list_append(last, kv_clone); + + env = env->next; + } + + return clone; +} @@ -0,0 +1,16 @@ +#ifndef ENV_H +#define ENV_H + +struct list; +struct atom; + +struct list *env_new(); +struct atom *env_lookup(struct list *env, const char *symbol); +struct list *env_extend(struct list *env, int count, ...); //const char *symbol, struct atom *value +// struct list *env_extend_env(struct list *enva, struct list *envb); +int env_set(struct list *env, const char *symbol, + struct atom *value); +void env_free(struct list *env); +struct list *env_clone(struct list *env); + +#endif |
