aboutsummaryrefslogtreecommitdiff
path: root/exts
diff options
context:
space:
mode:
authorMistivia <i@mistivia.com>2025-12-14 04:53:43 +0800
committerMistivia <i@mistivia.com>2025-12-14 04:53:43 +0800
commit995b45685a5d23e9bbf5667b2e9246ba385110cd (patch)
tree039197e5147a1451daaf2c980f602bf52ad18fb1 /exts
parent14469e9fb6db827ce9b1308d11fff1026e50a75f (diff)
clean dir
Diffstat (limited to 'exts')
-rw-r--r--exts/dict.c165
-rw-r--r--exts/vector.c129
2 files changed, 0 insertions, 294 deletions
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 <string.h>
-#include <stdlib.h>
-#include <algds/tree_map.h>
-#include <algds/basic_traits.h>
-
-#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;
-}