add load primitive and (minimal) stdlib
This commit is contained in:
parent
9ef27f90e1
commit
d6c89d0e6d
7 changed files with 75 additions and 2 deletions
|
|
@ -1,2 +1,5 @@
|
||||||
# wolflisp
|
# wolflisp
|
||||||
a lisp but wolfy. right now it's very minimal... :^)
|
|
||||||
|
A toy Lisp started as a learning project.
|
||||||
|
I might work on making it less toy-ish and more useful-ish, but for now expect
|
||||||
|
bites and nibbles from it if you do things wrong. :^)
|
||||||
|
|
|
||||||
|
|
@ -290,6 +290,8 @@ O list_assoc(In *in, O key, O alist);
|
||||||
O list_reverse(In *in, O list);
|
O list_reverse(In *in, O list);
|
||||||
O list_next(In *in, O *list);
|
O list_next(In *in, O *list);
|
||||||
|
|
||||||
|
int read_expr(In *in, Lx *lex, O *result);
|
||||||
|
|
||||||
V compile(Cm *co, O expr, I toplevel);
|
V compile(Cm *co, O expr, I toplevel);
|
||||||
V disassemble(Cm *co);
|
V disassemble(Cm *co);
|
||||||
O vm_run(Cm *c);
|
O vm_run(Cm *c);
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ V interp_init(In *in) {
|
||||||
PRIM(">", prim_gt, 2, 2);
|
PRIM(">", prim_gt, 2, 2);
|
||||||
PRIM("=", prim_equal, 0, -1); // variadic
|
PRIM("=", prim_equal, 0, -1); // variadic
|
||||||
PRIM("gc", prim_gc, 0, 0);
|
PRIM("gc", prim_gc, 0, 0);
|
||||||
|
PRIM("load", prim_load, 1, 1);
|
||||||
#undef PRIM
|
#undef PRIM
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#include <prim.h>
|
#include <prim.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <wolflisp.h>
|
#include <wolflisp.h>
|
||||||
|
|
||||||
#define BOOL(x) ((x) ? in->t : NIL)
|
#define BOOL(x) ((x) ? in->t : NIL)
|
||||||
|
|
@ -207,3 +208,45 @@ O prim_gc(In *in, O *args, int argc, O env) {
|
||||||
gc_collect(&in->gc);
|
gc_collect(&in->gc);
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
O prim_load(In *in, O *args, int argc, O env) {
|
||||||
|
(void)env;
|
||||||
|
if (argc != 1)
|
||||||
|
error_throw(in, "load: expected 1 argument, got %d", argc);
|
||||||
|
if (type(args[0]) != TYPE_STR)
|
||||||
|
error_throw(in, "load: expected string argument, got %s",
|
||||||
|
typename(type(args[0])));
|
||||||
|
Ss *s = (Ss *)(UNBOX(args[0]) + 1);
|
||||||
|
FILE *fp = fopen(s->data, "r");
|
||||||
|
if (!fp)
|
||||||
|
error_throw(in, "load: could not open file '%s'", s->data);
|
||||||
|
Lx lex = {0, 0, fp, {0}};
|
||||||
|
nexttoken(&lex);
|
||||||
|
O result = NIL;
|
||||||
|
I mark = gc_rootmark(&in->gc);
|
||||||
|
gc_addroot(&in->gc, &result);
|
||||||
|
while (lex.kind != TOK_EOF) {
|
||||||
|
O expr = NIL;
|
||||||
|
if (read_expr(in, &lex, &expr) == -1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
Cm compiler;
|
||||||
|
memset(&compiler, 0, sizeof(Cm));
|
||||||
|
compiler.in = in;
|
||||||
|
|
||||||
|
compile(&compiler, expr, 1);
|
||||||
|
result = vm_run(&compiler);
|
||||||
|
|
||||||
|
free(compiler.code);
|
||||||
|
if (compiler.locals.data)
|
||||||
|
free(compiler.locals.data);
|
||||||
|
if (compiler.constants.data)
|
||||||
|
free(compiler.constants.data);
|
||||||
|
|
||||||
|
nexttoken(&lex);
|
||||||
|
}
|
||||||
|
|
||||||
|
gc_rootreset(&in->gc, mark);
|
||||||
|
fclose(fp);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,3 +18,4 @@ O prim_gt(In *in, O *args, int argc, O env);
|
||||||
O prim_nil_p(In *in, O *args, int argc, O env);
|
O prim_nil_p(In *in, O *args, int argc, O env);
|
||||||
O prim_env(In *in, O *args, int argc, O env);
|
O prim_env(In *in, O *args, int argc, O env);
|
||||||
O prim_gc(In *in, O *args, int argc, O env);
|
O prim_gc(In *in, O *args, int argc, O env);
|
||||||
|
O prim_load(In *in, O *args, int argc, O env);
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@ void repl(void) {
|
||||||
if (setjmp(in.err.handler) == 0) {
|
if (setjmp(in.err.handler) == 0) {
|
||||||
in.err.active = 1;
|
in.err.active = 1;
|
||||||
compile(&compiler, expr, 1);
|
compile(&compiler, expr, 1);
|
||||||
disassemble(&compiler);
|
|
||||||
result = vm_run(&compiler);
|
result = vm_run(&compiler);
|
||||||
println(result);
|
println(result);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
24
src/std.scm
Normal file
24
src/std.scm
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
(def defmacro
|
||||||
|
(mac (name args . body)
|
||||||
|
(list 'def name (cons 'mac (cons args body)))))
|
||||||
|
|
||||||
|
(defmacro defn (name args . body)
|
||||||
|
(list 'def name (cons 'fn (cons args body))))
|
||||||
|
|
||||||
|
(defn map-aux (f acc l)
|
||||||
|
(if (nil? l)
|
||||||
|
(acc f '())
|
||||||
|
(map-aux
|
||||||
|
f
|
||||||
|
(fn (f ys)
|
||||||
|
(acc f (cons (f (head l)) ys)))
|
||||||
|
(tail l))))
|
||||||
|
(defn map (f l)
|
||||||
|
(map-aux f (fn (f x) x) l))
|
||||||
|
|
||||||
|
(defmacro let (bindings . body)
|
||||||
|
(cons
|
||||||
|
(cons 'fn (cons (map head bindings) body))
|
||||||
|
(map (fn (x) (head (tail x))) bindings)))
|
||||||
|
|
||||||
|
'()
|
||||||
Loading…
Add table
Add a link
Reference in a new issue