~brenns10/funlisp

c4e4105e744c6bdeb7254417001faa262283b44c — Stephen Brennan 1 year, 5 months ago 2255dd2
Add stub import and getattr builtins

Signed-off-by: Stephen Brennan <stephen@brennan.io>
6 files changed, 74 insertions(+), 1 deletions(-)

M Makefile
M Makefile.dep
A scripts/tests/modules.lisp
M src/builtins.c
M src/funlisp_internal.h
A src/module.c
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;
}