From 995b45685a5d23e9bbf5667b2e9246ba385110cd Mon Sep 17 00:00:00 2001 From: Mistivia Date: Sun, 14 Dec 2025 04:53:43 +0800 Subject: clean dir --- Makefile | 4 +- ext_example/vector.c | 129 ++++++++++++++++++++++++++++++++++++++++ exts/dict.c | 165 --------------------------------------------------- exts/vector.c | 129 ---------------------------------------- tests/vector.lisp | 2 +- 5 files changed, 131 insertions(+), 298 deletions(-) create mode 100644 ext_example/vector.c delete mode 100644 exts/dict.c delete mode 100644 exts/vector.c diff --git a/Makefile b/Makefile index 466de18..dd277b0 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ installdir = /usr/local/lib/ src = $(shell find ./ -maxdepth 1 -name '*.c' -not -name 'main.c') obj = $(src:.c=.o) -extsrc = $(shell find ./exts/ -maxdepth 1 -name '*.c') +extsrc = $(shell find ./ext_example/ -maxdepth 1 -name '*.c') extobj = $(extsrc:.c=.so) tests=$(shell ls tests/*.c) @@ -31,8 +31,6 @@ install: bamboo-lisp libbamboo-lisp.so sudo cp libbamboo-lisp.so $(installdir) sudo mkdir -p /usr/local/include/bamboo_lisp sudo cp *.h /usr/local/include/bamboo_lisp/ - sudo mkdir -p /usr/local/share/bamboo-lisp/exts/ - sudo cp exts/*.so /usr/local/share/bamboo-lisp/exts/ prelude.c: prelude.lisp cat prelude.lisp | python scripts/genprelude.py > prelude.c diff --git a/ext_example/vector.c b/ext_example/vector.c new file mode 100644 index 0000000..a67a504 --- /dev/null +++ b/ext_example/vector.c @@ -0,0 +1,129 @@ +#include "interp.h" +#include "sexp.h" + +#define VECTOR_TYPEID "ext.core.vector" + +LispUserdataMeta bamboo_lisp_array_meta; + +static bool is_vector_impl(Interp *interp, SExpRef vec) { + if (VALTYPE(vec) == kUserDataSExp && strcmp(VECTOR_TYPEID, REF(vec)->userdata_meta->type) == 0) { + return true; + } + return false; +} + +static SExpRef is_vector(Interp* interp, SExpRef args) { + if (LENGTH(args) != 1) return new_error(interp, "vector?: wrongs args num.\n"); + return new_boolean(interp, is_vector_impl(interp, CAR(args))); +} + +static SExpRef make_vector(Interp* interp, SExpRef args) { + SExpRef ret = new_sexp(interp); + REF(ret)->type = kUserDataSExp; + REF(ret)->userdata_meta = &bamboo_lisp_array_meta; + SExpRefVector *data = malloc(sizeof(SExpRefVector)); + SExpRefVector_init(data); + REF(ret)->userdata = data; + return ret; +} + +static SExpRef vector_ref(Interp* interp, SExpRef args) { + if (LENGTH(args) != 2) return new_error(interp, "vector-ref: wrong args num.\n"); + if (!is_vector_impl(interp, CAR(args)) + || REF(CADR(args))->type != kIntegerSExp) { + return new_error(interp, "vector-ref: wrong type.\n"); + } + int n = REF(CADR(args))->integer; + SExpRefVector *vec = REF(CAR(args))->userdata; + if (n >= SExpRefVector_len(vec)) return new_error(interp, "vector-ref: out of bound.\n"); + SExpRef ret = new_sexp(interp); + return *SExpRefVector_ref(vec, n); +} + +static SExpRef vector_append(Interp* interp, SExpRef args) { + if (LENGTH(args) != 2) return new_error(interp, "vector-append: wrong args num.\n"); + if (!is_vector_impl(interp, CAR(args))) return new_error(interp, "vector-append: first arg not a vector.\n"); + + SExpRefVector *vec = REF(CAR(args))->userdata; + SExpRef elem = CADR(args); + SExpRefVector_push_back(vec, elem); + return NIL; +} + +static SExpRef vector_insert(Interp* interp, SExpRef args) { + if (LENGTH(args) != 3) return new_error(interp, "vector-insert: wrong args num.\n"); + if (!is_vector_impl(interp, CAR(args)) || REF(CADR(args))->type != kIntegerSExp) + return new_error(interp, "vector-insert: wrong types.\n"); + + int pos = REF(CADR(args))->integer; + SExpRefVector *vec = REF(CAR(args))->userdata; + SExpRef elem = CADDR(args); + SExpRefVector_insert_before(vec, pos, elem); + return NIL; +} + +static SExpRef vector_delete(Interp* interp, SExpRef args) { + if (LENGTH(args) != 2) return new_error(interp, "vector-remove: wrong args num.\n"); + if (!is_vector_impl(interp, CAR(args)) || REF(CADR(args))->type != kIntegerSExp) + return new_error(interp, "vector-remove: wrong types.\n"); + + int pos = REF(CADR(args))->integer; + SExpRefVector *vec = REF(CAR(args))->userdata; + if (pos >= SExpRefVector_len(vec)) return new_error(interp, "vector-remove: out of bound.\n"); + SExpRefVector_remove(vec, pos); + return NIL; +} + +static SExpRef vector_length(Interp* interp, SExpRef args) { + if (LENGTH(args) != 1) return new_error(interp, "vector-length: wrong args num.\n"); + if (!is_vector_impl(interp, CAR(args))) return new_error(interp, "vector-length: not a vector.\n"); + + SExpRefVector *vec = REF(CAR(args))->userdata; + return new_integer(interp, SExpRefVector_len(vec)); +} + +static SExpRef vector_set(Interp* interp, SExpRef args) { + if (LENGTH(args) != 3) return new_error(interp, "vector-set: wrong args num.\n"); + if (!is_vector_impl(interp, CAR(args)) || REF(CADR(args))->type != kIntegerSExp) + return new_error(interp, "vector-set: wrong types.\n"); + + int pos = REF(CADR(args))->integer; + SExpRefVector *vec = REF(CAR(args))->userdata; + if (pos >= SExpRefVector_len(vec)) return new_error(interp, "vector-set: out of bound.\n"); + + *SExpRefVector_ref(vec, pos) = CADDR(args); + return NIL; +} + +static void vector_free(void *vself) { + SExpRefVector *self = vself; + SExpRefVector_free(self); + free(self); +} + +static void vector_gcmark(Interp *interp, SExpPtrVector *gcstack, void *vself) { + SExpRefVector *vec = (SExpRefVector *)vself; + int vecsize = SExpRefVector_len(vec); + for (int i = 0; i < vecsize; ++i) { + SExpPtr child = REF(*SExpRefVector_ref(vec, i)); + if (child && !child->marked) { + SExpPtrVector_push_back(gcstack, child); + } + } +} + +int bamboo_lisp_ext_init(Interp *interp) { + bamboo_lisp_array_meta.type = VECTOR_TYPEID; + bamboo_lisp_array_meta.free = &vector_free; + bamboo_lisp_array_meta.gcmark = &vector_gcmark; + + Interp_add_userfunc(interp, "vector?", &is_vector); + Interp_add_userfunc(interp, "make-vector", &make_vector); + Interp_add_userfunc(interp, "vector-ref", &vector_ref); + Interp_add_userfunc(interp, "vector-append", &vector_append); + Interp_add_userfunc(interp, "vector-insert", &vector_insert); + Interp_add_userfunc(interp, "vector-remove", &vector_delete); + Interp_add_userfunc(interp, "vector-length", &vector_length); + Interp_add_userfunc(interp, "vector-set", &vector_set); + return 1; +} diff --git a/exts/dict.c b/exts/dict.c deleted file mode 100644 index 02b7d4e..0000000 --- a/exts/dict.c +++ /dev/null @@ -1,165 +0,0 @@ -#include -#include -#include -#include - -#include "interp.h" -#include "sexp.h" - -TREE_MAP_DEF(String, SExpRef); -TREE_MAP_IMPL(String, SExpRef); - -typedef String2SExpRefTreeMap DictMap; -typedef String2SExpRefTreeMapIter DictIter; -typedef String2SExpRefTreeMapNode DictNode; - -LispUserdataMeta bamboo_lisp_dict_meta; - -#define DICT_TYPEID "ext.core.dict" - -static bool is_dict_impl(Interp *interp, SExpRef obj) { - if (VALTYPE(obj) == kUserDataSExp && strcmp(DICT_TYPEID, REF(obj)->userdata_meta->type) == 0) { - return true; - } - return false; -} - -static void dict_free(void *vself) { - DictMap *map = (DictMap *)vself; - - DictIter it = String2SExpRefTreeMap_min(map); - while (it != NULL) { - if (it->key) { - free((void*)it->key); - it->key = NULL; - } - it = String2SExpRefTreeMap_next(map, it); - } - - String2SExpRefTreeMap_free(map); - - free(map); -} - - -static void dict_gcmark(Interp *interp, SExpPtrVector *gcstack, void *vself) { - DictMap *map = (DictMap *)vself; - - DictIter it = String2SExpRefTreeMap_min(map); - while (it != NULL) { - SExpRef val = it->value; - SExpPtr ptr = REF(val); - - if (ptr && !ptr->marked) { - SExpPtrVector_push_back(gcstack, ptr); - } - - it = String2SExpRefTreeMap_next(map, it); - } -} - - -static SExpRef lisp_is_dict(Interp* interp, SExpRef args) { - if (LENGTH(args) != 1) return new_error(interp, "dict?: wrongs args num.\n"); - return new_boolean(interp, is_dict_impl(interp, CAR(args))); -} - -// (make-dict) -static SExpRef lisp_make_dict(Interp* interp, SExpRef args) { - if (LENGTH(args) != 0) return new_error(interp, "make-dict: expects no args.\n"); - - SExpRef ret = new_sexp(interp); - REF(ret)->type = kUserDataSExp; - REF(ret)->userdata_meta = &bamboo_lisp_dict_meta; - - DictMap *map = malloc(sizeof(DictMap)); - if (!map) return new_error(interp, "make-dict: out of memory.\n"); - - String2SExpRefTreeMap_init(map); - REF(ret)->userdata = map; - - return ret; -} - -// (dict-set dict key value) -static SExpRef lisp_dict_set(Interp* interp, SExpRef args) { - if (LENGTH(args) != 3) return new_error(interp, "dict-set: wrong args num.\n"); - - SExpRef r_dict = CAR(args); - SExpRef r_key = CADR(args); - SExpRef r_val = CADDR(args); - - if (!is_dict_impl(interp, r_dict)) return new_error(interp, "dict-set: first arg not a dict.\n"); - if (REF(r_key)->type != kStringSExp) return new_error(interp, "dict-set: key must be a string.\n"); - - DictMap *map = REF(r_dict)->userdata; - const char *key_str = REF(r_key)->str; - - DictIter it = String2SExpRefTreeMap_find(map, key_str); - if (it != NULL) { - it->value = r_val; - } else { - char *key_dup = strdup(key_str); - String2SExpRefTreeMap_insert(map, key_dup, r_val); - } - - return NIL; -} - -// (dict-get dict key) -> value or nil -static SExpRef lisp_dict_get(Interp* interp, SExpRef args) { - if (LENGTH(args) != 2) return new_error(interp, "dict-get: wrong args num.\n"); - - SExpRef r_dict = CAR(args); - SExpRef r_key = CADR(args); - - if (!is_dict_impl(interp, r_dict)) return new_error(interp, "dict-get: first arg not a dict.\n"); - if (REF(r_key)->type != kStringSExp) return new_error(interp, "dict-get: key must be a string.\n"); - - DictMap *map = REF(r_dict)->userdata; - const char *key_str = REF(r_key)->str; - - SExpRef *val_ptr = String2SExpRefTreeMap_get(map, key_str); - if (val_ptr == NULL) { - return NIL; - } - return *val_ptr; -} - -// (dict-remove dict key) -static SExpRef lisp_dict_remove(Interp* interp, SExpRef args) { - if (LENGTH(args) != 2) return new_error(interp, "dict-remove: wrong args num.\n"); - - SExpRef r_dict = CAR(args); - SExpRef r_key = CADR(args); - - if (!is_dict_impl(interp, r_dict)) return new_error(interp, "dict-remove: first arg not a dict.\n"); - if (REF(r_key)->type != kStringSExp) return new_error(interp, "dict-remove: key must be a string.\n"); - - DictMap *map = REF(r_dict)->userdata; - const char *key_str = REF(r_key)->str; - - DictIter it = String2SExpRefTreeMap_find(map, key_str); - if (it != NULL) { - const char *owned_key = it->key; - String2SExpRefTreeMap_remove(map, it); - if (owned_key) free((void*)owned_key); - free(it); - } - - return NIL; -} - -int bamboo_lisp_dict_ext_init(Interp *interp) { - bamboo_lisp_dict_meta.type = DICT_TYPEID; - bamboo_lisp_dict_meta.free = &dict_free; - bamboo_lisp_dict_meta.gcmark = &dict_gcmark; - - Interp_add_userfunc(interp, "dict?", &lisp_is_dict); - Interp_add_userfunc(interp, "make-dict", &lisp_make_dict); - Interp_add_userfunc(interp, "dict-get", &lisp_dict_get); - Interp_add_userfunc(interp, "dict-set", &lisp_dict_set); - Interp_add_userfunc(interp, "dict-remove", &lisp_dict_remove); - // TODO dict-keys - return 1; -} \ No newline at end of file diff --git a/exts/vector.c b/exts/vector.c deleted file mode 100644 index a67a504..0000000 --- a/exts/vector.c +++ /dev/null @@ -1,129 +0,0 @@ -#include "interp.h" -#include "sexp.h" - -#define VECTOR_TYPEID "ext.core.vector" - -LispUserdataMeta bamboo_lisp_array_meta; - -static bool is_vector_impl(Interp *interp, SExpRef vec) { - if (VALTYPE(vec) == kUserDataSExp && strcmp(VECTOR_TYPEID, REF(vec)->userdata_meta->type) == 0) { - return true; - } - return false; -} - -static SExpRef is_vector(Interp* interp, SExpRef args) { - if (LENGTH(args) != 1) return new_error(interp, "vector?: wrongs args num.\n"); - return new_boolean(interp, is_vector_impl(interp, CAR(args))); -} - -static SExpRef make_vector(Interp* interp, SExpRef args) { - SExpRef ret = new_sexp(interp); - REF(ret)->type = kUserDataSExp; - REF(ret)->userdata_meta = &bamboo_lisp_array_meta; - SExpRefVector *data = malloc(sizeof(SExpRefVector)); - SExpRefVector_init(data); - REF(ret)->userdata = data; - return ret; -} - -static SExpRef vector_ref(Interp* interp, SExpRef args) { - if (LENGTH(args) != 2) return new_error(interp, "vector-ref: wrong args num.\n"); - if (!is_vector_impl(interp, CAR(args)) - || REF(CADR(args))->type != kIntegerSExp) { - return new_error(interp, "vector-ref: wrong type.\n"); - } - int n = REF(CADR(args))->integer; - SExpRefVector *vec = REF(CAR(args))->userdata; - if (n >= SExpRefVector_len(vec)) return new_error(interp, "vector-ref: out of bound.\n"); - SExpRef ret = new_sexp(interp); - return *SExpRefVector_ref(vec, n); -} - -static SExpRef vector_append(Interp* interp, SExpRef args) { - if (LENGTH(args) != 2) return new_error(interp, "vector-append: wrong args num.\n"); - if (!is_vector_impl(interp, CAR(args))) return new_error(interp, "vector-append: first arg not a vector.\n"); - - SExpRefVector *vec = REF(CAR(args))->userdata; - SExpRef elem = CADR(args); - SExpRefVector_push_back(vec, elem); - return NIL; -} - -static SExpRef vector_insert(Interp* interp, SExpRef args) { - if (LENGTH(args) != 3) return new_error(interp, "vector-insert: wrong args num.\n"); - if (!is_vector_impl(interp, CAR(args)) || REF(CADR(args))->type != kIntegerSExp) - return new_error(interp, "vector-insert: wrong types.\n"); - - int pos = REF(CADR(args))->integer; - SExpRefVector *vec = REF(CAR(args))->userdata; - SExpRef elem = CADDR(args); - SExpRefVector_insert_before(vec, pos, elem); - return NIL; -} - -static SExpRef vector_delete(Interp* interp, SExpRef args) { - if (LENGTH(args) != 2) return new_error(interp, "vector-remove: wrong args num.\n"); - if (!is_vector_impl(interp, CAR(args)) || REF(CADR(args))->type != kIntegerSExp) - return new_error(interp, "vector-remove: wrong types.\n"); - - int pos = REF(CADR(args))->integer; - SExpRefVector *vec = REF(CAR(args))->userdata; - if (pos >= SExpRefVector_len(vec)) return new_error(interp, "vector-remove: out of bound.\n"); - SExpRefVector_remove(vec, pos); - return NIL; -} - -static SExpRef vector_length(Interp* interp, SExpRef args) { - if (LENGTH(args) != 1) return new_error(interp, "vector-length: wrong args num.\n"); - if (!is_vector_impl(interp, CAR(args))) return new_error(interp, "vector-length: not a vector.\n"); - - SExpRefVector *vec = REF(CAR(args))->userdata; - return new_integer(interp, SExpRefVector_len(vec)); -} - -static SExpRef vector_set(Interp* interp, SExpRef args) { - if (LENGTH(args) != 3) return new_error(interp, "vector-set: wrong args num.\n"); - if (!is_vector_impl(interp, CAR(args)) || REF(CADR(args))->type != kIntegerSExp) - return new_error(interp, "vector-set: wrong types.\n"); - - int pos = REF(CADR(args))->integer; - SExpRefVector *vec = REF(CAR(args))->userdata; - if (pos >= SExpRefVector_len(vec)) return new_error(interp, "vector-set: out of bound.\n"); - - *SExpRefVector_ref(vec, pos) = CADDR(args); - return NIL; -} - -static void vector_free(void *vself) { - SExpRefVector *self = vself; - SExpRefVector_free(self); - free(self); -} - -static void vector_gcmark(Interp *interp, SExpPtrVector *gcstack, void *vself) { - SExpRefVector *vec = (SExpRefVector *)vself; - int vecsize = SExpRefVector_len(vec); - for (int i = 0; i < vecsize; ++i) { - SExpPtr child = REF(*SExpRefVector_ref(vec, i)); - if (child && !child->marked) { - SExpPtrVector_push_back(gcstack, child); - } - } -} - -int bamboo_lisp_ext_init(Interp *interp) { - bamboo_lisp_array_meta.type = VECTOR_TYPEID; - bamboo_lisp_array_meta.free = &vector_free; - bamboo_lisp_array_meta.gcmark = &vector_gcmark; - - Interp_add_userfunc(interp, "vector?", &is_vector); - Interp_add_userfunc(interp, "make-vector", &make_vector); - Interp_add_userfunc(interp, "vector-ref", &vector_ref); - Interp_add_userfunc(interp, "vector-append", &vector_append); - Interp_add_userfunc(interp, "vector-insert", &vector_insert); - Interp_add_userfunc(interp, "vector-remove", &vector_delete); - Interp_add_userfunc(interp, "vector-length", &vector_length); - Interp_add_userfunc(interp, "vector-set", &vector_set); - return 1; -} diff --git a/tests/vector.lisp b/tests/vector.lisp index de22a89..10afde4 100644 --- a/tests/vector.lisp +++ b/tests/vector.lisp @@ -1,4 +1,4 @@ -(loadext "exts/vector.so") +(loadext "ext_example/vector.so") (assert (vector? (make-vector))) (assert (not (vector? 1))) -- cgit v1.0