~ chicken-core (chicken-5) 9a42090d173ab29fa57de23af835a54c1aa92f6c
commit 9a42090d173ab29fa57de23af835a54c1aa92f6c Author: Evan Hanson <evhan@foldling.org> AuthorDate: Sun Oct 11 17:56:24 2015 +1300 Commit: Peter Bex <peter@more-magic.net> CommitDate: Mon Nov 2 21:29:01 2015 +0100 Some refactoring to simplify import handling Introduces a mapping from modules to unit names in eval.scm, for loading code when a core module is required (with e.g. `use`). Cleans up library list handling in eval.scm and modules.scm. Standardizes syntax stripping behaviour across all of the four complex import types ("prefix", "rename" et al.). diff --git a/chicken-install.scm b/chicken-install.scm index eb1b2fb3..0798dcc0 100644 --- a/chicken-install.scm +++ b/chicken-install.scm @@ -222,8 +222,8 @@ (cond ((or (eq? x 'chicken) (equal? x "chicken") (let ((xs (->string x))) - (or (member xs ##sys#core-library-modules) - (member xs ##sys#core-syntax-modules)))) + (or (member xs ##sys#core-library-units) + (member xs ##sys#core-syntax-units)))) (chicken-version) ) ((extension-information x) => (lambda (info) diff --git a/chicken-syntax.scm b/chicken-syntax.scm index 6464808c..03f67fca 100644 --- a/chicken-syntax.scm +++ b/chicken-syntax.scm @@ -1155,10 +1155,7 @@ (and (list? argname) (= 2 (length argname)) (symbol? (car argname)) - (let ((param (cadr argname))) - (or (symbol? param) - (and (list? param) - (every symbol? param)))))) + (chicken.internal#valid-library-specifier? (cadr argname)))) (##sys#syntax-error-hook "invalid functor argument" name arg)) (cons argname exps))) args) diff --git a/eval.scm b/eval.scm index 1db97c09..5ff73fa1 100644 --- a/eval.scm +++ b/eval.scm @@ -78,15 +78,22 @@ (define-foreign-variable uses-soname? bool "C_USES_SONAME") (define-foreign-variable install-lib-name c-string "C_INSTALL_LIB_NAME") -;; Core units under the "chicken" module namespace. -(define ##sys#core-chicken-modules - '(eval extras lolevel utils files tcp irregex posix data-structures ports)) - -;; Core units outside the "chicken" module namespace. -(define ##sys#core-library-modules - `(srfi-4 . ,##sys#core-chicken-modules)) - -(define ##sys#core-syntax-modules +(define-constant core-chicken-modules + '((chicken.data-structures . data-structures) + (chicken.eval . eval) + (chicken.extras . extras) + (chicken.files . files) + (chicken.irregex . irregex) + (chicken.lolevel . lolevel) + (chicken.ports . ports) + (chicken.posix . posix) + (chicken.tcp . tcp) + (chicken.utils . utils))) + +(define ##sys#core-library-units + `(srfi-4 . ,(map cdr core-chicken-modules))) + +(define ##sys#core-syntax-units '(chicken-syntax chicken-ffi-syntax)) (define ##sys#explicit-library-modules '()) @@ -1231,8 +1238,8 @@ (else (##sys#check-symbol id loc)) ) (let ([p (##sys#canonicalize-extension-path id loc)]) (cond ((member p ##sys#loaded-extensions)) - ((or (memq id ##sys#core-library-modules) - (memq id ##sys#core-syntax-modules)) + ((or (memq id ##sys#core-library-units) + (memq id ##sys#core-syntax-units)) (or (##sys#load-library-0 id #f) (and err? (##sys#error loc "cannot load core library" id)))) @@ -1297,7 +1304,7 @@ (define ##sys#do-the-right-thing (let ((vector->list vector->list)) - (lambda (id comp? imp? #!optional (add-req void)) + (lambda (spec comp? imp? #!optional (add-req void)) (define (impform x id builtin?) `(##core#begin ,x @@ -1310,7 +1317,7 @@ (values (impform '(##core#undefined) impid #t) #t id)) ((and (not comp?) (##sys#feature? id)) (values (impform '(##core#undefined) impid #f) #t id)) - ((memq id ##sys#core-library-modules) + ((memq id ##sys#core-library-units) (values (impform (if comp? @@ -1318,7 +1325,7 @@ `(##sys#load-library ',id #f) ) impid #f) #t id) ) - ((memq id ##sys#core-syntax-modules) + ((memq id ##sys#core-syntax-units) (values (impform (if comp? @@ -1369,36 +1376,21 @@ `(##sys#require ',id) impid #f) #f id))))))) - (cond ((and (pair? id) (symbol? (car id))) - (case (car id) - ((srfi) - (let* ((f #f) - (exp - `(##core#begin - ,@(map (lambda (n) - (let ((rid (srfi-id n))) - (let-values (((exp f2 _) (doit rid))) - (set! f (or f f2)) - exp))) - (cdr id))))) - (values exp f id))) ;XXX `id' not fully correct - ((rename except only prefix) - (let follow ((id2 id)) - (if (and (pair? id2) (pair? (cdr id2))) - (if (and (eq? 'srfi (car id2)) (null? (cddr id2))) ; only allow one number - (doit (srfi-id (cadr id2)) id) - (follow (cadr id2))) - (doit id2 id)))) - ((chicken) - (if (memq (cadr id) ##sys#core-chicken-modules) - (doit (cadr id) (library-id id)) - (doit (library-id id)))) - (else - (doit (library-id id))))) - ((symbol? id) - (doit id)) - (else - (##sys#error "invalid extension specifier" id)))))) + (let loop ((id spec)) + (cond ((assq id core-chicken-modules) => + (lambda (lib) (doit (cdr lib) spec))) + ((symbol? id) + (doit (library-id id) spec)) + ((pair? id) + (case (car id) + ((rename except only prefix) + (if (pair? (cdr id)) + (loop (cadr id)) + (loop (library-id id)))) + (else + (loop (library-id id))))) + (else + (##sys#error "invalid extension specifier" id))))))) ;;; Convert string into valid C-identifier: diff --git a/expand.scm b/expand.scm index 257214d9..e8702ef9 100644 --- a/expand.scm +++ b/expand.scm @@ -106,7 +106,6 @@ alias) ) ) (define (strip-syntax exp) - ;; if se is given, retain bound vars (let ((seen '())) (let walk ((x exp)) (cond ((assq x seen) => cdr) diff --git a/internal.scm b/internal.scm index 76f75af7..eda1fc48 100644 --- a/internal.scm +++ b/internal.scm @@ -30,28 +30,41 @@ (fixnum)) (module chicken.internal - (srfi-id library-id) + (library-id valid-library-specifier?) (import scheme chicken) -(define (srfi-id n) - (if (fixnum? n) - (##sys#intern-symbol - (##sys#string-append "srfi-" (##sys#number->string n))) - (##sys#error "invalid SRFI number" n))) +(include "mini-srfi-1.scm") + +(define (valid-library-specifier? x) + (or (symbol? x) + (and (list? x) + (not (null? x)) + (every (lambda (x) (or (symbol? x) (fixnum? x))) x)))) (define (library-id lib) - (define (library-part->string id) - (cond ((symbol? id) (##sys#symbol->string id)) - ((number? id) (##sys#number->string id)) - (else (##sys#error "invalid library specifier" lib)))) + (define (fail) + (##sys#error "invalid library specifier" lib)) + (define (srfi? x) + (and (pair? (cdr x)) + (null? (cddr x)) + (eq? 'srfi (car x)) + (fixnum? (cadr x)))) + (define (library-part->string x) + (cond ((symbol? x) (##sys#symbol->string x)) + ((fixnum? x) (##sys#number->string x)) + (else (fail)))) (cond ((symbol? lib) lib) - ((list? lib) - (do ((lib (cdr lib) (cdr lib)) + ((not (pair? lib)) (fail)) + ((srfi? lib) + (##sys#intern-symbol + (##sys#string-append "srfi-" (##sys#number->string (cadr lib))))) + (else + (do ((lst (cdr lib) (cdr lst)) (str (library-part->string (car lib)) - (string-append str "." (library-part->string (car lib))))) - ((null? lib) (##sys#intern-symbol str)))) - (else (##sys#error "invalid library specifier" lib)))) + (string-append str "." (library-part->string (car lst))))) + ((null? lst) + (##sys#intern-symbol str)))))) ) ; chicken.internal diff --git a/modules.scm b/modules.scm index ae4452ae..d7f1cc55 100644 --- a/modules.scm +++ b/modules.scm @@ -29,7 +29,7 @@ (uses eval expand internal) (disable-interrupts) (fixnum) - (hide lookup merge-se module-indirect-exports) + (hide merge-se module-indirect-exports) (not inline ##sys#alias-global-hook)) (include "common-declarations.scm") @@ -56,13 +56,6 @@ ;;; Support definitions -;; duplicates code in the hope of being inlined -(define (lookup id se) - (cond ((##core#inline "C_u_i_assq" id se) => cdr) - ((getp id '##core#macro-alias)) - (else #f))) - - ;;; low-level module support (define ##sys#current-module (make-parameter #f)) @@ -555,8 +548,8 @@ ;;; Import-expansion -(define (##sys#find-module/import-library mname loc) - (let* ((mname (##sys#resolve-module-name mname loc)) +(define (##sys#find-module/import-library lib loc) + (let* ((mname (##sys#resolve-module-name lib loc)) (mod (##sys#find-module mname #f loc))) (unless mod (let* ((il (##sys#find-extension @@ -581,10 +574,7 @@ (let ((%only (r 'only)) (%rename (r 'rename)) (%except (r 'except)) - (%prefix (r 'prefix)) - (%srfi (r 'srfi))) - (define (resolve sym) - (or (lookup sym '()) sym)) ;XXX really empty se? + (%prefix (r 'prefix))) (define (warn msg mod id) (##sys#warn (string-append msg " in module `" (symbol->string mod) "'") id)) (define (tostr x) @@ -594,66 +584,66 @@ ((number? x) (number->string x)) (else (##sys#syntax-error-hook loc "invalid prefix" )))) (define (import-name spec) - (let* ((mod (##sys#find-module/import-library (chicken.expand#strip-syntax spec) 'import)) + (let* ((mod (##sys#find-module/import-library spec 'import)) (vexp (module-vexports mod)) (sexp (module-sexports mod)) (iexp (module-iexports mod)) (name (module-name mod))) (values name name vexp sexp iexp))) (define (import-spec spec) - (cond ((symbol? spec) (import-name spec)) - ((null? (cdr spec)) (import-name (car spec))) ; single library component - ((and (c %srfi (car spec)) (fixnum? (cadr spec)) (null? (cddr spec))) ; only one number - (import-name (chicken.internal#srfi-id (cadr spec)))) - (else - (let ((head (car spec)) - (imports (cddr spec))) + (cond ((symbol? spec) + (import-name (chicken.expand#strip-syntax spec))) + ((not (pair? spec)) + (##sys#syntax-error-hook loc "invalid import specification" spec)) + (else + (let ((head (car spec))) (cond ((c %only head) (##sys#check-syntax loc spec '(_ _ . #(symbol 0))) - (let-values (((name form impv imps impi) (import-spec (cadr spec)))) - (let ((ids (map resolve imports))) - (let loop ((ids ids) (v '()) (s '()) (missing '())) - (cond ((null? ids) - (for-each - (lambda (id) - (warn "imported identifier doesn't exist" name id)) - missing) - (values name `(,head ,form ,@imports) v s impi)) - ((assq (car ids) impv) => - (lambda (a) - (loop (cdr ids) (cons a v) s missing))) - ((assq (car ids) imps) => - (lambda (a) - (loop (cdr ids) v (cons a s) missing))) - (else - (loop (cdr ids) v s (cons (car ids) missing)))))))) + (let-values (((name form impv imps impi) (import-spec (cadr spec))) + ((imports) (chicken.expand#strip-syntax (cddr spec)))) + (let loop ((ids imports) (v '()) (s '()) (missing '())) + (cond ((null? ids) + (for-each + (lambda (id) + (warn "imported identifier doesn't exist" name id)) + missing) + (values name `(,head ,form ,@imports) v s impi)) + ((assq (car ids) impv) => + (lambda (a) + (loop (cdr ids) (cons a v) s missing))) + ((assq (car ids) imps) => + (lambda (a) + (loop (cdr ids) v (cons a s) missing))) + (else + (loop (cdr ids) v s (cons (car ids) missing))))))) ((c %except head) (##sys#check-syntax loc spec '(_ _ . #(symbol 0))) - (let-values (((name form impv imps impi) (import-spec (cadr spec)))) - (let ((ids (map resolve imports))) - (let loop ((impv impv) (v '()) (ids imports)) - (cond ((null? impv) - (let loop ((imps imps) (s '()) (ids ids)) - (cond ((null? imps) - (for-each - (lambda (id) - (warn "excluded identifier doesn't exist" name id)) - ids) - (values name `(,head ,form ,@imports) v s impi)) - ((memq (caar imps) ids) => - (lambda (id) - (loop (cdr imps) s (delete (car id) ids eq?)))) - (else - (loop (cdr imps) (cons (car imps) s) ids))))) - ((memq (caar impv) ids) => - (lambda (id) - (loop (cdr impv) v (delete (car id) ids eq?)))) - (else - (loop (cdr impv) (cons (car impv) v) ids))))))) + (let-values (((name form impv imps impi) (import-spec (cadr spec))) + ((imports) (chicken.expand#strip-syntax (cddr spec)))) + (let loop ((impv impv) (v '()) (ids imports)) + (cond ((null? impv) + (let loop ((imps imps) (s '()) (ids ids)) + (cond ((null? imps) + (for-each + (lambda (id) + (warn "excluded identifier doesn't exist" name id)) + ids) + (values name `(,head ,form ,@imports) v s impi)) + ((memq (caar imps) ids) => + (lambda (id) + (loop (cdr imps) s (delete (car id) ids eq?)))) + (else + (loop (cdr imps) (cons (car imps) s) ids))))) + ((memq (caar impv) ids) => + (lambda (id) + (loop (cdr impv) v (delete (car id) ids eq?)))) + (else + (loop (cdr impv) (cons (car impv) v) ids)))))) ((c %rename head) (##sys#check-syntax loc spec '(_ _ . #((symbol symbol) 0))) - (let-values (((name form impv imps impi) (import-spec (cadr spec)))) - (let loop ((impv impv) (v '()) (ids imports)) + (let-values (((name form impv imps impi) (import-spec (cadr spec))) + ((renames) (chicken.expand#strip-syntax (cddr spec)))) + (let loop ((impv impv) (v '()) (ids renames)) (cond ((null? impv) (let loop ((imps imps) (s '()) (ids ids)) (cond ((null? imps) @@ -661,7 +651,7 @@ (lambda (id) (warn "renamed identifier doesn't exist" name id)) (map car ids)) - (values name `(,head ,form ,@imports) v s impi)) + (values name `(,head ,form ,@renames) v s impi)) ((assq (caar imps) ids) => (lambda (a) (loop (cdr imps) @@ -678,16 +668,16 @@ (loop (cdr impv) (cons (car impv) v) ids)))))) ((c %prefix head) (##sys#check-syntax loc spec '(_ _ _)) - (let-values (((name form impv imps impi) (import-spec (cadr spec)))) - (let ((pref (caddr spec))) - (define (ren imp) - (cons - (##sys#string->symbol - (##sys#string-append (tostr pref) (##sys#symbol->string (car imp)))) - (cdr imp) ) ) - (values name `(,head ,form ,pref) (map ren impv) (map ren imps) impi)))) + (let-values (((name form impv imps impi) (import-spec (cadr spec))) + ((prefix) (chicken.expand#strip-syntax (caddr spec)))) + (define (rename imp) + (cons + (##sys#string->symbol + (##sys#string-append (tostr prefix) (##sys#symbol->string (car imp)))) + (cdr imp))) + (values name `(,head ,form ,prefix) (map rename impv) (map rename imps) impi))) (else - (import-name (chicken.internal#library-id spec)))))))) + (import-name (chicken.expand#strip-syntax spec)))))))) (##sys#check-syntax loc x '(_ . #(_ 1))) (let ((cm (##sys#current-module))) (for-each diff --git a/tests/scrutiny.expected b/tests/scrutiny.expected index 350d948a..70f732a0 100644 --- a/tests/scrutiny.expected +++ b/tests/scrutiny.expected @@ -42,17 +42,17 @@ Warning: at toplevel: (scrutiny-tests.scm:29) in procedure call to `+', expected argument #2 of type `number', but was given an argument of type `symbol' Warning: at toplevel: - assignment of value of type `fixnum' to toplevel variable `car' does not match declared type `(forall (a200) (procedure car ((pair a200 *)) a200))' + assignment of value of type `fixnum' to toplevel variable `car' does not match declared type `(forall (a196) (procedure car ((pair a196 *)) a196))' Warning: at toplevel: - expected in `let' binding of `g20' a single result, but were given 2 results + expected in `let' binding of `g18' a single result, but were given 2 results Warning: at toplevel: - in procedure call to `g20', expected a value of type `(procedure () *)', but was given a value of type `fixnum' + in procedure call to `g18', expected a value of type `(procedure () *)', but was given a value of type `fixnum' Note: in toplevel procedure `foo': expected value of type boolean in conditional but were given a value of type - `(procedure bar42 () *)' which is always true: + `(procedure bar40 () *)' which is always true: (if bar 3 (##core#undefined))Trap