#include "env.h"

#include <stdlib.h>
#include <string.h>

struct binding {
    char *name;
    double value;
    struct binding *next;
};

struct env {
    Env *parent;
    struct binding *first;
};

Env *env_new(Env *parent) {
    Env *env = malloc(sizeof *env);
    if (env == NULL) {
        return NULL;
    }
    env->parent = parent;
    env->first = NULL;
    return env;
}

void env_free(Env *env) {
    if (env == NULL) {
        return;
    }
    struct binding *current = env->first;
    while (current != NULL) {
        struct binding *next = current->next;
        free(current->name);
        free(current);
        current = next;
    }
    free(env);
}

int env_set(Env *env, const char *name, double value) {
    for (struct binding *b = env->first; b != NULL; b = b->next) {
        if (strcmp(b->name, name) == 0) {
            b->value = value;
            return 1;
        }
    }
    struct binding *b = malloc(sizeof *b);
    if (b == NULL) {
        return 0;
    }
    b->name = malloc(strlen(name) + 1);
    if (b->name == NULL) {
        free(b);
        return 0;
    }
    strcpy(b->name, name);
    b->value = value;
    b->next = env->first;
    env->first = b;
    return 1;
}

int env_get(const Env *env, const char *name, double *value) {
    for (const Env *e = env; e != NULL; e = e->parent) {
        for (const struct binding *b = e->first; b != NULL; b = b->next) {
            if (strcmp(b->name, name) == 0) {
                *value = b->value;
                return 1;
            }
        }
    }
    return 0;
}
