(define-library (scheme-deps) (export main) (import (except (scheme base) features) (scheme file) (scheme read) (scheme write) (only (srfi 1) append-map append-reverse fold any every remove) (srfi 193)) (cond-expand (chibi (import (chibi show) (chibi show pretty))) (gauche (import (only (gauche base) pprint))) (else)) (cond-expand (chibi (begin (define (pretty-print obj) (show #t (pretty obj))))) (gauche (begin (define (pretty-print obj) (pprint obj)))) (else (begin (define (pretty-print obj) (write obj) (newline))))) (begin (define edisp (lambda objs (for-each (lambda (obj) (display obj (current-error-port))) objs) (newline (current-error-port)))) (define (read-all) (let loop ((xs '())) (let ((x (read))) (if (eof-object? x) (reverse xs) (loop (cons x xs)))))) ;; (define (natural? obj) (and (integer? obj) (exact? obj) (not (negative? obj)))) ;; (define first car) (define second cadr) (define rest cdr) (define (liststring part) (cond ((symbol? part) (symbol->string part)) ((number? part) (number->string part)) (else (error "Bad library name part" part)))) (define (library-name-partstring a) (library-name-part->string b))) (define (library-namestring library-name) separator) extension)) (define (library-name->filename library-name) (format-library-name library-name "/" ".sld")) ;; (define (no-consumer value) (error "No consumer")) (define (producer consumer) (lambda (value) ((consumer) value))) (define consume-name (make-parameter no-consumer)) (define consume-import (make-parameter no-consumer)) (define consume-include (make-parameter no-consumer)) (define produce-name (producer consume-name)) (define produce-import (producer consume-import)) (define produce-include (producer consume-include)) (define features (make-parameter '())) (define libraries (make-parameter '())) ;; (define (requirement-satisfied? exp) (cond ((symbol? exp) (not (not (member exp (features))))) ((head? exp 'library) (if (= 2 (length exp)) (not (not (member (second exp) (libraries)))) (error "Bad (library ...) requirement"))) ((head? exp 'not) (if (= 2 (length exp)) (not (requirement-satisfied? (second exp))) (error "Bad (not ...) requirement" exp))) ((head? exp 'and) (every requirement-satisfied? exp)) ((head? exp 'or) (any requirement-satisfied? exp)) (else (error "Bad cond-expand requirement" exp)))) (define (walk-cond-expand form) (let loop ((clauses (dehead form 'cond-expand))) (if (null? clauses) (error "No cond-expand clause matches these features" (features)) (let ((clause (first clauses))) (cond ((not (nonnull-list? clause)) (error "Bad cond-expand clause" clause)) ((or (equal? 'else (first clause)) (requirement-satisfied? (first clause))) (walk-library-declarations (rest clause))) (else (loop (rest clauses)))))))) (define (walk-include form) (if (and (head? form 'include) (= 2 (length form))) (produce-include (second form)) (error "Bad include" form))) (define (walk-import-set import-set) (cond ((or (head? import-set 'except) (head? import-set 'only) (head? import-set 'prefix) (head? import-set 'rename)) (walk-import-set (second import-set))) ((list? import-set) (produce-import import-set)) (else (error "Bad import set" import-set)))) (define (walk-import form) (for-each walk-import-set (dehead form 'import))) (define ignored-declarations '(begin export)) (define (walk-library-declaration decl) (cond ((head? decl 'cond-expand) (walk-cond-expand decl)) ((head? decl 'include) (walk-include decl)) ((head? decl 'import) (walk-import decl)) ((and (nonnull-list? decl) (member (first decl) ignored-declarations)) (values)) (else (edisp "warning: ignoring unknown library declaration " decl) (values)))) (define (walk-library-declarations decls) (for-each walk-library-declaration decls)) (define (walk-define-library exp) (unless (and (head? exp 'define-library) (>= (length exp) 3)) (error "Bad define-library" exp)) (let ((name (second exp)) (decls (rest (rest exp)))) (unless (valid-library-name? name) (error "Bad library name" name)) (produce-name name) (walk-library-declarations decls))) (define (walk-sld-file sld-file) (for-each walk-define-library (with-input-from-file sld-file read-all))) (define-record-type (make-library name source-file imports includes) library? (name library-name) (source-file library-source-file) (imports library-imports) (includes library-includes)) (define (standard-or-implementation-library? library-name) (member (first library-name) '(chicken rnrs scheme srfi))) (define (library->chicken-extension library) (define (library-name->chicken library-name) (string->symbol (format-library-name library-name "." ""))) `(extension ,(library-name->chicken (library-name library)) (source ,(library-source-file library)) ,@(if-nonnull 'source-dependencies (library-includes library)) ,@(if-nonnull 'component-dependencies (map library-name->chicken (remove standard-or-implementation-library? (library-imports library)))) (csc-options "-R" "r7rs" "-X" "r7rs"))) (define-syntax add-to (syntax-rules () ((add-to lis <) (lambda (elem) (set! lis (sorted-insert-unique < elem lis)))))) (define (process-sld-file sld-file) (let ((name '()) (imports '()) (includes '())) (parameterize ((consume-name (lambda (x) (set! name x))) (consume-import (add-to imports library-namechicken-extension libs))))) (define main (lambda ignored (parameterize ((features '(chicken)) (libraries '((srfi 13)))) (let ((libs (map process-sld-file (command-args)))) (print-chicken libs)))))))