summaryrefslogtreecommitdiff
path: root/lisp.c
diff options
context:
space:
mode:
authorFelix Perktold <Felix.Perktold@student.uibk.ac.at>2026-01-18 15:47:48 +0100
committerFelix Perktold <Felix.Perktold@student.uibk.ac.at>2026-01-18 15:47:48 +0100
commitdb3fdda53f16644181a6c68b3e9152af9b300066 (patch)
treef9d3c5c9d9f9752582d162d08c9b0d025a6c6ceb /lisp.c
parentb86d3361836935297c6aedb0318ed8a34e4c52f0 (diff)
add module system to load .so with load_module builtin
Diffstat (limited to 'lisp.c')
-rw-r--r--lisp.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/lisp.c b/lisp.c
index d5f9600..1c80a74 100644
--- a/lisp.c
+++ b/lisp.c
@@ -3,6 +3,7 @@
#include <readline/readline.h>
#include <readline/history.h>
#include <math.h>
+#include <dlfcn.h>
#include "lisp_api.h"
#include "lisp.h"
#include "lex.yy.h"
@@ -488,6 +489,38 @@ value *builtin_lt(env *e, value *args) {
return make_int(1);
}
+value *builtin_load_module(env *e, value *args) {
+ value *fst_arg = eval(e, car(args));
+
+ if (fst_arg->type != VT_STRING) {
+ printf("error: not a string:");
+ print_value(fst_arg);
+ return make_nil(); //TODO: make_err
+ }
+
+ const char *path = fst_arg->as.str;
+
+ void *handle = dlopen(path, RTLD_LAZY);
+ if (!handle) {
+ printf("dlopen error: %s\n", dlerror());
+ return make_nil(); //TODO: make_err
+ }
+
+ module_export *(*init)(void) = dlsym(handle, "module_init");
+
+ if (!init) {
+ printf("not a valid module: %s\n", dlerror());
+ return make_nil(); //TODO: make_err
+ }
+
+ module_export *exports = init();
+ for (int i = 0; exports[i].name; i++) {
+ env_define(e, exports[i].name, exports[i].v);
+ }
+
+ return make_nil();
+}
+
int is_integer(double x) {
return floor(x) == x && isfinite(x);
}