Add error types and simple state
This commit is contained in:
60
src/state.c
Normal file
60
src/state.c
Normal file
@@ -0,0 +1,60 @@
|
||||
#include "nihilispm.h"
|
||||
#include "nihilispm_internal.h"
|
||||
#include "nihilispm_state.h"
|
||||
#include "nihilispm_utility.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Implements state as a giant alist
|
||||
// TODO: Consider generalizing the alist concept
|
||||
|
||||
struct nl_state {
|
||||
struct nl_object *list;
|
||||
};
|
||||
|
||||
#define NAME_POSITION 0
|
||||
#define DATA_POSITION 1
|
||||
|
||||
|
||||
static struct nl_object *nl_state_get_cell(struct nl_state *state, const char *name) {
|
||||
FOREACH_LIST(state->list, iter, item) {
|
||||
assert(item->type == NL_TYPE_CELL);
|
||||
const char *item_name = nl_list_nth(item, NAME_POSITION)->string;
|
||||
if (!strcmp(name, item_name)) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct nl_object *nl_state_get(struct nl_state *state, const char *name) {
|
||||
struct nl_object *cell = nl_state_get_cell(state, name);
|
||||
NL_COND_OR_RET_ERROR(cell != NULL, "Unknown name");
|
||||
return nl_list_nth(cell, DATA_POSITION);
|
||||
}
|
||||
|
||||
void nl_state_put(struct nl_state *state, const char *name, struct nl_object *obj) {
|
||||
struct nl_object *cell = nl_state_get_cell(state, name);
|
||||
if (cell == NULL) {
|
||||
nl_list_append(state->list,
|
||||
nl_tuple_create(
|
||||
nl_string_create(strdup(name)),
|
||||
obj));
|
||||
} else {
|
||||
// TODO: Refcounting / cleanup
|
||||
cell->cell.cdr->cell.car = obj;
|
||||
}
|
||||
}
|
||||
|
||||
struct nl_state *nl_state_create() {
|
||||
struct nl_state *state = malloc(sizeof(struct nl_state));
|
||||
state->list = nl_nil_create();
|
||||
return state;
|
||||
}
|
||||
|
||||
void nl_state_delete(struct nl_state *state) {
|
||||
nl_object_delete(state->list);
|
||||
}
|
||||
Reference in New Issue
Block a user