library is now a non-first-class object

This commit is contained in:
Yuichi Nishiwaki 2016-02-18 17:39:32 +09:00
parent 7816be80c1
commit 561c350a12
34 changed files with 308 additions and 282 deletions

View File

@ -282,8 +282,6 @@ pic_callcc_callcc(pic_state *pic)
void void
pic_init_callcc(pic_state *pic) pic_init_callcc(pic_state *pic)
{ {
pic_deflibrary(pic, "(scheme base)"); pic_redefun(pic, "picrin.base", "call-with-current-continuation", pic_callcc_callcc);
pic_redefun(pic, "picrin.base", "call/cc", pic_callcc_callcc);
pic_redefun(pic, pic->PICRIN_BASE, "call-with-current-continuation", pic_callcc_callcc);
pic_redefun(pic, pic->PICRIN_BASE, "call/cc", pic_callcc_callcc);
} }

View File

@ -284,7 +284,7 @@ pic_number_expt(pic_state *pic)
void void
pic_init_math(pic_state *pic) pic_init_math(pic_state *pic)
{ {
pic_deflibrary(pic, "(picrin math)"); pic_deflibrary(pic, "picrin.math");
pic_defun(pic, "floor/", pic_number_floor2); pic_defun(pic, "floor/", pic_number_floor2);
pic_defun(pic, "truncate/", pic_number_trunc2); pic_defun(pic, "truncate/", pic_number_trunc2);

View File

@ -6,14 +6,11 @@
(define-syntax (inc! n) (define-syntax (inc! n)
#`(set! #,n (+ #,n 1))) #`(set! #,n (+ #,n 1)))
(define (number->symbol n)
(string->symbol (number->string n)))
(define (environment . specs) (define (environment . specs)
(let ((library-name `(picrin @@my-environment ,(number->symbol counter)))) (let ((lib (string-append "picrin.@@my-environment." (number->string counter))))
(inc! counter) (inc! counter)
(let ((lib (make-library library-name))) (make-library lib)
(eval `(import ,@specs) lib) (eval `(import ,@specs) lib)
lib))) lib))
(export environment eval)) (export environment eval))

View File

@ -28,12 +28,12 @@
(define (null-environment n) (define (null-environment n)
(if (not (= n 5)) (if (not (= n 5))
(error "unsupported environment version" n) (error "unsupported environment version" n)
(find-library '(scheme null)))) "scheme.null"))
(define (scheme-report-environment n) (define (scheme-report-environment n)
(if (not (= n 5)) (if (not (= n 5))
(error "unsupported environment version" n) (error "unsupported environment version" n)
(find-library '(scheme r5rs)))) "scheme.r5rs"))
(export * + - / < <= = > >= (export * + - / < <= = > >=
abs acos and abs acos and

View File

@ -93,7 +93,7 @@ pic_file_delete(pic_state *pic)
void void
pic_init_file(pic_state *pic) pic_init_file(pic_state *pic)
{ {
pic_deflibrary(pic, "(scheme file)"); pic_deflibrary(pic, "scheme.file");
pic_defun(pic, "open-input-file", pic_file_open_input_file); pic_defun(pic, "open-input-file", pic_file_open_input_file);
pic_defun(pic, "open-binary-input-file", pic_file_open_binary_input_file); pic_defun(pic, "open-binary-input-file", pic_file_open_binary_input_file);

View File

@ -25,7 +25,7 @@ pic_load_load(pic_state *pic)
void void
pic_init_load(pic_state *pic) pic_init_load(pic_state *pic)
{ {
pic_deflibrary(pic, "(scheme load)"); pic_deflibrary(pic, "scheme.load");
pic_defun(pic, "load", pic_load_load); pic_defun(pic, "load", pic_load_load);
} }

View File

@ -85,7 +85,7 @@ pic_str_string_fill_ip(pic_state *pic)
void void
pic_init_mutable_string(pic_state *pic) pic_init_mutable_string(pic_state *pic)
{ {
pic_deflibrary(pic, "(picrin string)"); pic_deflibrary(pic, "picrin.string");
pic_defun(pic, "string-set!", pic_str_string_set); pic_defun(pic, "string-set!", pic_str_string_set);
pic_defun(pic, "string-copy!", pic_str_string_copy_ip); pic_defun(pic, "string-copy!", pic_str_string_copy_ip);

View File

@ -127,7 +127,7 @@ pic_system_getenvs(pic_state *pic)
void void
pic_init_system(pic_state *pic) pic_init_system(pic_state *pic)
{ {
pic_deflibrary(pic, "(scheme process-context)"); pic_deflibrary(pic, "scheme.process-context");
pic_defun(pic, "command-line", pic_system_cmdline); pic_defun(pic, "command-line", pic_system_cmdline);
pic_defun(pic, "exit", pic_system_exit); pic_defun(pic, "exit", pic_system_exit);

View File

@ -41,7 +41,7 @@ pic_jiffies_per_second(pic_state *pic)
void void
pic_init_time(pic_state *pic) pic_init_time(pic_state *pic)
{ {
pic_deflibrary(pic, "(scheme time)"); pic_deflibrary(pic, "scheme.time");
pic_defun(pic, "current-second", pic_current_second); pic_defun(pic, "current-second", pic_current_second);
pic_defun(pic, "current-jiffy", pic_current_jiffy); pic_defun(pic, "current-jiffy", pic_current_jiffy);

View File

@ -13,7 +13,7 @@ pic_random_real(pic_state *pic)
void void
pic_init_random(pic_state *pic) pic_init_random(pic_state *pic)
{ {
pic_deflibrary(pic, "(srfi 27)"); pic_deflibrary(pic, "srfi.27");
pic_defun(pic, "random-real", pic_random_real); pic_defun(pic, "random-real", pic_random_real);
} }

View File

@ -247,11 +247,11 @@ void
pic_init_readline(pic_state *pic){ pic_init_readline(pic_state *pic){
using_history(); using_history();
pic_deflibrary(pic, "(picrin readline)"); pic_deflibrary(pic, "picrin.readline");
pic_defun(pic, "readline", pic_rl_readline); pic_defun(pic, "readline", pic_rl_readline);
pic_deflibrary(pic, "(picrin readline history)"); pic_deflibrary(pic, "picrin.readline.history");
/* pic_defun(pic, "history-offset", pic_rl_history_offset); */ /* pic_defun(pic, "history-offset", pic_rl_history_offset); */
pic_defun(pic, "history-length", pic_rl_history_length); pic_defun(pic, "history-length", pic_rl_history_length);

View File

@ -178,7 +178,7 @@ pic_regexp_regexp_replace(pic_state *pic)
void void
pic_init_regexp(pic_state *pic) pic_init_regexp(pic_state *pic)
{ {
pic_deflibrary(pic, "(picrin regexp)"); pic_deflibrary(pic, "picrin.regexp");
pic_defun(pic, "regexp", pic_regexp_regexp); pic_defun(pic, "regexp", pic_regexp_regexp);
pic_defun(pic, "regexp?", pic_regexp_regexp_p); pic_defun(pic, "regexp?", pic_regexp_regexp_p);

View File

@ -399,10 +399,10 @@ pic_socket_call_with_socket(pic_state *pic)
void void
pic_init_srfi_106(pic_state *pic) pic_init_srfi_106(pic_state *pic)
{ {
#define pic_defun_(pic, name, f) pic_define(pic, pic->lib, name, pic_obj_value(pic_make_proc(pic, f, 0, NULL))) pic_deflibrary(pic, "srfi.106");
#define pic_define_(pic, name, v) pic_define(pic, pic->lib, name, v)
pic_deflibrary(pic, "(srfi 106)"); #define pic_defun_(pic, name, f) pic_define(pic, "srfi.106", name, pic_obj_value(pic_make_proc(pic, f, 0, NULL)))
#define pic_define_(pic, name, v) pic_define(pic, "srfi.106", name, v)
pic_defun_(pic, "socket?", pic_socket_socket_p); pic_defun_(pic, "socket?", pic_socket_socket_p);
pic_defun_(pic, "make-socket", pic_socket_make_socket); pic_defun_(pic, "make-socket", pic_socket_make_socket);

View File

@ -15,7 +15,7 @@ pic_repl_tty_p(pic_state *pic)
void void
pic_init_repl(pic_state *pic) pic_init_repl(pic_state *pic)
{ {
pic_deflibrary(pic, "(picrin repl)"); pic_deflibrary(pic, "picrin.repl");
pic_defun(pic, "tty?", pic_repl_tty_p); pic_defun(pic, "tty?", pic_repl_tty_p);
} }

View File

@ -34,7 +34,7 @@
(scheme eval) (scheme eval)
(scheme r5rs) (scheme r5rs)
(picrin macro)) (picrin macro))
(find-library '(picrin user)))) "picrin.user"))
(define (repl) (define (repl)
(init-env) (init-env)
@ -65,7 +65,7 @@
(lambda (port) (lambda (port)
(let next ((expr (read port))) (let next ((expr (read port)))
(unless (eof-object? expr) (unless (eof-object? expr)
(write (eval expr (find-library '(picrin user)))) (write (eval expr "picrin.user"))
(newline) (newline)
(set! str "") (set! str "")
(next (read port)))))))))) (next (read port))))))))))

View File

@ -41,7 +41,7 @@
(lambda (in) (lambda (in)
(let loop ((expr (read in))) (let loop ((expr (read in)))
(unless (eof-object? expr) (unless (eof-object? expr)
(eval expr (find-library '(picrin user))) (eval expr (find-library "picrin.user"))
(loop (read in))))))) (loop (read in)))))))
(define (main) (define (main)

View File

@ -542,12 +542,24 @@ my $src = <<'EOL';
;;; library primitives ;;; library primitives
(define (mangle name)
(define (->string n)
(if (symbol? n)
(symbol->string n)
(number->string n)))
(define (join strs delim)
(let loop ((res (car strs)) (strs (cdr strs)))
(if (null? strs)
res
(loop (string-append res delim (car strs)) (cdr strs)))))
(join (map ->string name) "."))
(define-macro define-library (define-macro define-library
(lambda (form _) (lambda (form _)
(let ((name (cadr form)) (let ((lib (mangle (cadr form)))
(body (cddr form))) (body (cddr form)))
(let ((new-library (or (find-library name) (make-library name)))) (or (find-library lib) (make-library lib))
(for-each (lambda (expr) (eval expr new-library)) body))))) (for-each (lambda (expr) (eval expr lib)) body))))
(define-macro cond-expand (define-macro cond-expand
(lambda (form _) (lambda (form _)
@ -559,7 +571,7 @@ my $src = <<'EOL';
(memq form (features))) (memq form (features)))
(and (pair? form) (and (pair? form)
(case (car form) (case (car form)
((library) (find-library (cadr form))) ((library) (find-library (mangle (cadr form))))
((not) (not (test (cadr form)))) ((not) (not (test (cadr form))))
((and) (let loop ((form (cdr form))) ((and) (let loop ((form (cdr form)))
(or (null? form) (or (null? form)
@ -584,7 +596,13 @@ my $src = <<'EOL';
(string->symbol (string->symbol
(string-append (string-append
(symbol->string prefix) (symbol->string prefix)
(symbol->string symbol)))))) (symbol->string symbol)))))
(getlib
(lambda (name)
(let ((lib (mangle name)))
(if (find-library lib)
lib
(error "library not found" name))))))
(letrec (letrec
((extract ((extract
(lambda (spec) (lambda (spec)
@ -592,7 +610,7 @@ my $src = <<'EOL';
((only rename prefix except) ((only rename prefix except)
(extract (cadr spec))) (extract (cadr spec)))
(else (else
(or (find-library spec) (error "library not found" spec)))))) (getlib spec)))))
(collect (collect
(lambda (spec) (lambda (spec)
(case (car spec) (case (car spec)
@ -615,8 +633,7 @@ my $src = <<'EOL';
(loop (cdr alist)) (loop (cdr alist))
(cons (car alist) (loop (cdr alist)))))))) (cons (car alist) (loop (cdr alist))))))))
(else (else
(let ((lib (or (find-library spec) (error "library not found" spec)))) (map (lambda (x) (cons x x)) (library-exports (getlib spec))))))))
(map (lambda (x) (cons x x)) (library-exports lib))))))))
(letrec (letrec
((import ((import
(lambda (spec) (lambda (spec)
@ -948,31 +965,37 @@ const char pic_boot[][80] = {
"rm))))\n `(let ()\n ,@(map (lambda (x)\n `(,(the 'def", "rm))))\n `(let ()\n ,@(map (lambda (x)\n `(,(the 'def",
"ine-syntax) ,(car x) ,(cadr x)))\n formal)\n ,@body))))\n\n(d", "ine-syntax) ,(car x) ,(cadr x)))\n formal)\n ,@body))))\n\n(d",
"efine-macro let-syntax\n (lambda (form env)\n `(,(the 'letrec-syntax) ,@(cdr f", "efine-macro let-syntax\n (lambda (form env)\n `(,(the 'letrec-syntax) ,@(cdr f",
"orm))))\n\n\n;;; library primitives\n\n(define-macro define-library\n (lambda (form _", "orm))))\n\n\n;;; library primitives\n\n(define (mangle name)\n (define (->string n)\n ",
")\n (let ((name (cadr form))\n (body (cddr form)))\n (let ((new-li", " (if (symbol? n)\n (symbol->string n)\n (number->string n)))\n (de",
"brary (or (find-library name) (make-library name))))\n (for-each (lambda (", "fine (join strs delim)\n (let loop ((res (car strs)) (strs (cdr strs)))\n ",
"expr) (eval expr new-library)) body)))))\n\n(define-macro cond-expand\n (lambda (f", "(if (null? strs)\n res\n (loop (string-append res delim (car str",
"orm _)\n (letrec\n ((test (lambda (form)\n (or\n ", "s)) (cdr strs)))))\n (join (map ->string name) \".\"))\n\n(define-macro define-libra",
" (eq? form 'else)\n (and (symbol? form)\n ", "ry\n (lambda (form _)\n (let ((lib (mangle (cadr form)))\n (body (cddr",
" (memq form (features)))\n (and (pair? form)\n ", " form)))\n (or (find-library lib) (make-library lib))\n (for-each (lambd",
" (case (car form)\n ((library) (find-library (cad", "a (expr) (eval expr lib)) body))))\n\n(define-macro cond-expand\n (lambda (form _)",
"r form)))\n ((not) (not (test (cadr form))))\n ", "\n (letrec\n ((test (lambda (form)\n (or\n ",
" ((and) (let loop ((form (cdr form)))\n ", " (eq? form 'else)\n (and (symbol? form)\n ",
" (or (null? form)\n (and (test (car form)", "(memq form (features)))\n (and (pair? form)\n ",
") (loop (cdr form))))))\n ((or) (let loop ((form (cdr for", " (case (car form)\n ((library) (find-library (mangle (c",
"m)))\n (and (pair? form)\n ", "adr form))))\n ((not) (not (test (cadr form))))\n ",
" (or (test (car form)) (loop (cdr form))))))\n ", " ((and) (let loop ((form (cdr form)))\n ",
" (else #f)))))))\n (let loop ((clauses (cdr form)))\n (if (null? cla", " (or (null? form)\n (and (test (car fo",
"uses)\n #undefined\n (if (test (caar clauses))\n ", "rm)) (loop (cdr form))))))\n ((or) (let loop ((form (cdr ",
" `(,the-begin ,@(cdar clauses))\n (loop (cdr clauses))))))))\n\n(d", "form)))\n (and (pair? form)\n ",
"efine-macro import\n (lambda (form _)\n (let ((caddr\n (lambda (x) (c", " (or (test (car form)) (loop (cdr form))))))\n ",
"ar (cdr (cdr x)))))\n (prefix\n (lambda (prefix symbol)\n ", " (else #f)))))))\n (let loop ((clauses (cdr form)))\n (if (null? ",
" (string->symbol\n (string-append\n (symbol->strin", "clauses)\n #undefined\n (if (test (caar clauses))\n ",
"g prefix)\n (symbol->string symbol))))))\n (letrec\n ((", " `(,the-begin ,@(cdar clauses))\n (loop (cdr clauses))))))))\n",
"extract\n (lambda (spec)\n (case (car spec)\n ", "\n(define-macro import\n (lambda (form _)\n (let ((caddr\n (lambda (x)",
" ((only rename prefix except)\n (extract (cadr spec)))\n ", " (car (cdr (cdr x)))))\n (prefix\n (lambda (prefix symbol)\n ",
" (else\n (or (find-library spec) (error \"library not found\"", " (string->symbol\n (string-append\n (symbol->st",
" spec))))))\n (collect\n (lambda (spec)\n (case (", "ring prefix)\n (symbol->string symbol)))))\n (getlib\n ",
" (lambda (name)\n (let ((lib (mangle name)))\n (if (",
"find-library lib)\n lib\n (error \"library not ",
"found\" name))))))\n (letrec\n ((extract\n (lambda (spec)\n ",
" (case (car spec)\n ((only rename prefix except)\n ",
" (extract (cadr spec)))\n (else\n (getli",
"b spec)))))\n (collect\n (lambda (spec)\n (case (",
"car spec)\n ((only)\n (let ((alist (collect (cadr s", "car spec)\n ((only)\n (let ((alist (collect (cadr s",
"pec))))\n (map (lambda (var) (assq var alist)) (cddr spec))))\n ", "pec))))\n (map (lambda (var) (assq var alist)) (cddr spec))))\n ",
" ((rename)\n (let ((alist (collect (cadr spec)))\n ", " ((rename)\n (let ((alist (collect (cadr spec)))\n ",
@ -985,25 +1008,24 @@ const char pic_boot[][80] = {
"f (null? alist)\n '()\n (if (memq ", "f (null? alist)\n '()\n (if (memq ",
"(caar alist) (cddr spec))\n (loop (cdr alist))\n ", "(caar alist) (cddr spec))\n (loop (cdr alist))\n ",
" (cons (car alist) (loop (cdr alist))))))))\n ", " (cons (car alist) (loop (cdr alist))))))))\n ",
" (else\n (let ((lib (or (find-library spec) (error \"library not ", " (else\n (map (lambda (x) (cons x x)) (library-exports (getlib s",
"found\" spec))))\n (map (lambda (x) (cons x x)) (library-exports", "pec))))))))\n (letrec\n ((import\n (lambda (spec)\n ",
" lib))))))))\n (letrec\n ((import\n (lambda (spec)\n", " (let ((lib (extract spec))\n (alist (collec",
" (let ((lib (extract spec))\n (alist (colle", "t spec)))\n (for-each\n (lambda (slot)\n ",
"ct spec)))\n (for-each\n (lambda (slot)\n ", " (library-import lib (cdr slot) (car slot)))\n ",
" (library-import lib (cdr slot) (car slot)))\n ", "alist)))))\n (for-each import (cdr form)))))))\n\n(define-macro export\n (",
" alist)))))\n (for-each import (cdr form)))))))\n\n(define-macro export\n ", "lambda (form _)\n (letrec\n ((collect\n (lambda (spec)\n ",
"(lambda (form _)\n (letrec\n ((collect\n (lambda (spec)\n ", " (cond\n ((symbol? spec)\n `(,spec . ,spec))\n ",
" (cond\n ((symbol? spec)\n `(,spec . ,spec))\n ", " ((and (list? spec) (= (length spec) 3) (eq? (car spec) 'rename))\n ",
" ((and (list? spec) (= (length spec) 3) (eq? (car spec) 'rename))\n ", " `(,(list-ref spec 1) . ,(list-ref spec 2)))\n (else\n (",
" `(,(list-ref spec 1) . ,(list-ref spec 2)))\n (else\n ", "error \"malformed export\")))))\n (export\n (lambda (spec)\n ",
"(error \"malformed export\")))))\n (export\n (lambda (spec)\n ", " (let ((slot (collect spec)))\n (library-export (car slot) (cd",
" (let ((slot (collect spec)))\n (library-export (car slot) (c", "r slot))))))\n (for-each export (cdr form)))))\n\n(export define lambda quote ",
"dr slot))))))\n (for-each export (cdr form)))))\n\n(export define lambda quote", "set! if begin define-macro\n let let* letrec letrec*\n let-values le",
" set! if begin define-macro\n let let* letrec letrec*\n let-values l", "t*-values define-values\n quasiquote unquote unquote-splicing\n and ",
"et*-values define-values\n quasiquote unquote unquote-splicing\n and", "or\n cond case else =>\n do when unless\n parameterize\n ",
" or\n cond case else =>\n do when unless\n parameterize\n ", " define-syntax\n syntax-quote syntax-unquote\n syntax-quasiquote syn",
" define-syntax\n syntax-quote syntax-unquote\n syntax-quasiquote sy", "tax-unquote-splicing\n let-syntax letrec-syntax\n syntax-error)\n\n\n",
"ntax-unquote-splicing\n let-syntax letrec-syntax\n syntax-error)\n\n\n",
"", "",
"" ""
}; };

View File

@ -885,20 +885,23 @@ pic_compile(pic_state *pic, pic_value obj)
} }
pic_value pic_value
pic_eval(pic_state *pic, pic_value program, struct pic_lib *lib) pic_eval(pic_state *pic, pic_value program, const char *lib)
{ {
struct pic_lib *prev_lib = pic->lib; const char *prev_lib = pic_current_library(pic);
struct pic_env *env;
pic_value r; pic_value r;
pic->lib = lib; env = pic_library_environment(pic, lib);
pic_in_library(pic, lib);
pic_try { pic_try {
r = pic_call(pic, pic_compile(pic, pic_expand(pic, program, lib->env)), 0); r = pic_call(pic, pic_compile(pic, pic_expand(pic, program, env)), 0);
} }
pic_catch { pic_catch {
pic->lib = prev_lib; pic_in_library(pic, prev_lib);
pic_raise(pic, pic->err); pic_raise(pic, pic->err);
} }
pic->lib = prev_lib; pic_in_library(pic, prev_lib);
return r; return r;
} }
@ -906,13 +909,12 @@ pic_eval(pic_state *pic, pic_value program, struct pic_lib *lib)
static pic_value static pic_value
pic_eval_eval(pic_state *pic) pic_eval_eval(pic_state *pic)
{ {
pic_value program, lib; pic_value program;
const char *str;
pic_get_args(pic, "oo", &program, &lib); pic_get_args(pic, "oz", &program, &str);
pic_assert_type(pic, lib, lib); return pic_eval(pic, program, str);
return pic_eval(pic, program, pic_lib_ptr(lib));
} }
void void

View File

@ -34,7 +34,6 @@ struct pic_object {
struct pic_context cxt; struct pic_context cxt;
struct pic_port port; struct pic_port port;
struct pic_error err; struct pic_error err;
struct pic_lib lib;
struct pic_checkpoint cp; struct pic_checkpoint cp;
} u; } u;
}; };
@ -347,20 +346,11 @@ gc_mark_object(pic_state *pic, struct pic_object *obj)
gc_mark_object(pic, (struct pic_object *)kh_val(h, it)); gc_mark_object(pic, (struct pic_object *)kh_val(h, it));
} }
} }
if (obj->u.env.prefix) {
gc_mark_object(pic, (struct pic_object *)obj->u.env.prefix);
}
if (obj->u.env.up) { if (obj->u.env.up) {
LOOP(obj->u.env.up); LOOP(obj->u.env.up);
} }
break; break;
} }
case PIC_TT_LIB: {
gc_mark(pic, obj->u.lib.name);
gc_mark_object(pic, (struct pic_object *)obj->u.lib.env);
LOOP(obj->u.lib.exports);
break;
}
case PIC_TT_DATA: { case PIC_TT_DATA: {
if (obj->u.data.type->mark) { if (obj->u.data.type->mark) {
obj->u.data.type->mark(pic, obj->u.data.data, gc_mark); obj->u.data.type->mark(pic, obj->u.data.data, gc_mark);
@ -428,6 +418,7 @@ gc_mark_phase(pic_state *pic)
pic_callinfo *ci; pic_callinfo *ci;
struct pic_proc **xhandler; struct pic_proc **xhandler;
struct pic_list *list; struct pic_list *list;
khiter_t it;
size_t j; size_t j;
assert(pic->heap->weaks == NULL); assert(pic->heap->weaks == NULL);
@ -492,12 +483,19 @@ gc_mark_phase(pic_state *pic)
/* features */ /* features */
gc_mark(pic, pic->features); gc_mark(pic, pic->features);
/* library table */
gc_mark(pic, pic->libs);
/* parameter table */ /* parameter table */
gc_mark(pic, pic->ptable); gc_mark(pic, pic->ptable);
/* library table */
for (it = kh_begin(&pic->ltable); it != kh_end(&pic->ltable); ++it) {
if (! kh_exist(&pic->ltable, it)) {
continue;
}
gc_mark_object(pic, (struct pic_object *)kh_val(&pic->ltable, it).name);
gc_mark_object(pic, (struct pic_object *)kh_val(&pic->ltable, it).env);
gc_mark_object(pic, (struct pic_object *)kh_val(&pic->ltable, it).exports);
}
/* weak maps */ /* weak maps */
do { do {
struct pic_object *key; struct pic_object *key;
@ -580,7 +578,6 @@ gc_finalize_object(pic_state *pic, struct pic_object *obj)
case PIC_TT_PORT: case PIC_TT_PORT:
case PIC_TT_ERROR: case PIC_TT_ERROR:
case PIC_TT_ID: case PIC_TT_ID:
case PIC_TT_LIB:
case PIC_TT_RECORD: case PIC_TT_RECORD:
case PIC_TT_CP: case PIC_TT_CP:
break; break;

View File

@ -63,17 +63,18 @@ void pic_add_feature(pic_state *, const char *);
void pic_defun(pic_state *, const char *, pic_func_t); void pic_defun(pic_state *, const char *, pic_func_t);
void pic_defvar(pic_state *, const char *, pic_value, struct pic_proc *); void pic_defvar(pic_state *, const char *, pic_value, struct pic_proc *);
void pic_define(pic_state *, struct pic_lib *, const char *, pic_value); void pic_define(pic_state *, const char *, const char *, pic_value);
pic_value pic_ref(pic_state *, struct pic_lib *, const char *); pic_value pic_ref(pic_state *, const char *, const char *);
void pic_set(pic_state *, struct pic_lib *, const char *, pic_value); void pic_set(pic_state *, const char *, const char *, pic_value);
pic_value pic_closure_ref(pic_state *, int); pic_value pic_closure_ref(pic_state *, int);
void pic_closure_set(pic_state *, int, pic_value); void pic_closure_set(pic_state *, int, pic_value);
pic_value pic_funcall(pic_state *pic, struct pic_lib *, const char *, int, ...); pic_value pic_funcall(pic_state *pic, const char *, const char *, int, ...);
struct pic_lib *pic_make_library(pic_state *, pic_value); void pic_make_library(pic_state *, const char *);
void pic_in_library(pic_state *, pic_value); void pic_in_library(pic_state *, const char *);
struct pic_lib *pic_find_library(pic_state *, pic_value); bool pic_find_library(pic_state *, const char *);
void pic_import(pic_state *, struct pic_lib *); const char *pic_current_library(pic_state *);
void pic_import(pic_state *, const char *);
void pic_export(pic_state *, pic_sym *); void pic_export(pic_state *, pic_sym *);
PIC_NORETURN void pic_panic(pic_state *, const char *); PIC_NORETURN void pic_panic(pic_state *, const char *);
@ -186,7 +187,6 @@ int pic_str_hash(pic_state *, struct pic_string *);
#include "picrin/data.h" #include "picrin/data.h"
#include "picrin/dict.h" #include "picrin/dict.h"
#include "picrin/error.h" #include "picrin/error.h"
#include "picrin/lib.h"
#include "picrin/macro.h" #include "picrin/macro.h"
#include "picrin/pair.h" #include "picrin/pair.h"
#include "picrin/port.h" #include "picrin/port.h"
@ -215,16 +215,15 @@ pic_value pic_read_cstr(pic_state *, const char *);
void pic_load(pic_state *, struct pic_port *); void pic_load(pic_state *, struct pic_port *);
void pic_load_cstr(pic_state *, const char *); void pic_load_cstr(pic_state *, const char *);
pic_value pic_eval(pic_state *, pic_value, struct pic_lib *); pic_value pic_eval(pic_state *, pic_value, const char *);
struct pic_proc *pic_make_var(pic_state *, pic_value, struct pic_proc *); struct pic_proc *pic_make_var(pic_state *, pic_value, struct pic_proc *);
#define pic_deflibrary(pic, spec) do { \ #define pic_deflibrary(pic, lib) do { \
pic_value libname = pic_read_cstr(pic, spec); \ if (! pic_find_library(pic, lib)) { \
if (pic_find_library(pic, libname) == NULL) { \ pic_make_library(pic, lib); \
pic_make_library(pic, libname); \ } \
} \ pic_in_library(pic, lib); \
pic_in_library(pic, libname); \
} while (0) } while (0)
void pic_warnf(pic_state *, const char *, ...); void pic_warnf(pic_state *, const char *, ...);
@ -242,6 +241,8 @@ void pic_fprintf(pic_state *, struct pic_port *, const char *, ...);
pic_value pic_display(pic_state *, pic_value); pic_value pic_display(pic_state *, pic_value);
pic_value pic_fdisplay(pic_state *, pic_value, xFILE *); pic_value pic_fdisplay(pic_state *, pic_value, xFILE *);
struct pic_env *pic_library_environment(pic_state *, const char *);
#if DEBUG #if DEBUG
# define pic_debug(pic,obj) pic_fwrite(pic,obj,xstderr) # define pic_debug(pic,obj) pic_fwrite(pic,obj,xstderr)
# define pic_fdebug(pic,obj,file) pic_fwrite(pic,obj,file) # define pic_fdebug(pic,obj,file) pic_fwrite(pic,obj,file)

View File

@ -206,6 +206,15 @@ typedef khint_t khiter_t;
#define kh_ptr_hash_equal(a, b) ((a) == (b)) #define kh_ptr_hash_equal(a, b) ((a) == (b))
#define kh_int_hash_func(key) (int)(key) #define kh_int_hash_func(key) (int)(key)
#define kh_int_hash_equal(a, b) ((a) == (b)) #define kh_int_hash_equal(a, b) ((a) == (b))
PIC_INLINE int kh_str_hash_func(const char *s) {
int h = 0;
while (*s) {
h = (h << 5) - h + *s++;
}
return h;
}
#define kh_str_cmp_func(a, b) (strcmp((a), (b)) == 0)
/* --- END OF HASH FUNCTIONS --- */ /* --- END OF HASH FUNCTIONS --- */

View File

@ -1,26 +0,0 @@
/**
* See Copyright Notice in picrin.h
*/
#ifndef PICRIN_LIB_H
#define PICRIN_LIB_H
#if defined(__cplusplus)
extern "C" {
#endif
struct pic_lib {
PIC_OBJECT_HEADER
pic_value name;
struct pic_env *env;
struct pic_dict *exports;
};
#define pic_lib_p(o) (pic_type(o) == PIC_TT_LIB)
#define pic_lib_ptr(o) ((struct pic_lib *)pic_ptr(o))
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -15,7 +15,7 @@ struct pic_env {
PIC_OBJECT_HEADER PIC_OBJECT_HEADER
khash_t(env) map; khash_t(env) map;
struct pic_env *up; struct pic_env *up;
struct pic_string *prefix; struct pic_string *lib;
}; };
#define pic_env_p(v) (pic_type(v) == PIC_TT_ENV) #define pic_env_p(v) (pic_type(v) == PIC_TT_ENV)

View File

@ -16,7 +16,11 @@ extern "C" {
#include "picrin/read.h" #include "picrin/read.h"
#include "picrin/gc.h" #include "picrin/gc.h"
KHASH_DECLARE(oblist, struct pic_string *, pic_sym *) struct pic_lib {
struct pic_string *name;
struct pic_env *env;
struct pic_dict *exports;
};
typedef struct pic_checkpoint { typedef struct pic_checkpoint {
PIC_OBJECT_HEADER PIC_OBJECT_HEADER
@ -37,6 +41,9 @@ typedef struct {
struct pic_context *up; struct pic_context *up;
} pic_callinfo; } pic_callinfo;
KHASH_DECLARE(oblist, struct pic_string *, pic_sym *)
KHASH_DECLARE(ltable, const char *, struct pic_lib)
struct pic_state { struct pic_state {
pic_allocf allocf; pic_allocf allocf;
void *userdata; void *userdata;
@ -68,16 +75,13 @@ struct pic_state {
pic_sym *sCONS, *sCAR, *sCDR, *sNILP, *sSYMBOLP, *sPAIRP; pic_sym *sCONS, *sCAR, *sCDR, *sNILP, *sSYMBOLP, *sPAIRP;
pic_sym *sADD, *sSUB, *sMUL, *sDIV, *sEQ, *sLT, *sLE, *sGT, *sGE, *sNOT; pic_sym *sADD, *sSUB, *sMUL, *sDIV, *sEQ, *sLT, *sLE, *sGT, *sGE, *sNOT;
struct pic_lib *PICRIN_BASE;
struct pic_lib *PICRIN_USER;
pic_value features; pic_value features;
khash_t(oblist) oblist; /* string to symbol */ khash_t(oblist) oblist; /* string to symbol */
int ucnt; int ucnt;
struct pic_weak *globals; struct pic_weak *globals;
struct pic_weak *macros; struct pic_weak *macros;
pic_value libs; khash_t(ltable) ltable;
struct pic_list ireps; /* chain */ struct pic_list ireps; /* chain */
pic_reader reader; pic_reader reader;

View File

@ -169,7 +169,6 @@ enum pic_tt {
PIC_TT_ERROR, PIC_TT_ERROR,
PIC_TT_ID, PIC_TT_ID,
PIC_TT_ENV, PIC_TT_ENV,
PIC_TT_LIB,
PIC_TT_DATA, PIC_TT_DATA,
PIC_TT_DICT, PIC_TT_DICT,
PIC_TT_WEAK, PIC_TT_WEAK,
@ -197,7 +196,6 @@ struct pic_proc;
struct pic_port; struct pic_port;
struct pic_error; struct pic_error;
struct pic_env; struct pic_env;
struct pic_lib;
/* set aliases to basic types */ /* set aliases to basic types */
typedef struct pic_symbol pic_sym; typedef struct pic_symbol pic_sym;
@ -298,8 +296,6 @@ pic_type_repr(enum pic_tt tt)
return "proc"; return "proc";
case PIC_TT_ENV: case PIC_TT_ENV:
return "env"; return "env";
case PIC_TT_LIB:
return "lib";
case PIC_TT_DATA: case PIC_TT_DATA:
return "data"; return "data";
case PIC_TT_DICT: case PIC_TT_DICT:

View File

@ -4,22 +4,38 @@
#include "picrin.h" #include "picrin.h"
KHASH_DEFINE(ltable, const char *, struct pic_lib, kh_str_hash_func, kh_str_cmp_func)
static struct pic_lib *
get_library_opt(pic_state *pic, const char *lib)
{
khash_t(ltable) *h = &pic->ltable;
khiter_t it;
it = kh_get(ltable, h, lib);
if (it == kh_end(h)) {
return NULL;
}
return &kh_val(h, it);
}
static struct pic_lib *
get_library(pic_state *pic, const char *lib)
{
struct pic_lib *libp;
if ((libp = get_library_opt(pic, lib)) == NULL) {
pic_errorf(pic, "library not found: %s", lib);
}
return libp;
}
static struct pic_env * static struct pic_env *
make_library_env(pic_state *pic, pic_value name) make_library_env(pic_state *pic, struct pic_string *name)
{ {
struct pic_env *env; struct pic_env *env;
pic_value dir, it;
struct pic_string *prefix = NULL;
pic_for_each (dir, name, it) { env = pic_make_topenv(pic, name);
if (prefix == NULL) {
prefix = pic_format(pic, "~a", dir);
} else {
prefix = pic_format(pic, "~a.~a", pic_obj_value(prefix), dir);
}
}
env = pic_make_topenv(pic, prefix);
/* set up default environment */ /* set up default environment */
pic_put_identifier(pic, (pic_id *)pic->sDEFINE_LIBRARY, pic->sDEFINE_LIBRARY, env); pic_put_identifier(pic, (pic_id *)pic->sDEFINE_LIBRARY, pic->sDEFINE_LIBRARY, env);
@ -30,64 +46,76 @@ make_library_env(pic_state *pic, pic_value name)
return env; return env;
} }
struct pic_lib * void
pic_make_library(pic_state *pic, pic_value name) pic_make_library(pic_state *pic, const char *lib)
{ {
struct pic_lib *lib; khash_t(ltable) *h = &pic->ltable;
const char *old_lib;
struct pic_string *name;
struct pic_env *env; struct pic_env *env;
struct pic_dict *exports; struct pic_dict *exports;
khiter_t it;
int ret;
if ((lib = pic_find_library(pic, name)) != NULL) { if (pic->lib) {
pic_errorf(pic, "library name already in use: ~s", name); old_lib = pic_current_library(pic);
} }
name = pic_make_cstr(pic, lib);
env = make_library_env(pic, name); env = make_library_env(pic, name);
exports = pic_make_dict(pic); exports = pic_make_dict(pic);
lib = (struct pic_lib *)pic_obj_alloc(pic, sizeof(struct pic_lib), PIC_TT_LIB); it = kh_put(ltable, h, pic_str_cstr(pic, name), &ret);
lib->name = name; if (ret == 0) { /* if exists */
lib->env = env; pic_errorf(pic, "library name already in use: %s", lib);
lib->exports = exports; }
/* register! */ kh_val(h, it).name = name;
pic->libs = pic_acons(pic, name, pic_obj_value(lib), pic->libs); kh_val(h, it).env = env;
kh_val(h, it).exports = exports;
return lib; if (pic->lib) {
pic->lib = get_library(pic, old_lib); /* ltable might be rehashed */
}
} }
void void
pic_in_library(pic_state *pic, pic_value name) pic_in_library(pic_state *pic, const char *lib)
{ {
struct pic_lib *lib; pic->lib = get_library(pic, lib);
if ((lib = pic_find_library(pic, name)) == NULL) {
pic_errorf(pic, "library not found ~s", name);
}
pic->lib = lib;
} }
struct pic_lib * bool
pic_find_library(pic_state *pic, pic_value spec) pic_find_library(pic_state *pic, const char *lib)
{ {
pic_value v; return get_library_opt(pic, lib) != NULL;
}
v = pic_assoc(pic, spec, pic->libs, NULL); const char *
if (pic_false_p(v)) { pic_current_library(pic_state *pic)
return NULL; {
} return pic_str_cstr(pic, pic->lib->name);
return pic_lib_ptr(pic_cdr(pic, v)); }
struct pic_env *
pic_library_environment(pic_state *pic, const char *lib)
{
return get_library(pic, lib)->env;
} }
void void
pic_import(pic_state *pic, struct pic_lib *lib) pic_import(pic_state *pic, const char *lib)
{ {
pic_sym *name, *realname, *uid; pic_sym *name, *realname, *uid;
khiter_t it; khiter_t it;
struct pic_lib *libp;
pic_dict_for_each (name, lib->exports, it) { libp = get_library(pic, lib);
realname = pic_sym_ptr(pic_dict_ref(pic, lib->exports, name));
if ((uid = pic_find_identifier(pic, (pic_id *)realname, lib->env)) == NULL) { pic_dict_for_each (name, libp->exports, it) {
realname = pic_sym_ptr(pic_dict_ref(pic, libp->exports, name));
if ((uid = pic_find_identifier(pic, (pic_id *)realname, libp->env)) == NULL) {
pic_errorf(pic, "attempted to export undefined variable '~s'", pic_obj_value(realname)); pic_errorf(pic, "attempted to export undefined variable '~s'", pic_obj_value(realname));
} }
pic_put_identifier(pic, (pic_id *)name, uid, pic->lib->env); pic_put_identifier(pic, (pic_id *)name, uid, pic->lib->env);
@ -103,42 +131,38 @@ pic_export(pic_state *pic, pic_sym *name)
static pic_value static pic_value
pic_lib_make_library(pic_state *pic) pic_lib_make_library(pic_state *pic)
{ {
pic_value name; const char *lib;
pic_get_args(pic, "o", &name); pic_get_args(pic, "z", &lib);
return pic_obj_value(pic_make_library(pic, name)); pic_make_library(pic, lib);
return pic_undef_value();
} }
static pic_value static pic_value
pic_lib_find_library(pic_state *pic) pic_lib_find_library(pic_state *pic)
{ {
pic_value name; const char *lib;
struct pic_lib *lib;
pic_get_args(pic, "o", &name); pic_get_args(pic, "z", &lib);
if ((lib = pic_find_library(pic, name)) == NULL) { return pic_bool_value(pic_find_library(pic, lib));
return pic_false_value();
}
return pic_obj_value(lib);
} }
static pic_value static pic_value
pic_lib_current_library(pic_state *pic) pic_lib_current_library(pic_state *pic)
{ {
pic_value lib; const char *lib;
int n; int n;
n = pic_get_args(pic, "|o", &lib); n = pic_get_args(pic, "|z", &lib);
if (n == 0) { if (n == 0) {
return pic_obj_value(pic->lib); return pic_obj_value(pic->lib->name);
} }
else { else {
pic_assert_type(pic, lib, lib); pic_in_library(pic, lib);
pic->lib = pic_lib_ptr(lib);
return pic_undef_value(); return pic_undef_value();
} }
@ -147,27 +171,25 @@ pic_lib_current_library(pic_state *pic)
static pic_value static pic_value
pic_lib_library_import(pic_state *pic) pic_lib_library_import(pic_state *pic)
{ {
pic_value lib_opt; const char *lib;
pic_sym *name, *realname, *uid, *alias = NULL; pic_sym *name, *realname, *uid, *alias = NULL;
struct pic_lib *lib; struct pic_lib *libp;
pic_get_args(pic, "om|m", &lib_opt, &name, &alias); pic_get_args(pic, "zm|m", &lib, &name, &alias);
pic_assert_type(pic, lib_opt, lib);
if (alias == NULL) { if (alias == NULL) {
alias = name; alias = name;
} }
lib = pic_lib_ptr(lib_opt); libp = get_library(pic, lib);
if (! pic_dict_has(pic, lib->exports, name)) { if (! pic_dict_has(pic, libp->exports, name)) {
pic_errorf(pic, "attempted to import undefined variable '~s'", pic_obj_value(name)); pic_errorf(pic, "attempted to import undefined variable '~s'", pic_obj_value(name));
} else { } else {
realname = pic_sym_ptr(pic_dict_ref(pic, lib->exports, name)); realname = pic_sym_ptr(pic_dict_ref(pic, libp->exports, name));
} }
if ((uid = pic_find_identifier(pic, (pic_id *)realname, lib->env)) == NULL) { if ((uid = pic_find_identifier(pic, (pic_id *)realname, libp->env)) == NULL) {
pic_errorf(pic, "attempted to export undefined variable '~s'", pic_obj_value(realname)); pic_errorf(pic, "attempted to export undefined variable '~s'", pic_obj_value(realname));
} else { } else {
pic_put_identifier(pic, (pic_id *)alias, uid, pic->lib->env); pic_put_identifier(pic, (pic_id *)alias, uid, pic->lib->env);
@ -195,15 +217,17 @@ pic_lib_library_export(pic_state *pic)
static pic_value static pic_value
pic_lib_library_exports(pic_state *pic) pic_lib_library_exports(pic_state *pic)
{ {
pic_value lib, exports = pic_nil_value(); const char *lib;
pic_value exports = pic_nil_value();
pic_sym *sym; pic_sym *sym;
khiter_t it; khiter_t it;
struct pic_lib *libp;
pic_get_args(pic, "o", &lib); pic_get_args(pic, "z", &lib);
pic_assert_type(pic, lib, lib); libp = get_library(pic, lib);
pic_dict_for_each (sym, pic_lib_ptr(lib)->exports, it) { pic_dict_for_each (sym, libp->exports, it) {
pic_push(pic, pic_obj_value(sym), exports); pic_push(pic, pic_obj_value(sym), exports);
} }
@ -213,13 +237,11 @@ pic_lib_library_exports(pic_state *pic)
static pic_value static pic_value
pic_lib_library_environment(pic_state *pic) pic_lib_library_environment(pic_state *pic)
{ {
pic_value lib; const char *lib;
pic_get_args(pic, "o", &lib); pic_get_args(pic, "z", &lib);
pic_assert_type(pic, lib, lib); return pic_obj_value(get_library(pic, lib)->env);
return pic_obj_value(pic_lib_ptr(lib)->env);
} }
void void

View File

@ -11,7 +11,7 @@ pic_load(pic_state *pic, struct pic_port *port)
size_t ai = pic_gc_arena_preserve(pic); size_t ai = pic_gc_arena_preserve(pic);
while (! pic_eof_p(form = pic_read(pic, port))) { while (! pic_eof_p(form = pic_read(pic, port))) {
pic_eval(pic, form, pic->lib); pic_eval(pic, form, pic_current_library(pic));
pic_gc_arena_restore(pic, ai); pic_gc_arena_restore(pic, ai);
} }

View File

@ -15,19 +15,19 @@ pic_make_env(pic_state *pic, struct pic_env *up)
env = (struct pic_env *)pic_obj_alloc(pic, sizeof(struct pic_env), PIC_TT_ENV); env = (struct pic_env *)pic_obj_alloc(pic, sizeof(struct pic_env), PIC_TT_ENV);
env->up = up; env->up = up;
env->prefix = NULL; env->lib = NULL;
kh_init(env, &env->map); kh_init(env, &env->map);
return env; return env;
} }
struct pic_env * struct pic_env *
pic_make_topenv(pic_state *pic, struct pic_string *prefix) pic_make_topenv(pic_state *pic, struct pic_string *lib)
{ {
struct pic_env *env; struct pic_env *env;
env = (struct pic_env *)pic_obj_alloc(pic, sizeof(struct pic_env), PIC_TT_ENV); env = (struct pic_env *)pic_obj_alloc(pic, sizeof(struct pic_env), PIC_TT_ENV);
env->up = NULL; env->up = NULL;
env->prefix = prefix; env->lib = lib;
kh_init(env, &env->map); kh_init(env, &env->map);
return env; return env;
} }
@ -42,7 +42,7 @@ pic_add_identifier(pic_state *pic, pic_id *id, struct pic_env *env)
name = pic_identifier_name(pic, id); name = pic_identifier_name(pic, id);
if (env->up == NULL && pic_sym_p(pic_obj_value(id))) { /* toplevel & public */ if (env->up == NULL && pic_sym_p(pic_obj_value(id))) { /* toplevel & public */
str = pic_format(pic, "%s/%s", pic_str_cstr(pic, env->prefix), name); str = pic_format(pic, "%s/%s", pic_str_cstr(pic, env->lib), name);
} else { } else {
str = pic_format(pic, ".%s.%d", name, pic->ucnt++); str = pic_format(pic, ".%s.%d", name, pic->ucnt++);
} }

View File

@ -172,7 +172,7 @@ pic_define_standard_port(pic_state *pic, const char *name, xFILE *file, int dir)
{ \ { \
pic_value obj; \ pic_value obj; \
\ \
obj = pic_funcall(pic, pic->PICRIN_BASE, var, 0); \ obj = pic_funcall(pic, "picrin.base", var, 0); \
\ \
return pic_port_ptr(obj); \ return pic_port_ptr(obj); \
} }

View File

@ -856,14 +856,30 @@ pic_vlambda(pic_state *pic, pic_func_t f, int n, va_list ap)
} }
void void
pic_define(pic_state *pic, struct pic_lib *lib, const char *name, pic_value val) pic_defun(pic_state *pic, const char *name, pic_func_t f)
{
pic_define(pic, pic_current_library(pic), name, pic_obj_value(pic_make_proc(pic, f, 0, NULL)));
pic_export(pic, pic_intern_cstr(pic, name));
}
void
pic_defvar(pic_state *pic, const char *name, pic_value init, struct pic_proc *conv)
{
pic_define(pic, pic_current_library(pic), name, pic_obj_value(pic_make_var(pic, init, conv)));
pic_export(pic, pic_intern_cstr(pic, name));
}
void
pic_define(pic_state *pic, const char *lib, const char *name, pic_value val)
{ {
pic_sym *sym, *uid; pic_sym *sym, *uid;
struct pic_env *env;
sym = pic_intern_cstr(pic, name); sym = pic_intern_cstr(pic, name);
if ((uid = pic_find_identifier(pic, (pic_id *)sym, lib->env)) == NULL) { env = pic_library_environment(pic, lib);
uid = pic_add_identifier(pic, (pic_id *)sym, lib->env); if ((uid = pic_find_identifier(pic, (pic_id *)sym, env)) == NULL) {
uid = pic_add_identifier(pic, (pic_id *)sym, env);
} else { } else {
if (pic_weak_has(pic, pic->globals, uid)) { if (pic_weak_has(pic, pic->globals, uid)) {
pic_warnf(pic, "redefining variable: ~s", pic_obj_value(uid)); pic_warnf(pic, "redefining variable: ~s", pic_obj_value(uid));
@ -873,43 +889,33 @@ pic_define(pic_state *pic, struct pic_lib *lib, const char *name, pic_value val)
pic_set(pic, lib, name, val); pic_set(pic, lib, name, val);
} }
void
pic_defun(pic_state *pic, const char *name, pic_func_t f)
{
pic_define(pic, pic->lib, name, pic_obj_value(pic_make_proc(pic, f, 0, NULL)));
pic_export(pic, pic_intern_cstr(pic, name));
}
void
pic_defvar(pic_state *pic, const char *name, pic_value init, struct pic_proc *conv)
{
pic_define(pic, pic->lib, name, pic_obj_value(pic_make_var(pic, init, conv)));
pic_export(pic, pic_intern_cstr(pic, name));
}
pic_value pic_value
pic_ref(pic_state *pic, struct pic_lib *lib, const char *name) pic_ref(pic_state *pic, const char *lib, const char *name)
{ {
pic_sym *sym, *uid; pic_sym *sym, *uid;
struct pic_env *env;
sym = pic_intern_cstr(pic, name); sym = pic_intern_cstr(pic, name);
if ((uid = pic_find_identifier(pic, (pic_id *)sym, lib->env)) == NULL) { env = pic_library_environment(pic, lib);
pic_errorf(pic, "symbol \"%s\" not defined in library ~s", name, lib->name); if ((uid = pic_find_identifier(pic, (pic_id *)sym, env)) == NULL) {
pic_errorf(pic, "symbol \"%s\" not defined in library %s", name, lib);
} }
return vm_gref(pic, uid); return vm_gref(pic, uid);
} }
void void
pic_set(pic_state *pic, struct pic_lib *lib, const char *name, pic_value val) pic_set(pic_state *pic, const char *lib, const char *name, pic_value val)
{ {
pic_sym *sym, *uid; pic_sym *sym, *uid;
struct pic_env *env;
sym = pic_intern_cstr(pic, name); sym = pic_intern_cstr(pic, name);
if ((uid = pic_find_identifier(pic, (pic_id *)sym, lib->env)) == NULL) { env = pic_library_environment(pic, lib);
pic_errorf(pic, "symbol \"%s\" not defined in library ~s", name, lib->name); if ((uid = pic_find_identifier(pic, (pic_id *)sym, env)) == NULL) {
pic_errorf(pic, "symbol \"%s\" not defined in library %s", name, lib);
} }
vm_gset(pic, uid, val); vm_gset(pic, uid, val);
@ -946,7 +952,7 @@ pic_closure_set(pic_state *pic, int n, pic_value v)
} }
pic_value pic_value
pic_funcall(pic_state *pic, struct pic_lib *lib, const char *name, int n, ...) pic_funcall(pic_state *pic, const char *lib, const char *name, int n, ...)
{ {
pic_value proc, r; pic_value proc, r;
va_list ap; va_list ap;

View File

@ -120,7 +120,7 @@ pic_init_core(pic_state *pic)
pic_init_features(pic); pic_init_features(pic);
pic_deflibrary(pic, "(picrin base)"); pic_deflibrary(pic, "picrin.base");
ai = pic_gc_arena_preserve(pic); ai = pic_gc_arena_preserve(pic);
@ -268,7 +268,7 @@ pic_open(pic_allocf allocf, void *userdata)
pic->features = pic_nil_value(); pic->features = pic_nil_value();
/* libraries */ /* libraries */
pic->libs = pic_nil_value(); kh_init(ltable, &pic->ltable);
pic->lib = NULL; pic->lib = NULL;
/* ireps */ /* ireps */
@ -346,9 +346,8 @@ pic_open(pic_allocf allocf, void *userdata)
pic->ptable = pic_cons(pic, pic_obj_value(pic_make_weak(pic)), pic->ptable); pic->ptable = pic_cons(pic, pic_obj_value(pic_make_weak(pic)), pic->ptable);
/* standard libraries */ /* standard libraries */
pic->PICRIN_BASE = pic_make_library(pic, pic_read_cstr(pic, "(picrin base)")); pic_make_library(pic, "picrin.user");
pic->PICRIN_USER = pic_make_library(pic, pic_read_cstr(pic, "(picrin user)")); pic_in_library(pic, "picrin.user");
pic->lib = pic->PICRIN_USER;
pic_gc_arena_restore(pic, ai); pic_gc_arena_restore(pic, ai);
@ -376,7 +375,6 @@ pic_open(pic_allocf allocf, void *userdata)
void void
pic_close(pic_state *pic) pic_close(pic_state *pic)
{ {
khash_t(oblist) *h = &pic->oblist;
pic_allocf allocf = pic->allocf; pic_allocf allocf = pic->allocf;
/* clear out root objects */ /* clear out root objects */
@ -388,7 +386,9 @@ pic_close(pic_state *pic)
pic->globals = NULL; pic->globals = NULL;
pic->macros = NULL; pic->macros = NULL;
pic->features = pic_nil_value(); pic->features = pic_nil_value();
pic->libs = pic_nil_value();
/* free all libraries */
kh_clear(ltable, &pic->ltable);
/* free all heap objects */ /* free all heap objects */
pic_gc(pic); pic_gc(pic);
@ -420,7 +420,8 @@ pic_close(pic_state *pic)
allocf(pic->userdata, pic->xpbase, 0); allocf(pic->userdata, pic->xpbase, 0);
/* free global stacks */ /* free global stacks */
kh_destroy(oblist, h); kh_destroy(oblist, &pic->oblist);
kh_destroy(ltable, &pic->ltable);
/* free GC arena */ /* free GC arena */
allocf(pic->userdata, pic->arena, 0); allocf(pic->userdata, pic->arena, 0);

View File

@ -578,7 +578,7 @@ pic_str_string_map(pic_state *pic)
for (j = 0; j < argc; ++j) { for (j = 0; j < argc; ++j) {
pic_push(pic, pic_char_value(pic_str_ref(pic, pic_str_ptr(argv[j]), i)), vals); pic_push(pic, pic_char_value(pic_str_ref(pic, pic_str_ptr(argv[j]), i)), vals);
} }
val = pic_funcall(pic, pic->PICRIN_BASE, "apply", 2, pic_obj_value(proc), vals); val = pic_funcall(pic, "picrin.base", "apply", 2, pic_obj_value(proc), vals);
pic_assert_type(pic, val, char); pic_assert_type(pic, val, char);
buf[i] = pic_char(val); buf[i] = pic_char(val);
@ -623,7 +623,7 @@ pic_str_string_for_each(pic_state *pic)
for (j = 0; j < argc; ++j) { for (j = 0; j < argc; ++j) {
pic_push(pic, pic_char_value(pic_str_ref(pic, pic_str_ptr(argv[j]), i)), vals); pic_push(pic, pic_char_value(pic_str_ref(pic, pic_str_ptr(argv[j]), i)), vals);
} }
pic_funcall(pic, pic->PICRIN_BASE, "apply", 2, pic_obj_value(proc), vals); pic_funcall(pic, "picrin.base", "apply", 2, pic_obj_value(proc), vals);
} }
return pic_undef_value(); return pic_undef_value();

View File

@ -240,7 +240,7 @@ pic_vec_vector_map(pic_state *pic)
for (j = 0; j < argc; ++j) { for (j = 0; j < argc; ++j) {
pic_push(pic, pic_vec_ptr(argv[j])->data[i], vals); pic_push(pic, pic_vec_ptr(argv[j])->data[i], vals);
} }
vec->data[i] = pic_funcall(pic, pic->PICRIN_BASE, "apply", 2, pic_obj_value(proc), vals); vec->data[i] = pic_funcall(pic, "picrin.base", "apply", 2, pic_obj_value(proc), vals);
} }
return pic_obj_value(vec); return pic_obj_value(vec);
@ -269,7 +269,7 @@ pic_vec_vector_for_each(pic_state *pic)
for (j = 0; j < argc; ++j) { for (j = 0; j < argc; ++j) {
pic_push(pic, pic_vec_ptr(argv[j])->data[i], vals); pic_push(pic, pic_vec_ptr(argv[j])->data[i], vals);
} }
pic_funcall(pic, pic->PICRIN_BASE, "apply", 2, pic_obj_value(proc), vals); pic_funcall(pic, "picrin.base", "apply", 2, pic_obj_value(proc), vals);
} }
return pic_undef_value(); return pic_undef_value();

View File

@ -22,7 +22,6 @@ int
main(int argc, char *argv[], char **envp) main(int argc, char *argv[], char **envp)
{ {
pic_state *pic; pic_state *pic;
struct pic_lib *PICRIN_MAIN;
int status; int status;
pic = pic_open(pic_default_allocf, NULL); pic = pic_open(pic_default_allocf, NULL);
@ -34,9 +33,7 @@ main(int argc, char *argv[], char **envp)
pic_try { pic_try {
pic_init_picrin(pic); pic_init_picrin(pic);
PICRIN_MAIN = pic_find_library(pic, pic_read_cstr(pic, "(picrin main)")); pic_funcall(pic, "picrin.main", "main", 0);
pic_funcall(pic, PICRIN_MAIN, "main", 0);
status = 0; status = 0;
} }