Add error types and simple state

This commit is contained in:
2022-10-28 16:08:40 -04:00
parent fd91e66b8a
commit ed173bd17a
14 changed files with 302 additions and 89 deletions

60
src/state.c Normal file
View 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);
}