diff options
| author | Mistivia <i@mistivia.com> | 2025-07-23 17:29:42 +0800 |
|---|---|---|
| committer | Mistivia <i@mistivia.com> | 2025-07-23 17:32:44 +0800 |
| commit | dec35ab80b9cc3b83b3a806835198b0a58cdc0cb (patch) | |
| tree | d1e489c945b5bf9bce1f26b512758cc741ffe880 /primitives.c | |
| parent | cc8ea3f88c75216c7c03342a4a41bbc7d0b354f5 (diff) | |
add ext
Diffstat (limited to 'primitives.c')
| -rw-r--r-- | primitives.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/primitives.c b/primitives.c index 971aa87..1b49bfe 100644 --- a/primitives.c +++ b/primitives.c @@ -3,6 +3,8 @@ #include "sexp.h" #include "parser.h" +#include <dlfcn.h> + SExpRef primitive_assert_exception(Interp *interp, SExpRef args, bool istail) { SExpRef eargs = lisp_eval_args(interp, args); if (VALTYPE(eargs) == kExceptionSignal) return interp->t; @@ -69,6 +71,34 @@ SExpRef primitive_load(Interp *interp, SExpRef args, bool istail) { return ret; } +typedef int (*BambooLispExtInitFn)(Interp *interp); + +SExpRef primitive_loadext(Interp *interp, SExpRef args, bool istail) { + if (CAR(interp->stack).idx != interp->top_level.idx) { + return new_error(interp, "loadext: loadext can only be in top level.\n"); + } + if (LENGTH(args) != 1) return new_error(interp, "loadext: syntax error.\n"); + args = lisp_eval_args(interp, args); + if (VALTYPE(CAR(args)) != kStringSExp) return new_error(interp, "loadext: syntax error.\n"); + const char *filename = REF(CAR(args))->str; + void *handle = dlopen(filename, RTLD_LAZY); + if (!handle) { + return new_error(interp, "Failed to load library: %s\n", dlerror()); + } + dlerror(); + BambooLispExtInitFn init_func = (BambooLispExtInitFn)dlsym(handle, "bamboo_lisp_ext_init"); + const char *error; + if ((error = dlerror()) != NULL) { + dlclose(handle); + return new_error(interp, "Failed to locate symbol: %s\n", error); + } + int ret = (*init_func)(interp); + if (ret < 0) { + return new_error(interp, "Failed to init ext: %s\n", filename); + } + return NIL; +} + SExpRef primitive_return(Interp *interp, SExpRef args, bool istail) { if (LENGTH(args) > 1) { return new_error(interp, "return: syntax error.\n"); |
