Files
uclisp/src/state.c

75 lines
2.0 KiB
C

#include "uclisp.h"
#include "internal.h"
#include "state.h"
#include "utility.h"
#include <assert.h>
#include <string.h>
#include <stdlib.h>
// Implements state as a giant alist
// TODO: Consider generalizing the alist concept
struct ucl_state {
struct ucl_object *list;
struct ucl_state *parent;
};
#define NAME_POSITION 0
#define DATA_POSITION 1
static struct ucl_object *ucl_state_get_cell(struct ucl_state *state, const char *name) {
FOREACH_LIST(state->list, iter, item) {
assert(item->type == UCL_TYPE_CELL);
const char *item_name = ucl_list_nth(item, NAME_POSITION)->string;
if (!strcmp(name, item_name)) {
return item;
}
}
return NULL;
}
struct ucl_object *ucl_state_get(struct ucl_state *state, const char *name) {
struct ucl_object *cell = ucl_state_get_cell(state, name);
if (cell == NULL) {
if (state->parent == NULL) {
return ucl_error_create(strdup("Unknown error"));
} else {
return ucl_state_get(state->parent, name);
}
}
return ucl_list_nth(cell, DATA_POSITION);
}
void ucl_state_put(struct ucl_state *state, const char *name, struct ucl_object *obj) {
struct ucl_object *cell = ucl_state_get_cell(state, name);
if (cell == NULL) {
ucl_list_append(state->list,
ucl_tuple_create(
ucl_string_create(strdup(name)),
obj));
} else {
// TODO: Refcounting / cleanup
cell->cell.cdr->cell.car = obj;
}
}
struct ucl_state *ucl_state_create() {
struct ucl_state *state = malloc(sizeof(struct ucl_state));
state->list = ucl_nil_create();
state->parent = NULL;
return state;
}
struct ucl_state *ucl_state_create_child(struct ucl_state *parent) {
struct ucl_state *state = ucl_state_create();
state->parent = parent;
return state;
}
void ucl_state_delete(struct ucl_state *state) {
// TODO: Cleanup
// ucl_object_delete(state->list);
}