chibi-scheme/config.scm
Alex Shinn 0efd491c24 fixing nested let-syntax hygiene, simplifying error handling
also providing better errors in some cases, and exiting with
a non-zero status on script errors
2009-12-06 17:40:50 +09:00

155 lines
6.4 KiB
Scheme

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; modules
(define *modules* '())
(define *this-module* '())
(define *load-path* (list "./lib" (string-append *module-directory* "/lib")))
(define (make-module exports env meta) (vector exports env meta))
(define (module-exports mod) (vector-ref mod 0))
(define (module-env mod) (vector-ref mod 1))
(define (module-meta-data mod) (vector-ref mod 2))
(define (module-env-set! mod env) (vector-set! mod 1 env))
(define (find-module-file name file)
(let lp ((ls *load-path*))
(and (pair? ls)
(let ((path (string-append (car ls) "/" file)))
(if (file-exists? path) path (lp (cdr ls)))))))
(define (module-name->strings ls res)
(if (null? ls)
res
(let ((str (cond ((symbol? (car ls)) (symbol->string (car ls)))
((number? (car ls)) (number->string (car ls)))
((string? (car ls)) (car ls))
(else (error "invalid module name" (car ls))))))
(module-name->strings (cdr ls) (cons "/" (cons str res))))))
(define (module-name->file name)
(string-concatenate
(reverse (cons ".module" (cdr (module-name->strings name '()))))))
(define (module-name-prefix name)
(string-concatenate (reverse (cdr (cdr (module-name->strings name '()))))))
(define (load-module-definition name)
(let* ((file (module-name->file name))
(path (find-module-file name file)))
(if path (load path *config-env*))))
(define (find-module name)
(cond
((assoc name *modules*) => cdr)
(else
(load-module-definition name)
(cond ((assoc name *modules*) => cdr)
(else #f)))))
(define (eval-module name mod)
(let ((env (make-environment))
(prefix (module-name-prefix name)))
(for-each
(lambda (x)
(case (and (pair? x) (car x))
((import)
(let ((mod2 (load-module (cadr x))))
(%env-copy! env (module-env mod2) (module-exports mod2))))
((include include-shared)
(for-each
(lambda (f)
(let ((f (string-append
prefix f
(if (eq? (car x) 'include) "" *shared-object-extension*))))
(cond
((find-module-file name f) => (lambda (x) (load x env)))
(else (error "couldn't find include" f)))))
(cdr x)))
((body)
(for-each (lambda (expr) (eval expr env)) (cdr x)))))
(module-meta-data mod))
env))
(define (load-module name)
(let ((mod (find-module name)))
(if (and mod (not (module-env mod)))
(module-env-set! mod (eval-module name mod)))
mod))
(define-syntax define-module
(rsc-macro-transformer
(lambda (expr env)
(let ((name (cadr expr))
(body (cddr expr)))
`(let ((tmp *this-module*))
(set! *this-module* '())
,@body
(set! *this-module* (reverse *this-module*))
(let ((exports
(cond ((assq 'export *this-module*) => cdr)
(else '()))))
(set! *modules*
(cons (cons ',name (make-module exports #f *this-module*))
*modules*)))
(set! *this-module* tmp))))))
(define-syntax define-config-primitive
(rsc-macro-transformer
(lambda (expr env)
`(define-syntax ,(cadr expr)
(er-macro-transformer
(lambda (expr rename compare)
`(set! *this-module* (cons ',expr *this-module*))))))))
(define-config-primitive import)
(define-config-primitive export)
(define-config-primitive include)
(define-config-primitive include-shared)
(define-config-primitive body)
(let ((exports
'(define set! let let* letrec lambda if cond case delay
and or begin do quote quasiquote unquote unquote-splicing
define-syntax let-syntax letrec-syntax syntax-rules eqv? eq? equal?
not boolean? number? complex? real? rational? integer? exact? inexact?
= < > <= >= zero? positive? negative? odd? even? max min + * - / abs
quotient remainder modulo gcd lcm numerator denominator floor ceiling
truncate round exp log sin cos tan asin acos atan sqrt
expt make-rectangular make-polar real-part imag-part magnitude angle
exact->inexact inexact->exact number->string string->number pair? cons
car cdr set-car! set-cdr! caar cadr cdar cddr caaar caadr cadar caddr
cdaar cdadr cddar cdddr caaaar caaadr caadar caaddr cadaar cadadr
caddar cadddr cdaaar cdaadr cdadar cdaddr cddaar cddadr cdddar cddddr
null? list? list length append reverse reverse!
list-tail list-ref memq memv
member assq assv assoc symbol? symbol->string string->symbol char?
char=? char<? char>? char<=? char>=? char-ci=? char-ci<? char-ci>?
char-ci<=? char-ci>=? char-alphabetic? char-numeric? char-whitespace?
char-upper-case? char-lower-case? char->integer integer->char
char-upcase char-downcase string? make-string string string-length
string-ref string-set! string=? string-ci=? string<? string>?
string<=? string>=? string-ci<? string-ci>? string-ci<=? string-ci>=?
substring string-append string->list list->string string-copy
string-fill! vector? make-vector vector vector-length vector-ref
vector-set! vector->list list->vector vector-fill! procedure? apply
map for-each force call-with-current-continuation values
call-with-values interaction-environment scheme-report-environment
null-environment call-with-input-file call-with-output-file
input-port? output-port? current-input-port current-output-port
with-input-from-file with-output-to-file open-input-file
open-output-file close-input-port close-output-port read read-char
peek-char eof-object? char-ready? write display newline write-char
load eval
error file-exists? string-concatenate
open-input-string open-output-string get-output-string
sc-macro-transformer rsc-macro-transformer er-macro-transformer
identifier? identifier=? identifier->symbol make-syntactic-closure
register-simple-type make-constructor make-type-predicate
make-getter make-setter
)))
(set! *modules*
(list (cons '(scheme) (make-module exports
(interaction-environment)
(list (cons 'export exports)))))))