From af88471b3aafab51a3d90680e9767d708bc8dd36 Mon Sep 17 00:00:00 2001 From: Max Regan Date: Mon, 14 Nov 2022 22:49:02 -0500 Subject: [PATCH] Rename 'state' to 'scope' --- SConstruct | 4 +- src/builtins.c | 62 ++++++++++---------- src/builtins.h | 54 +++++++++--------- src/evaluate.c | 36 ++++++------ src/internal.h | 6 +- src/lisp.h | 28 ++++----- src/main.c | 80 +++++++++++++------------- src/memory.c | 12 ++-- src/scope.c | 87 ++++++++++++++++++++++++++++ src/scope.h | 15 +++++ src/special.c | 52 ++++++++--------- src/special.h | 18 +++--- src/state.c | 88 ----------------------------- src/state.h | 15 ----- src/uclisp.h | 8 +-- src/utility.c | 2 +- src/utility.h | 2 +- test/test_e2e.c | 40 ++++++------- test/test_parse.c | 4 +- test/{test_state.c => test_scope.c} | 26 ++++----- test/test_utility.c | 2 +- 21 files changed, 320 insertions(+), 321 deletions(-) create mode 100644 src/scope.c create mode 100644 src/scope.h delete mode 100644 src/state.c delete mode 100644 src/state.h rename test/{test_state.c => test_scope.c} (69%) diff --git a/SConstruct b/SConstruct index 21bb891..d8548f5 100644 --- a/SConstruct +++ b/SConstruct @@ -17,7 +17,7 @@ lib_srcs = [ "src/evaluate.c", "src/memory.c", "src/special.c", - "src/state.c", + "src/scope.c", "src/utility.c", "src/parse.c", ] @@ -28,7 +28,7 @@ test_srcs = [ "test/test_arena.c", "test/test_e2e.c", "test/test_parse.c", - "test/test_state.c", + "test/test_scope.c", "test/test_utility.c", ] test_lib_srcs = ["third-party/unity/src/unity.c"] diff --git a/src/builtins.c b/src/builtins.c index 37bda61..c00801e 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -2,7 +2,7 @@ #include "internal.h" #include "utility.h" #include "builtins.h" -#include "state.h" +#include "scope.h" #include "lisp.h" #include @@ -11,7 +11,7 @@ #include #include -LISP_FUNC_1(ucl_builtin_type, state, arg) { +LISP_FUNC_1(ucl_builtin_type, scope, arg) { switch (arg->type) { case UCL_TYPE_CELL: return ucl_symbol_create("list"); @@ -33,7 +33,7 @@ LISP_FUNC_1(ucl_builtin_type, state, arg) { } } -LISP_FUNC_1(ucl_builtin_error, state, arg) { +LISP_FUNC_1(ucl_builtin_error, scope, arg) { if (arg->type != UCL_TYPE_STRING) { return ucl_error_create("Expected type string passed to 'error'"); } @@ -41,42 +41,42 @@ LISP_FUNC_1(ucl_builtin_error, state, arg) { return ucl_error_create(arg->error); } -LISP_FUNC_1(ucl_builtin_symbol_p, state, arg) { +LISP_FUNC_1(ucl_builtin_symbol_p, scope, arg) { return ucl_predicate(arg->type == UCL_TYPE_SYMBOL); } -LISP_FUNC_1(ucl_builtin_string_p, state, arg) { +LISP_FUNC_1(ucl_builtin_string_p, scope, arg) { return ucl_predicate(arg->type == UCL_TYPE_STRING); } -LISP_FUNC_1(ucl_builtin_int_p, state, arg) { +LISP_FUNC_1(ucl_builtin_int_p, scope, arg) { return ucl_predicate(arg->type == UCL_TYPE_INT); } -LISP_FUNC_1(ucl_builtin_list_p, state, arg) { +LISP_FUNC_1(ucl_builtin_list_p, scope, arg) { return ucl_predicate(arg->type == UCL_TYPE_CELL); } -LISP_FUNC_1(ucl_builtin_error_p, state, arg) { +LISP_FUNC_1(ucl_builtin_error_p, scope, arg) { return ucl_predicate(arg->type == UCL_TYPE_ERROR); } -LISP_FUNC_1(ucl_builtin_car, state, arg) { +LISP_FUNC_1(ucl_builtin_car, scope, arg) { return ucl_car(arg); } -LISP_FUNC_1(ucl_builtin_cdr, state, arg) { +LISP_FUNC_1(ucl_builtin_cdr, scope, arg) { return ucl_cdr(arg); } -LISP_FUNC_2(ucl_builtin_nth, state, n, list) { +LISP_FUNC_2(ucl_builtin_nth, scope, n, list) { UCL_COND_OR_RET_ERROR(n->type == UCL_TYPE_INT, "First argument to nth must be an integer"); UCL_COND_OR_RET_ERROR(list->type == UCL_TYPE_CELL, "Second argument to nth must be a list"); return ucl_list_nth(list, n->integer); } -LISP_FUNC_2(ucl_builtin_add, state, arg0, arg1) { +LISP_FUNC_2(ucl_builtin_add, scope, arg0, arg1) { if (arg0->type != UCL_TYPE_INT) { return ucl_error_create("Invalid type of argument 0 to 'add'"); } @@ -88,7 +88,7 @@ LISP_FUNC_2(ucl_builtin_add, state, arg0, arg1) { return ucl_int_create(arg0->integer + arg1->integer); } -LISP_FUNC_2(ucl_builtin_sub, state, arg0, arg1) { +LISP_FUNC_2(ucl_builtin_sub, scope, arg0, arg1) { if (arg0->type != UCL_TYPE_INT) { return ucl_error_create("Invalid type of argument 0 to 'sub'"); } @@ -100,7 +100,7 @@ LISP_FUNC_2(ucl_builtin_sub, state, arg0, arg1) { return ucl_int_create(arg0->integer - arg1->integer); } -LISP_FUNC_2(ucl_builtin_mul, state, arg0, arg1) { +LISP_FUNC_2(ucl_builtin_mul, scope, arg0, arg1) { if (arg0->type != UCL_TYPE_INT) { return ucl_error_create("Invalid type of argument 0 to 'mul'"); } @@ -112,7 +112,7 @@ LISP_FUNC_2(ucl_builtin_mul, state, arg0, arg1) { return ucl_int_create(arg0->integer * arg1->integer); } -LISP_FUNC_2(ucl_builtin_div, state, arg0, arg1) { +LISP_FUNC_2(ucl_builtin_div, scope, arg0, arg1) { if (arg0->type != UCL_TYPE_INT) { return ucl_error_create("Invalid type of argument 0 to 'div'"); } @@ -125,7 +125,7 @@ LISP_FUNC_2(ucl_builtin_div, state, arg0, arg1) { return ucl_int_create(arg0->integer / arg1->integer); } -LISP_FUNC_2(ucl_builtin_mod, state, arg0, arg1) { +LISP_FUNC_2(ucl_builtin_mod, scope, arg0, arg1) { if (arg0->type != UCL_TYPE_INT) { return ucl_error_create("Invalid type of argument 0 to 'mod'"); } @@ -137,7 +137,7 @@ LISP_FUNC_2(ucl_builtin_mod, state, arg0, arg1) { return ucl_int_create(arg0->integer % arg1->integer); } -LISP_FUNC_2(ucl_builtin_concat, state, arg0, arg1) { +LISP_FUNC_2(ucl_builtin_concat, scope, arg0, arg1) { if (arg0->type != UCL_TYPE_STRING) { return ucl_error_create("Invalid type of argument 0 to 'concat'"); } @@ -157,25 +157,25 @@ LISP_FUNC_2(ucl_builtin_concat, state, arg0, arg1) { return result; } -LISP_FUNC_0(ucl_builtin_now_millis_mono, state) { +LISP_FUNC_0(ucl_builtin_now_millis_mono, scope) { // TODO: Implement and move to a 'platform' file return NULL; } -LISP_FUNC_1(ucl_builtin_print, state, arg0) { +LISP_FUNC_1(ucl_builtin_print, scope, arg0) { ucl_print_obj(arg0); return ucl_nil_create(); } -LISP_FUNC_1(ucl_builtin_printl, state, arg0) { +LISP_FUNC_1(ucl_builtin_printl, scope, arg0) { ucl_print_obj(arg0); printf("\n"); return ucl_nil_create(); } -struct ucl_object *ucl_builtin_list(struct ucl_state *state, struct ucl_object *args) { +struct ucl_object *ucl_builtin_list(struct ucl_scope *scope, struct ucl_object *args) { struct ucl_object *head = ucl_nil_create(); FOREACH_LIST(args, iter, item) { ucl_list_append(head, item); @@ -184,57 +184,57 @@ struct ucl_object *ucl_builtin_list(struct ucl_state *state, struct ucl_object * return head; } -LISP_FUNC_2(ucl_builtin_mapcar, state, fun, elems) { +LISP_FUNC_2(ucl_builtin_mapcar, scope, fun, elems) { // TODO: Support arbitrary number of 'elems' lists struct ucl_object *result = ucl_nil_create(); FOREACH_LIST(elems, iter, elem) { struct ucl_object *form = ucl_tuple_create(fun, elem); - struct ucl_object *value = ucl_evaluate(state, form); + struct ucl_object *value = ucl_evaluate(scope, form); UCL_RET_IF_ERROR(value); ucl_list_append(result, value); } return result; } -LISP_FUNC_2(ucl_builtin_equal, state, arg0, arg1) { +LISP_FUNC_2(ucl_builtin_equal, scope, arg0, arg1) { return ucl_equal(arg0, arg1); } -LISP_FUNC_2(ucl_builtin_gt, state, arg0, arg1) { +LISP_FUNC_2(ucl_builtin_gt, scope, arg0, arg1) { UCL_COND_OR_RET_ERROR(arg0->type == UCL_TYPE_INT, "First argument to > must be an integer"); UCL_COND_OR_RET_ERROR(arg0->type == UCL_TYPE_INT, "Second argument to > must be an integer"); return ucl_predicate(arg0->integer > arg1->integer); } -LISP_FUNC_2(ucl_builtin_ge, state, arg0, arg1) { +LISP_FUNC_2(ucl_builtin_ge, scope, arg0, arg1) { UCL_COND_OR_RET_ERROR(arg0->type == UCL_TYPE_INT, "First argument to >= must be an integer"); UCL_COND_OR_RET_ERROR(arg0->type == UCL_TYPE_INT, "Second argument to >= must be an integer"); return ucl_predicate(arg0->integer > arg1->integer); } -LISP_FUNC_2(ucl_builtin_lt, state, arg0, arg1) { +LISP_FUNC_2(ucl_builtin_lt, scope, arg0, arg1) { UCL_COND_OR_RET_ERROR(arg0->type == UCL_TYPE_INT, "First argument to < must be an integer"); UCL_COND_OR_RET_ERROR(arg0->type == UCL_TYPE_INT, "Second argument to < must be an integer"); return ucl_predicate(arg0->integer < arg1->integer); } -LISP_FUNC_2(ucl_builtin_le, state, arg0, arg1) { +LISP_FUNC_2(ucl_builtin_le, scope, arg0, arg1) { UCL_COND_OR_RET_ERROR(arg0->type == UCL_TYPE_INT, "First argument to <= must be an integer"); UCL_COND_OR_RET_ERROR(arg0->type == UCL_TYPE_INT, "Second argument to <= must be an integer"); return ucl_predicate(arg0->integer < arg1->integer); } -LISP_FUNC_2(ucl_builtin_num_eq, state, arg0, arg1) { +LISP_FUNC_2(ucl_builtin_num_eq, scope, arg0, arg1) { UCL_COND_OR_RET_ERROR(arg0->type == UCL_TYPE_INT, "First argument to = must be an integer"); UCL_COND_OR_RET_ERROR(arg0->type == UCL_TYPE_INT, "Second argument to = must be an integer"); return ucl_predicate(arg0->integer == arg1->integer); } -LISP_FUNC_2(ucl_builtin_xor, state, arg0, arg1) { +LISP_FUNC_2(ucl_builtin_xor, scope, arg0, arg1) { return ucl_predicate(ucl_truthy_bool(arg0) || ucl_truthy_bool(arg1)); } -LISP_FUNC_1(ucl_builtin_not, state, arg0) { +LISP_FUNC_1(ucl_builtin_not, scope, arg0) { return ucl_predicate(!ucl_truthy_bool(arg0)); } diff --git a/src/builtins.h b/src/builtins.h index 05de882..889acdb 100644 --- a/src/builtins.h +++ b/src/builtins.h @@ -3,37 +3,37 @@ #include "utility.h" -struct ucl_object *ucl_builtin_error(struct ucl_state *state, struct ucl_object *args); -struct ucl_object *ucl_builtin_type(struct ucl_state *state, struct ucl_object *args); -struct ucl_object *ucl_builtin_symbol_p(struct ucl_state *state, struct ucl_object *args); -struct ucl_object *ucl_builtin_string_p(struct ucl_state *state, struct ucl_object *args); -struct ucl_object *ucl_builtin_int_p(struct ucl_state *state, struct ucl_object *args); -struct ucl_object *ucl_builtin_list_p(struct ucl_state *state, struct ucl_object *args); +struct ucl_object *ucl_builtin_error(struct ucl_scope *scope, struct ucl_object *args); +struct ucl_object *ucl_builtin_type(struct ucl_scope *scope, struct ucl_object *args); +struct ucl_object *ucl_builtin_symbol_p(struct ucl_scope *scope, struct ucl_object *args); +struct ucl_object *ucl_builtin_string_p(struct ucl_scope *scope, struct ucl_object *args); +struct ucl_object *ucl_builtin_int_p(struct ucl_scope *scope, struct ucl_object *args); +struct ucl_object *ucl_builtin_list_p(struct ucl_scope *scope, struct ucl_object *args); -struct ucl_object *ucl_builtin_add(struct ucl_state *state, struct ucl_object *args); -struct ucl_object *ucl_builtin_sub(struct ucl_state *state, struct ucl_object *args); -struct ucl_object *ucl_builtin_mul(struct ucl_state *state, struct ucl_object *args); -struct ucl_object *ucl_builtin_div(struct ucl_state *state, struct ucl_object *args); -struct ucl_object *ucl_builtin_mod(struct ucl_state *state, struct ucl_object *args); -struct ucl_object *ucl_builtin_gt(struct ucl_state *state, struct ucl_object *args); -struct ucl_object *ucl_builtin_ge(struct ucl_state *state, struct ucl_object *args); -struct ucl_object *ucl_builtin_lt(struct ucl_state *state, struct ucl_object *args); -struct ucl_object *ucl_builtin_le(struct ucl_state *state, struct ucl_object *args); -struct ucl_object *ucl_builtin_num_eq(struct ucl_state *state, struct ucl_object *args); -struct ucl_object *ucl_builtin_concat(struct ucl_state *state, struct ucl_object *args); +struct ucl_object *ucl_builtin_add(struct ucl_scope *scope, struct ucl_object *args); +struct ucl_object *ucl_builtin_sub(struct ucl_scope *scope, struct ucl_object *args); +struct ucl_object *ucl_builtin_mul(struct ucl_scope *scope, struct ucl_object *args); +struct ucl_object *ucl_builtin_div(struct ucl_scope *scope, struct ucl_object *args); +struct ucl_object *ucl_builtin_mod(struct ucl_scope *scope, struct ucl_object *args); +struct ucl_object *ucl_builtin_gt(struct ucl_scope *scope, struct ucl_object *args); +struct ucl_object *ucl_builtin_ge(struct ucl_scope *scope, struct ucl_object *args); +struct ucl_object *ucl_builtin_lt(struct ucl_scope *scope, struct ucl_object *args); +struct ucl_object *ucl_builtin_le(struct ucl_scope *scope, struct ucl_object *args); +struct ucl_object *ucl_builtin_num_eq(struct ucl_scope *scope, struct ucl_object *args); +struct ucl_object *ucl_builtin_concat(struct ucl_scope *scope, struct ucl_object *args); -struct ucl_object *ucl_builtin_not(struct ucl_state *state, struct ucl_object *args); -struct ucl_object *ucl_builtin_xor(struct ucl_state *state, struct ucl_object *args); +struct ucl_object *ucl_builtin_not(struct ucl_scope *scope, struct ucl_object *args); +struct ucl_object *ucl_builtin_xor(struct ucl_scope *scope, struct ucl_object *args); -struct ucl_object *ucl_builtin_now_millis_mono(struct ucl_state *state, struct ucl_object *args); +struct ucl_object *ucl_builtin_now_millis_mono(struct ucl_scope *scope, struct ucl_object *args); -struct ucl_object *ucl_builtin_car(struct ucl_state *state, struct ucl_object *args); -struct ucl_object *ucl_builtin_cdr(struct ucl_state *state, struct ucl_object *args); -struct ucl_object *ucl_builtin_nth(struct ucl_state *state, struct ucl_object *args); -struct ucl_object *ucl_builtin_list(struct ucl_state *state, struct ucl_object *args); -struct ucl_object *ucl_builtin_mapcar(struct ucl_state *state, struct ucl_object *args); +struct ucl_object *ucl_builtin_car(struct ucl_scope *scope, struct ucl_object *args); +struct ucl_object *ucl_builtin_cdr(struct ucl_scope *scope, struct ucl_object *args); +struct ucl_object *ucl_builtin_nth(struct ucl_scope *scope, struct ucl_object *args); +struct ucl_object *ucl_builtin_list(struct ucl_scope *scope, struct ucl_object *args); +struct ucl_object *ucl_builtin_mapcar(struct ucl_scope *scope, struct ucl_object *args); -struct ucl_object *ucl_builtin_print(struct ucl_state *state, struct ucl_object *args); -struct ucl_object *ucl_builtin_printl(struct ucl_state *state, struct ucl_object *args); +struct ucl_object *ucl_builtin_print(struct ucl_scope *scope, struct ucl_object *args); +struct ucl_object *ucl_builtin_printl(struct ucl_scope *scope, struct ucl_object *args); #endif diff --git a/src/evaluate.c b/src/evaluate.c index e3e057d..b2bf64b 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -4,17 +4,17 @@ #include "uclisp.h" #include "internal.h" #include "utility.h" -#include "state.h" +#include "scope.h" // TODO: remove string.h #include -struct ucl_object *ucl_evaluate_builtin_form(struct ucl_state *state, struct ucl_object *list) { +struct ucl_object *ucl_evaluate_builtin_form(struct ucl_scope *scope, struct ucl_object *list) { // TODO: Reasonably split builtin and non-builtin evaluation struct ucl_object *evaluated_list = ucl_nil_create(); FOREACH_LIST(list, iter, item) { - struct ucl_object *obj = ucl_evaluate(state, item); + struct ucl_object *obj = ucl_evaluate(scope, item); UCL_RET_IF_ERROR(obj); ucl_list_append(evaluated_list, obj); }; @@ -24,18 +24,18 @@ struct ucl_object *ucl_evaluate_builtin_form(struct ucl_state *state, struct ucl if (fun->type == UCL_TYPE_BUILTIN) { struct ucl_object *args = ucl_cdr(evaluated_list); - result = fun->builtin(state, args); + result = fun->builtin(scope, args); } else if (fun->type == UCL_TYPE_CELL) { - struct ucl_state *fun_state = ucl_state_create_child(state); + struct ucl_scope *fun_scope = ucl_scope_create_child(scope); struct ucl_object *fun_arg_syms = ucl_car(fun); struct ucl_object *fun_forms = ucl_cdr(fun); int i = 0; FOREACH_LIST(fun_arg_syms, iter, sym) { - ucl_state_put(fun_state, sym->symbol, ucl_list_nth(evaluated_list, i + 1)); + ucl_scope_put(fun_scope, sym->symbol, ucl_list_nth(evaluated_list, i + 1)); i++; } - result = ucl_progn(fun_state, fun_forms); - ucl_state_delete(fun_state); + result = ucl_progn(fun_scope, fun_forms); + ucl_scope_delete(fun_scope); } else { assert(0); } @@ -45,45 +45,45 @@ struct ucl_object *ucl_evaluate_builtin_form(struct ucl_state *state, struct ucl return (result == NULL) ? ucl_nil_create() : result; } -struct ucl_object *ucl_evaluate_special_form(struct ucl_state *state, struct ucl_object *list) { +struct ucl_object *ucl_evaluate_special_form(struct ucl_scope *scope, struct ucl_object *list) { // TODO: Recursively eval args const char *fun_sym = ucl_car(list)->symbol; - struct ucl_object *fun = ucl_state_get(state, fun_sym); + struct ucl_object *fun = ucl_scope_get(scope, fun_sym); struct ucl_object *args = ucl_cdr(list); struct ucl_object *result = NULL; - result = fun->special(state, args); + result = fun->special(scope, args); return result; } -struct ucl_object *ucl_evaluate_list(struct ucl_state *state, struct ucl_object *list) { +struct ucl_object *ucl_evaluate_list(struct ucl_scope *scope, struct ucl_object *list) { if (list->cell.car == NULL) { return list; } - struct ucl_object *fun = ucl_evaluate(state, ucl_car(list)); + struct ucl_object *fun = ucl_evaluate(scope, ucl_car(list)); UCL_RET_IF_ERROR(fun); if (fun->type == UCL_TYPE_SPECIAL) { - return ucl_evaluate_special_form(state, list); + return ucl_evaluate_special_form(scope, list); } else if (fun->type == UCL_TYPE_BUILTIN || fun->type == UCL_TYPE_CELL) { - return ucl_evaluate_builtin_form(state, list); + return ucl_evaluate_builtin_form(scope, list); } else { assert(0); // TODO: Lisp functions and other errors } } -struct ucl_object *ucl_evaluate(struct ucl_state *state, struct ucl_object *obj) { +struct ucl_object *ucl_evaluate(struct ucl_scope *scope, struct ucl_object *obj) { assert(obj != NULL); switch (obj->type) { case UCL_TYPE_CELL: - return ucl_evaluate_list(state, obj); + return ucl_evaluate_list(scope, obj); case UCL_TYPE_SYMBOL: - return ucl_state_get(state, obj->symbol); + return ucl_scope_get(scope, obj->symbol); case UCL_TYPE_INT: case UCL_TYPE_STRING: case UCL_TYPE_ERROR: diff --git a/src/internal.h b/src/internal.h index 35a28fe..ec36301 100644 --- a/src/internal.h +++ b/src/internal.h @@ -14,13 +14,13 @@ iter_name = iter_name->cell.cdr, item_name = (iter_name == NULL) ? NULL : iter_name->cell.car) // TODO: Refactor this struct's location -struct ucl_state { +struct ucl_scope { // TODO: For garbage collection, we need references from the parent->child state struct ucl_object *list; - struct ucl_state *parent; + struct ucl_scope *parent; }; -extern struct ucl_arena *state_arena; +extern struct ucl_arena *scope_arena; struct ucl_object *ucl_cell_create(struct ucl_object *car, struct ucl_object *cdr); struct ucl_object *ucl_int_create(int integer); diff --git a/src/lisp.h b/src/lisp.h index 76b470b..3ea30ed 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -4,19 +4,19 @@ #include "uclisp.h" #include "utility.h" -#define LISP_FUNC_0(func_name, state_name) \ +#define LISP_FUNC_0(func_name, scope_name) \ static struct ucl_object *func_name##_impl(); \ - struct ucl_object *func_name(struct ucl_state *state, struct ucl_object *args) { \ + struct ucl_object *func_name(struct ucl_scope *scope, struct ucl_object *args) { \ if (args->cell.car != NULL) { \ return NULL; \ } \ - return func_name##_impl(state_name); \ + return func_name##_impl(scope_name); \ } \ - static struct ucl_object *func_name##_impl(struct ucl_state *state) + static struct ucl_object *func_name##_impl(struct ucl_scope *scope) -#define LISP_FUNC_1(func_name, state_name, arg0_name) \ - static struct ucl_object *func_name##_impl(struct ucl_state *state, struct ucl_object *arg0_name); \ - struct ucl_object *func_name(struct ucl_state *state, struct ucl_object *args) { \ +#define LISP_FUNC_1(func_name, scope_name, arg0_name) \ + static struct ucl_object *func_name##_impl(struct ucl_scope *scope, struct ucl_object *arg0_name); \ + struct ucl_object *func_name(struct ucl_scope *scope, struct ucl_object *args) { \ struct ucl_object *len_obj = ucl_list_length(args); \ if (len_obj->type != UCL_TYPE_INT) { \ return NULL; \ @@ -25,14 +25,14 @@ return NULL; \ } \ struct ucl_object *arg0 = ucl_car(args); \ - return func_name##_impl(state_name, arg0); \ + return func_name##_impl(scope_name, arg0); \ } \ - static struct ucl_object *func_name##_impl(struct ucl_state *state, struct ucl_object *arg0_name) + static struct ucl_object *func_name##_impl(struct ucl_scope *scope, struct ucl_object *arg0_name) // TODO: Unroll the args more efficiently, this is O(n^2) -#define LISP_FUNC_2(func_name, state_name, arg0_name, arg1_name) \ - static struct ucl_object *func_name##_impl(struct ucl_state *state, struct ucl_object *arg0_name, struct ucl_object *arg1_name); \ - struct ucl_object *func_name(struct ucl_state *state, struct ucl_object *args) { \ +#define LISP_FUNC_2(func_name, scope_name, arg0_name, arg1_name) \ + static struct ucl_object *func_name##_impl(struct ucl_scope *scope, struct ucl_object *arg0_name, struct ucl_object *arg1_name); \ + struct ucl_object *func_name(struct ucl_scope *scope, struct ucl_object *args) { \ struct ucl_object *len_obj = ucl_list_length(args); \ if (len_obj->type != UCL_TYPE_INT) { \ return NULL; \ @@ -42,8 +42,8 @@ } \ struct ucl_object *arg0 = ucl_list_nth(args, 0); \ struct ucl_object *arg1 = ucl_list_nth(args, 1); \ - return func_name##_impl(state_name, arg0, arg1); \ + return func_name##_impl(scope_name, arg0, arg1); \ } \ - static struct ucl_object *func_name##_impl(struct ucl_state *state, struct ucl_object *arg0_name, struct ucl_object *arg1_name) + static struct ucl_object *func_name##_impl(struct ucl_scope *scope, struct ucl_object *arg0_name, struct ucl_object *arg1_name) #endif diff --git a/src/main.c b/src/main.c index 426bfbc..bc7dcc9 100644 --- a/src/main.c +++ b/src/main.c @@ -8,62 +8,62 @@ #include "builtins.h" #include "internal.h" #include "special.h" -#include "state.h" +#include "scope.h" #include "utility.h" int main(int argc, const char **argv) { (void) argc, (void) argv; - struct ucl_state *state = ucl_state_create(); + struct ucl_scope *scope = ucl_scope_create(); - ucl_state_put(state, "let", ucl_special_create(ucl_special_let)); - ucl_state_put(state, "if", ucl_special_create(ucl_special_if)); - ucl_state_put(state, "defun", ucl_special_create(ucl_special_defun)); - ucl_state_put(state, "lambda", ucl_special_create(ucl_special_lambda)); - ucl_state_put(state, "setq", ucl_special_create(ucl_special_setq)); - ucl_state_put(state, "progn", ucl_special_create(ucl_special_progn)); - ucl_state_put(state, "quote", ucl_special_create(ucl_special_quote)); - ucl_state_put(state, "and", ucl_special_create(ucl_special_and)); - ucl_state_put(state, "or", ucl_special_create(ucl_special_or)); + ucl_scope_put(scope, "let", ucl_special_create(ucl_special_let)); + ucl_scope_put(scope, "if", ucl_special_create(ucl_special_if)); + ucl_scope_put(scope, "defun", ucl_special_create(ucl_special_defun)); + ucl_scope_put(scope, "lambda", ucl_special_create(ucl_special_lambda)); + ucl_scope_put(scope, "setq", ucl_special_create(ucl_special_setq)); + ucl_scope_put(scope, "progn", ucl_special_create(ucl_special_progn)); + ucl_scope_put(scope, "quote", ucl_special_create(ucl_special_quote)); + ucl_scope_put(scope, "and", ucl_special_create(ucl_special_and)); + ucl_scope_put(scope, "or", ucl_special_create(ucl_special_or)); // TODO: // - iteration - ucl_state_put(state, "print", ucl_builtin_create(ucl_builtin_print)); - ucl_state_put(state, "printl", ucl_builtin_create(ucl_builtin_printl)); + ucl_scope_put(scope, "print", ucl_builtin_create(ucl_builtin_print)); + ucl_scope_put(scope, "printl", ucl_builtin_create(ucl_builtin_printl)); // TODO: // - object -> string // - formatted printing? - ucl_state_put(state, "+", ucl_builtin_create(ucl_builtin_add)); - ucl_state_put(state, "-", ucl_builtin_create(ucl_builtin_sub)); - ucl_state_put(state, "*", ucl_builtin_create(ucl_builtin_mul)); - ucl_state_put(state, "/", ucl_builtin_create(ucl_builtin_div)); - ucl_state_put(state, "%", ucl_builtin_create(ucl_builtin_mod)); - ucl_state_put(state, ">", ucl_builtin_create(ucl_builtin_gt)); - ucl_state_put(state, ">=", ucl_builtin_create(ucl_builtin_ge)); - ucl_state_put(state, "<", ucl_builtin_create(ucl_builtin_lt)); - ucl_state_put(state, "<=", ucl_builtin_create(ucl_builtin_le)); - ucl_state_put(state, "=", ucl_builtin_create(ucl_builtin_num_eq)); - ucl_state_put(state, "not", ucl_builtin_create(ucl_builtin_not)); - ucl_state_put(state, "xor", ucl_builtin_create(ucl_builtin_xor)); + ucl_scope_put(scope, "+", ucl_builtin_create(ucl_builtin_add)); + ucl_scope_put(scope, "-", ucl_builtin_create(ucl_builtin_sub)); + ucl_scope_put(scope, "*", ucl_builtin_create(ucl_builtin_mul)); + ucl_scope_put(scope, "/", ucl_builtin_create(ucl_builtin_div)); + ucl_scope_put(scope, "%", ucl_builtin_create(ucl_builtin_mod)); + ucl_scope_put(scope, ">", ucl_builtin_create(ucl_builtin_gt)); + ucl_scope_put(scope, ">=", ucl_builtin_create(ucl_builtin_ge)); + ucl_scope_put(scope, "<", ucl_builtin_create(ucl_builtin_lt)); + ucl_scope_put(scope, "<=", ucl_builtin_create(ucl_builtin_le)); + ucl_scope_put(scope, "=", ucl_builtin_create(ucl_builtin_num_eq)); + ucl_scope_put(scope, "not", ucl_builtin_create(ucl_builtin_not)); + ucl_scope_put(scope, "xor", ucl_builtin_create(ucl_builtin_xor)); // TODO: // - Floats or nah? - ucl_state_put(state, "concat", ucl_builtin_create(ucl_builtin_concat)); + ucl_scope_put(scope, "concat", ucl_builtin_create(ucl_builtin_concat)); - ucl_state_put(state, "error", ucl_builtin_create(ucl_builtin_error)); - ucl_state_put(state, "type", ucl_builtin_create(ucl_builtin_type)); - ucl_state_put(state, "symbol-p", ucl_builtin_create(ucl_builtin_symbol_p)); - ucl_state_put(state, "string-p", ucl_builtin_create(ucl_builtin_string_p)); - ucl_state_put(state, "int-p", ucl_builtin_create(ucl_builtin_int_p)); - ucl_state_put(state, "list-p", ucl_builtin_create(ucl_builtin_list_p)); + ucl_scope_put(scope, "error", ucl_builtin_create(ucl_builtin_error)); + ucl_scope_put(scope, "type", ucl_builtin_create(ucl_builtin_type)); + ucl_scope_put(scope, "symbol-p", ucl_builtin_create(ucl_builtin_symbol_p)); + ucl_scope_put(scope, "string-p", ucl_builtin_create(ucl_builtin_string_p)); + ucl_scope_put(scope, "int-p", ucl_builtin_create(ucl_builtin_int_p)); + ucl_scope_put(scope, "list-p", ucl_builtin_create(ucl_builtin_list_p)); - ucl_state_put(state, "list", ucl_builtin_create(ucl_builtin_list)); - ucl_state_put(state, "car", ucl_builtin_create(ucl_builtin_car)); - ucl_state_put(state, "cdr", ucl_builtin_create(ucl_builtin_cdr)); - ucl_state_put(state, "nth", ucl_builtin_create(ucl_builtin_nth)); - ucl_state_put(state, "mapcar", ucl_builtin_create(ucl_builtin_mapcar)); - ucl_state_put(state, "equal", ucl_builtin_create(ucl_builtin_mapcar)); + ucl_scope_put(scope, "list", ucl_builtin_create(ucl_builtin_list)); + ucl_scope_put(scope, "car", ucl_builtin_create(ucl_builtin_car)); + ucl_scope_put(scope, "cdr", ucl_builtin_create(ucl_builtin_cdr)); + ucl_scope_put(scope, "nth", ucl_builtin_create(ucl_builtin_nth)); + ucl_scope_put(scope, "mapcar", ucl_builtin_create(ucl_builtin_mapcar)); + ucl_scope_put(scope, "equal", ucl_builtin_create(ucl_builtin_mapcar)); // TODO: // - reduce @@ -80,7 +80,7 @@ int main(int argc, const char **argv) { } struct ucl_object *sexp = ucl_parse(line); - struct ucl_object *result = ucl_evaluate(state, ucl_car(sexp)); + struct ucl_object *result = ucl_evaluate(scope, ucl_car(sexp)); ucl_print_obj(result); printf("\n"); @@ -89,7 +89,7 @@ int main(int argc, const char **argv) { } } else { struct ucl_object *sexp = ucl_parse(argv[1]); - struct ucl_object *result = ucl_evaluate(state, ucl_car(sexp)); + struct ucl_object *result = ucl_evaluate(scope, ucl_car(sexp)); if (result->type == UCL_TYPE_ERROR) { printf("%s", result->error); diff --git a/src/memory.c b/src/memory.c index 14170bb..e21d11b 100644 --- a/src/memory.c +++ b/src/memory.c @@ -9,8 +9,8 @@ #include #include -#ifndef UCL_STATE_ARENA_SIZE -#define UCL_STATE_ARENA_SIZE 16 +#ifndef UCL_SCOPE_ARENA_SIZE +#define UCL_SCOPE_ARENA_SIZE 16 #endif #ifndef UCL_OBJECT_ARENA_SIZE @@ -134,11 +134,11 @@ void ucl_object_mark(struct ucl_object *obj) { } } -void ucl_state_mark(struct ucl_arena * arena, void *obj) { +void ucl_scope_mark(struct ucl_arena * arena, void *obj) { (void) arena; - struct ucl_state *state = (struct ucl_state *) obj; + struct ucl_scope *scope = (struct ucl_scope *) obj; - ucl_object_mark(state->list); + ucl_object_mark(scope->list); } void ucl_gc_unmark(struct ucl_arena * arena, void *obj) { @@ -161,7 +161,7 @@ void ucl_gc_sweep(struct ucl_arena * arena, void *obj) { void ucl_gc() { ucl_arena_map(object_arena, ucl_gc_unmark); - ucl_arena_map(state_arena, ucl_state_mark); + ucl_arena_map(scope_arena, ucl_scope_mark); ucl_arena_map(object_arena, ucl_gc_sweep); } diff --git a/src/scope.c b/src/scope.c new file mode 100644 index 0000000..fb6b7dc --- /dev/null +++ b/src/scope.c @@ -0,0 +1,87 @@ +#include "uclisp.h" +#include "internal.h" +#include "scope.h" +#include "utility.h" +#include "arena.h" + +#include +#include +#include + +// Implements state as a giant alist + +// TODO: Consider generalizing the alist concept + +#define NAME_POSITION 0 +#define DATA_POSITION 1 + +#define SCOPE_ARENA_CAPACITY 32 + +struct ucl_arena *scope_arena; + +static struct ucl_object *ucl_scope_get_cell(struct ucl_scope *scope, const char *name) { + FOREACH_LIST(scope->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_scope_get(struct ucl_scope *scope, const char *name) { + struct ucl_object *cell = ucl_scope_get_cell(scope, name); + if (cell == NULL) { + if (scope->parent == NULL) { + // TODO: Include the symbol name + return ucl_error_create("Unbound symbol"); + } else { + return ucl_scope_get(scope->parent, name); + } + } + return ucl_list_nth(cell, DATA_POSITION); +} + +void ucl_scope_put(struct ucl_scope *scope, const char *name, struct ucl_object *obj) { + struct ucl_object *cell = ucl_scope_get_cell(scope, name); + if (cell == NULL) { + ucl_list_append(scope->list, + ucl_tuple_create( + ucl_string_create(name), + obj)); + } else { + // TODO: Refcounting / cleanup + cell->cell.cdr->cell.car = obj; + } +} + +struct ucl_scope *ucl_scope_create() { + if (scope_arena == NULL) { + scope_arena = ucl_arena_create(sizeof(struct ucl_scope), SCOPE_ARENA_CAPACITY); + } + struct ucl_scope *scope = ucl_arena_get(scope_arena); + scope->list = ucl_nil_create(); + scope->parent = NULL; + return scope; +} + +struct ucl_scope *ucl_scope_create_child(struct ucl_scope *parent) { + struct ucl_scope *scope = ucl_scope_create(); + scope->parent = parent; + return scope; +} + +struct ucl_scope *ucl_scope_get_root(struct ucl_scope *scope) { + while (scope->parent != NULL) { + scope = scope->parent; + } + return scope; +} + +void ucl_scope_delete(struct ucl_scope *scope) { + assert(scope_arena != NULL); + ucl_arena_put(scope_arena, scope); + // Garbage collection will handle the objects, they are shared +} diff --git a/src/scope.h b/src/scope.h new file mode 100644 index 0000000..d955e51 --- /dev/null +++ b/src/scope.h @@ -0,0 +1,15 @@ +#ifndef _UCLISP_SCOPE_H_ +#define _UCLISP_SCOPE_H_ + +struct ucl_scope; + +struct ucl_scope *ucl_scope_create(); +struct ucl_scope *ucl_scope_create_child(struct ucl_scope *parent); + +void ucl_scope_delete(struct ucl_scope *scope); + +struct ucl_object *ucl_scope_get(struct ucl_scope *scope, const char *name); +void ucl_scope_put(struct ucl_scope *scope, const char *name, struct ucl_object *obj); +struct ucl_scope *ucl_scope_get_root(struct ucl_scope *scope); + +#endif diff --git a/src/special.c b/src/special.c index 63655d3..afcf1fb 100644 --- a/src/special.c +++ b/src/special.c @@ -1,55 +1,55 @@ -#include "state.h" +#include "scope.h" #include "lisp.h" #include "utility.h" #include "internal.h" #include -struct ucl_object *ucl_special_let(struct ucl_state *state, struct ucl_object *args) { +struct ucl_object *ucl_special_let(struct ucl_scope *scope, struct ucl_object *args) { // TODO: Check arguments struct ucl_object *assignments = ucl_car(args); struct ucl_object *expressions = ucl_cdr(args); - struct ucl_state *let_state = ucl_state_create_child(state); + struct ucl_scope *let_scope = ucl_scope_create_child(scope); FOREACH_LIST(assignments, iter, item) { // TODO: Check arguments struct ucl_object *sym = ucl_car(item); struct ucl_object *expr = ucl_car(ucl_cdr(item)); - struct ucl_object *value = ucl_evaluate(let_state, expr); + struct ucl_object *value = ucl_evaluate(let_scope, expr); assert(sym->type == UCL_TYPE_SYMBOL); //assert(ucl_list_length(expr)->integer == 1); if (value->type == UCL_TYPE_ERROR) { // TODO cleanup - ucl_state_delete(let_state); + ucl_scope_delete(let_scope); return value; } - ucl_state_put(let_state, sym->symbol, value); + ucl_scope_put(let_scope, sym->symbol, value); } - struct ucl_object *result = ucl_progn(let_state, expressions); - ucl_state_delete(let_state); + struct ucl_object *result = ucl_progn(let_scope, expressions); + ucl_scope_delete(let_scope); return result; } -struct ucl_object *ucl_special_if(struct ucl_state *state, struct ucl_object *args) { +struct ucl_object *ucl_special_if(struct ucl_scope *scope, struct ucl_object *args) { // TODO: Check arguments struct ucl_object *cond = ucl_car(args); struct ucl_object *true_form = ucl_list_nth(args, 1); struct ucl_object *false_forms = ucl_cdr(ucl_cdr(args)); - struct ucl_object *cond_result = ucl_evaluate(state, cond); + struct ucl_object *cond_result = ucl_evaluate(scope, cond); UCL_RET_IF_ERROR(cond_result); if (ucl_truthy(cond_result)->type == UCL_TYPE_SYMBOL) { - return ucl_evaluate(state, true_form); + return ucl_evaluate(scope, true_form); } - return ucl_progn(state, false_forms); + return ucl_progn(scope, false_forms); } -struct ucl_object *ucl_special_defun(struct ucl_state *state, struct ucl_object *args) { +struct ucl_object *ucl_special_defun(struct ucl_scope *scope, struct ucl_object *args) { // TODO: Check arguments struct ucl_object *fun_sym = ucl_car(args); if (fun_sym->type != UCL_TYPE_SYMBOL) { @@ -66,13 +66,13 @@ struct ucl_object *ucl_special_defun(struct ucl_state *state, struct ucl_object // there will be docstrings, maybe not! // Functions are added to the root scope - ucl_state_put(ucl_state_get_root(state), fun_sym->symbol, ucl_cdr(args)); + ucl_scope_put(ucl_scope_get_root(scope), fun_sym->symbol, ucl_cdr(args)); return fun_sym; } -struct ucl_object *ucl_special_lambda(struct ucl_state *state, struct ucl_object *args) { +struct ucl_object *ucl_special_lambda(struct ucl_scope *scope, struct ucl_object *args) { // TODO: Check arguments struct ucl_object *fun_args = ucl_list_nth(args, 0); if (fun_args->type != UCL_TYPE_CELL) { @@ -84,33 +84,33 @@ struct ucl_object *ucl_special_lambda(struct ucl_state *state, struct ucl_object } -struct ucl_object *ucl_special_setq(struct ucl_state *state, struct ucl_object *args) { +struct ucl_object *ucl_special_setq(struct ucl_scope *scope, struct ucl_object *args) { // TODO: Check arguments struct ucl_object *sym = ucl_car(args); - struct ucl_state *root_state = ucl_state_get_root(state); + struct ucl_scope *root_scope = ucl_scope_get_root(scope); if (sym->type != UCL_TYPE_SYMBOL) { return ucl_error_create("First argument to setq must be a symbol"); } - struct ucl_object *value = ucl_evaluate(state, ucl_list_nth(args, 1)); + struct ucl_object *value = ucl_evaluate(scope, ucl_list_nth(args, 1)); - ucl_state_put(root_state, sym->symbol, value); + ucl_scope_put(root_scope, sym->symbol, value); return value; } -struct ucl_object *ucl_special_progn(struct ucl_state *state, struct ucl_object *args) { - return ucl_progn(state, args); +struct ucl_object *ucl_special_progn(struct ucl_scope *scope, struct ucl_object *args) { + return ucl_progn(scope, args); } -struct ucl_object *ucl_special_quote(struct ucl_state *state, struct ucl_object *args) { +struct ucl_object *ucl_special_quote(struct ucl_scope *scope, struct ucl_object *args) { return ucl_car(args); } -struct ucl_object *ucl_special_and(struct ucl_state *state, struct ucl_object *args) { +struct ucl_object *ucl_special_and(struct ucl_scope *scope, struct ucl_object *args) { struct ucl_object *value = ucl_t_create(); FOREACH_LIST(args, iter, form) { - value = ucl_evaluate(state, form); + value = ucl_evaluate(scope, form); if (!ucl_truthy_bool(value)) { return value; } @@ -118,10 +118,10 @@ struct ucl_object *ucl_special_and(struct ucl_state *state, struct ucl_object *a return value; } -struct ucl_object *ucl_special_or(struct ucl_state *state, struct ucl_object *args) { +struct ucl_object *ucl_special_or(struct ucl_scope *scope, struct ucl_object *args) { struct ucl_object *value = ucl_nil_create(); FOREACH_LIST(args, iter, form) { - value = ucl_evaluate(state, form); + value = ucl_evaluate(scope, form); if (ucl_truthy_bool(value)) { return value; } diff --git a/src/special.h b/src/special.h index dea0988..7c43554 100644 --- a/src/special.h +++ b/src/special.h @@ -3,14 +3,14 @@ #include "uclisp.h" -struct ucl_object *ucl_special_let(struct ucl_state *state, struct ucl_object *args); -struct ucl_object *ucl_special_if(struct ucl_state *state, struct ucl_object *args); -struct ucl_object *ucl_special_defun(struct ucl_state *state, struct ucl_object *args); -struct ucl_object *ucl_special_lambda(struct ucl_state *state, struct ucl_object *args); -struct ucl_object *ucl_special_setq(struct ucl_state *state, struct ucl_object *args); -struct ucl_object *ucl_special_progn(struct ucl_state *state, struct ucl_object *args); -struct ucl_object *ucl_special_quote(struct ucl_state *state, struct ucl_object *args); -struct ucl_object *ucl_special_and(struct ucl_state *state, struct ucl_object *args); -struct ucl_object *ucl_special_or(struct ucl_state *state, struct ucl_object *args); +struct ucl_object *ucl_special_let(struct ucl_scope *scope, struct ucl_object *args); +struct ucl_object *ucl_special_if(struct ucl_scope *scope, struct ucl_object *args); +struct ucl_object *ucl_special_defun(struct ucl_scope *scope, struct ucl_object *args); +struct ucl_object *ucl_special_lambda(struct ucl_scope *scope, struct ucl_object *args); +struct ucl_object *ucl_special_setq(struct ucl_scope *scope, struct ucl_object *args); +struct ucl_object *ucl_special_progn(struct ucl_scope *scope, struct ucl_object *args); +struct ucl_object *ucl_special_quote(struct ucl_scope *scope, struct ucl_object *args); +struct ucl_object *ucl_special_and(struct ucl_scope *scope, struct ucl_object *args); +struct ucl_object *ucl_special_or(struct ucl_scope *scope, struct ucl_object *args); #endif diff --git a/src/state.c b/src/state.c deleted file mode 100644 index 287685c..0000000 --- a/src/state.c +++ /dev/null @@ -1,88 +0,0 @@ -#include "uclisp.h" -#include "internal.h" -#include "state.h" -#include "utility.h" -#include "arena.h" - -#include -#include -#include - -// Implements state as a giant alist - -// TODO: Consider generalizing the alist concept -// TODO: Rename 'state' to 'scope' - -#define NAME_POSITION 0 -#define DATA_POSITION 1 - -#define STATE_ARENA_CAPACITY 32 - -struct ucl_arena *state_arena; - -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) { - // TODO: Include the symbol name - return ucl_error_create("Unbound symbol"); - } 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(name), - obj)); - } else { - // TODO: Refcounting / cleanup - cell->cell.cdr->cell.car = obj; - } -} - -struct ucl_state *ucl_state_create() { - if (state_arena == NULL) { - state_arena = ucl_arena_create(sizeof(struct ucl_state), STATE_ARENA_CAPACITY); - } - struct ucl_state *state = ucl_arena_get(state_arena); - 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; -} - -struct ucl_state *ucl_state_get_root(struct ucl_state *state) { - while (state->parent != NULL) { - state = state->parent; - } - return state; -} - -void ucl_state_delete(struct ucl_state *state) { - assert(state_arena != NULL); - ucl_arena_put(state_arena, state); - // Garbage collection will handle the objects, they are shared -} diff --git a/src/state.h b/src/state.h deleted file mode 100644 index 322195d..0000000 --- a/src/state.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef _UCLISP_STATE_H_ -#define _UCLISP_STATE_H_ - -struct ucl_state; - -struct ucl_state *ucl_state_create(); -struct ucl_state *ucl_state_create_child(struct ucl_state *parent); - -void ucl_state_delete(struct ucl_state *state); - -struct ucl_object *ucl_state_get(struct ucl_state *state, const char *name); -void ucl_state_put(struct ucl_state *state, const char *name, struct ucl_object *obj); -struct ucl_state *ucl_state_get_root(struct ucl_state *state); - -#endif diff --git a/src/uclisp.h b/src/uclisp.h index e92fa53..0e959e8 100644 --- a/src/uclisp.h +++ b/src/uclisp.h @@ -17,8 +17,8 @@ struct ucl_cell { struct ucl_object *cdr; }; -struct ucl_state; -typedef struct ucl_object *(*ucl_lisp)(struct ucl_state* state, struct ucl_object *args); +struct ucl_scope; +typedef struct ucl_object *(*ucl_lisp)(struct ucl_scope* state, struct ucl_object *args); struct ucl_object { union { @@ -41,11 +41,11 @@ struct ucl_parse_result { struct ucl_cell *statement; }; -struct ucl_state; // TODO +struct ucl_scope; // TODO struct ucl_object *ucl_tokenize(const char *source); struct ucl_object *ucl_parse(const char *sexp); -struct ucl_object *ucl_evaluate(struct ucl_state *state, struct ucl_object *sexp); +struct ucl_object *ucl_evaluate(struct ucl_scope *state, struct ucl_object *sexp); // TODO: State encapsulation is all wonky here) void ucl_gc(); diff --git a/src/utility.c b/src/utility.c index 90b3249..f43c12b 100644 --- a/src/utility.c +++ b/src/utility.c @@ -162,7 +162,7 @@ void ucl_print_obj(struct ucl_object *obj) { } } -struct ucl_object *ucl_progn(struct ucl_state *state, struct ucl_object *forms) { +struct ucl_object *ucl_progn(struct ucl_scope *state, struct ucl_object *forms) { struct ucl_object *result = NULL; FOREACH_LIST(forms, iter, form) { result = ucl_evaluate(state, form); diff --git a/src/utility.h b/src/utility.h index 2d55427..89f1c4d 100644 --- a/src/utility.h +++ b/src/utility.h @@ -20,7 +20,7 @@ struct ucl_object* ucl_list_nth(struct ucl_object *list, int n); struct ucl_object* ucl_list_append(struct ucl_object *list, struct ucl_object *obj); struct ucl_object* ucl_tuple_create(struct ucl_object *obj0, struct ucl_object *obj1); -struct ucl_object *ucl_progn(struct ucl_state *state, struct ucl_object *forms); +struct ucl_object *ucl_progn(struct ucl_scope *scope, struct ucl_object *forms); void ucl_print_obj(struct ucl_object *obj); diff --git a/test/test_e2e.c b/test/test_e2e.c index 0ba8250..2eca5ca 100644 --- a/test/test_e2e.c +++ b/test/test_e2e.c @@ -6,51 +6,51 @@ #include "internal.h" #include "utility.h" #include "testing_helpers.h" -#include "state.h" +#include "scope.h" #include "builtins.h" #include "special.h" static struct ucl_object *input; static struct ucl_object *response; -static struct ucl_state *state; +static struct ucl_scope *scope; void setUp(void) { input = NULL; response = NULL; - state = ucl_state_create(); - ucl_state_put(state, "let", ucl_special_create(ucl_special_let)); - ucl_state_put(state, "defun", ucl_special_create(ucl_special_defun)); - ucl_state_put(state, "+", ucl_builtin_create(ucl_builtin_add)); - ucl_state_put(state, "error", ucl_builtin_create(ucl_builtin_error)); - ucl_state_put(state, "list", ucl_builtin_create(ucl_builtin_list)); - ucl_state_put(state, "setq", ucl_special_create(ucl_special_setq)); - ucl_state_put(state, "car", ucl_builtin_create(ucl_builtin_car)); - ucl_state_put(state, "cdr", ucl_builtin_create(ucl_builtin_cdr)); - ucl_state_put(state, "nth", ucl_builtin_create(ucl_builtin_nth)); - ucl_state_put(state, "mapcar", ucl_builtin_create(ucl_builtin_mapcar)); - ucl_state_put(state, "lambda", ucl_special_create(ucl_special_lambda)); - ucl_state_put(state, "quote", ucl_special_create(ucl_special_quote)); + scope = ucl_scope_create(); + ucl_scope_put(scope, "let", ucl_special_create(ucl_special_let)); + ucl_scope_put(scope, "defun", ucl_special_create(ucl_special_defun)); + ucl_scope_put(scope, "+", ucl_builtin_create(ucl_builtin_add)); + ucl_scope_put(scope, "error", ucl_builtin_create(ucl_builtin_error)); + ucl_scope_put(scope, "list", ucl_builtin_create(ucl_builtin_list)); + ucl_scope_put(scope, "setq", ucl_special_create(ucl_special_setq)); + ucl_scope_put(scope, "car", ucl_builtin_create(ucl_builtin_car)); + ucl_scope_put(scope, "cdr", ucl_builtin_create(ucl_builtin_cdr)); + ucl_scope_put(scope, "nth", ucl_builtin_create(ucl_builtin_nth)); + ucl_scope_put(scope, "mapcar", ucl_builtin_create(ucl_builtin_mapcar)); + ucl_scope_put(scope, "lambda", ucl_special_create(ucl_special_lambda)); + ucl_scope_put(scope, "quote", ucl_special_create(ucl_special_quote)); } void tearDown(void) { // TODO: Implement GC so we can clean these both up //ucl_object_delete(input); input = NULL; - ucl_state_delete(state); + ucl_scope_delete(scope); ucl_gc(); response = NULL; - state = NULL; + scope = NULL; } static struct ucl_object *eval (const char *code) { struct ucl_object *sexp = ucl_parse(code); - return ucl_evaluate(state, ucl_car(sexp)); + return ucl_evaluate(scope, ucl_car(sexp)); } void test_simple_add(void) { - ucl_state_put(state, "+", ucl_builtin_create(ucl_builtin_add)); + ucl_scope_put(scope, "+", ucl_builtin_create(ucl_builtin_add)); response = eval("(+ 2 3)"); TEST_ASSERT_OBJ_INT(response); TEST_ASSERT_EQUAL(response->integer, 5); @@ -103,7 +103,7 @@ void test_eval_string(void) { } void test_eval_sym_defined(void) { - ucl_state_put(state, "foo", ucl_int_create(2)); + ucl_scope_put(scope, "foo", ucl_int_create(2)); response = eval("foo"); TEST_ASSERT_OBJ_INT(response); TEST_ASSERT_EQUAL(response->integer, 2); diff --git a/test/test_parse.c b/test/test_parse.c index 18ccba0..5b05fb4 100644 --- a/test/test_parse.c +++ b/test/test_parse.c @@ -162,7 +162,7 @@ static void test_tokenize_nil(void) { TEST_ASSERT_NULL(token2->cell.cdr); } -static void test_tokenize_statement(void) { +static void test_tokenize_scopement(void) { response = ucl_tokenize("(foo)"); TEST_ASSERT_NOT_NULL(response); @@ -344,7 +344,7 @@ int main(void) { RUN_TEST(test_token_next_symbol_w_whitespace); RUN_TEST(test_tokenize_empty_str); RUN_TEST(test_tokenize_nil); - RUN_TEST(test_tokenize_statement); + RUN_TEST(test_tokenize_scopement); RUN_TEST(test_parse_atom_symbol); RUN_TEST(test_parse_atom_lparen); RUN_TEST(test_parse_atom_rparen); diff --git a/test/test_state.c b/test/test_scope.c similarity index 69% rename from test/test_state.c rename to test/test_scope.c index 576ee4a..bc7cb52 100644 --- a/test/test_state.c +++ b/test/test_scope.c @@ -4,38 +4,38 @@ #include "uclisp.h" #include "internal.h" -#include "state.h" +#include "scope.h" #include "utility.h" #include "testing_helpers.h" /* static struct ucl_parse_result *result; */ -static struct ucl_state *state; +static struct ucl_scope *scope; static struct ucl_object *response; void setUp(void) { - state = ucl_state_create(); + scope = ucl_scope_create(); } void tearDown(void) { - ucl_state_delete(state); - state = NULL; + ucl_scope_delete(scope); + scope = NULL; } static void test_get_empty(void) { - response = ucl_state_get(state, "foo"); + response = ucl_scope_get(scope, "foo"); TEST_ASSERT_OBJ_ERROR(response); } static void test_put_get(void) { - ucl_state_put(state, "foo", ucl_t_create()); - response = ucl_state_get(state, "foo"); + ucl_scope_put(scope, "foo", ucl_t_create()); + response = ucl_scope_get(scope, "foo"); TEST_ASSERT_T(response); } static void test_put2_get(void) { - ucl_state_put(state, "foo1", ucl_t_create()); - ucl_state_put(state, "foo2", ucl_nil_create()); - response = ucl_state_get(state, "foo1"); + ucl_scope_put(scope, "foo1", ucl_t_create()); + ucl_scope_put(scope, "foo2", ucl_nil_create()); + response = ucl_scope_get(scope, "foo1"); TEST_ASSERT_T(response); } @@ -44,9 +44,9 @@ static void test_put_modify_get(void) { ucl_string_create("bar"), ucl_string_create("baz")); - ucl_state_put(state, "foo", obj); + ucl_scope_put(scope, "foo", obj); ucl_list_append(obj, ucl_string_create("quux")); - response = ucl_state_get(state, "foo"); + response = ucl_scope_get(scope, "foo"); TEST_ASSERT_OBJ_STRING(ucl_list_nth(response, 2)); TEST_ASSERT_EQUAL_STRING(ucl_list_nth(response, 2)->string, "quux"); diff --git a/test/test_utility.c b/test/test_utility.c index 452f8d6..819e6a7 100644 --- a/test/test_utility.c +++ b/test/test_utility.c @@ -5,7 +5,7 @@ #include "uclisp.h" #include "internal.h" #include "utility.h" -#include "state.h" +#include "scope.h" #include "testing_helpers.h" static struct ucl_object *input;