M Makefile => Makefile +2 -1
@@ 6,7 6,8 @@
include Makefile.conf
OBJS=src/builtins.o src/charbuf.o src/gc.o src/hashtable.o src/iter.o \
- src/parse.o src/ringbuf.o src/types.o src/util.o src/textcache.o
+ src/parse.o src/ringbuf.o src/types.o src/util.o src/textcache.o \
+ src/module.o
# https://semver.org
VERSION=1.1.0
M Makefile.dep => Makefile.dep +2 -0
@@ 5,6 5,8 @@ gc.o: src/gc.c src/funlisp_internal.h inc/funlisp.h src/iter.h \
src/ringbuf.h src/hashtable.h
hashtable.o: src/hashtable.c src/iter.h src/hashtable.h
iter.o: src/iter.c src/iter.h
+module.o: src/module.c src/funlisp_internal.h inc/funlisp.h src/iter.h \
+ src/ringbuf.h src/hashtable.h
parse.o: src/parse.c src/funlisp_internal.h inc/funlisp.h src/iter.h \
src/ringbuf.h src/hashtable.h src/charbuf.h
ringbuf.o: src/ringbuf.c src/ringbuf.h
A scripts/tests/modules.lisp => scripts/tests/modules.lisp +5 -0
@@ 0,0 1,5 @@
+(import example)
+
+(assert (equal? (getattr example 'foo) "bar"))
+
+; OUTPUT(0)
M src/builtins.c => src/builtins.c +41 -0
@@ 742,6 742,45 @@ static lisp_value *lisp_builtin_let(
return lisp_progn(rt, new_scope, expressions);
}
+static lisp_value *lisp_builtin_import(
+ lisp_runtime *rt, lisp_scope *scope, lisp_list *arglist, void *user)
+{
+ /*
+ * args are NOT evaluated
+ * (import symbol) -> looks up module "symbol" and inserts it into
+ * current scope
+ */
+ lisp_symbol *sym;
+ lisp_module *mod;
+
+ (void) user; /* unused */
+
+ if (!lisp_get_args(rt, arglist, "s", &sym))
+ return NULL;
+
+ if (strcmp(sym->s, "example") == 0)
+ mod = create_example_module(rt);
+ else
+ return lisp_error(rt, LE_NOTFOUND, "module not found");
+
+ lisp_scope_bind(scope, sym, (lisp_value*)mod);
+ return (lisp_value*)mod;
+}
+
+static lisp_value *lisp_builtin_getattr(
+ lisp_runtime *rt, lisp_scope *scope, lisp_list *arglist, void *user)
+{
+ lisp_module *mod;
+ lisp_symbol *sym;
+
+ (void) user;
+
+ if (!lisp_get_args(rt, arglist, "*s", &mod, &sym))
+ return NULL;
+
+ return lisp_scope_lookup(rt, mod->contents, sym);
+}
+
void lisp_scope_populate_builtins(lisp_runtime *rt, lisp_scope *scope)
{
lisp_scope_add_builtin(rt, scope, "eval", lisp_builtin_eval, NULL, 1);
@@ 779,4 818,6 @@ void lisp_scope_populate_builtins(lisp_runtime *rt, lisp_scope *scope)
lisp_scope_add_builtin(rt, scope, "cond", lisp_builtin_cond, NULL, 0);
lisp_scope_add_builtin(rt, scope, "list", lisp_builtin_list, NULL, 1);
lisp_scope_add_builtin(rt, scope, "let", lisp_builtin_let, NULL, 0);
+ lisp_scope_add_builtin(rt, scope, "import", lisp_builtin_import, NULL, 0);
+ lisp_scope_add_builtin(rt, scope, "getattr", lisp_builtin_getattr, NULL, 1);
}
M src/funlisp_internal.h => src/funlisp_internal.h +3 -0
@@ 193,4 193,7 @@ int lisp_text_compare(void *left, void *right);
void lisp_textcache_remove(struct hashtable *cache, struct lisp_text *t);
int lisp_truthy(lisp_value *v);
+
+/* Module stuff */
+lisp_module *create_example_module(lisp_runtime *rt);
#endif
A src/module.c => src/module.c +21 -0
@@ 0,0 1,21 @@
+/*
+ * Module-related functionality. Includes builtin modules.
+ */
+#include "funlisp_internal.h"
+
+static void build_example_module(lisp_runtime *rt, lisp_module *m)
+{
+ lisp_scope_bind(m->contents, lisp_symbol_new(rt, "foo", 0),
+ (lisp_value*)lisp_string_new(rt, "bar", 0));
+}
+
+lisp_module *create_example_module(lisp_runtime *rt)
+{
+ lisp_module *m = (lisp_module *) lisp_new(rt, type_module);
+ m->name = lisp_string_new(rt, "example", 0);
+ m->file = lisp_string_new(rt, __FILE__, 0);
+ m->contents = lisp_new_empty_scope(rt);
+
+ build_example_module(rt, m);
+ return m;
+}