133 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Scheme
		
	
	
	
			
		
		
	
	
			133 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Scheme
		
	
	
	
;;; Ikarus Scheme -- A compiler for R6RS Scheme.
 | 
						|
;;; Copyright (C) 2006,2007,2008  Abdulaziz Ghuloum
 | 
						|
;;; 
 | 
						|
;;; This program is free software: you can redistribute it and/or modify
 | 
						|
;;; it under the terms of the GNU General Public License version 3 as
 | 
						|
;;; published by the Free Software Foundation.
 | 
						|
;;; 
 | 
						|
;;; This program is distributed in the hope that it will be useful, but
 | 
						|
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
						|
;;; General Public License for more details.
 | 
						|
;;; 
 | 
						|
;;; You should have received a copy of the GNU General Public License
 | 
						|
;;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
						|
 | 
						|
 | 
						|
(library (ikarus load)
 | 
						|
  (export load load-r6rs-script fasl-directory)
 | 
						|
  (import 
 | 
						|
    (except (ikarus) fasl-directory load load-r6rs-script)
 | 
						|
    (only (ikarus.compiler) compile-core-expr)
 | 
						|
    (only (psyntax library-manager)
 | 
						|
      serialize-all current-precompiled-library-loader)
 | 
						|
    (only (psyntax expander) compile-r6rs-top-level)
 | 
						|
    (only (ikarus.reader.annotated) read-script-source-file))
 | 
						|
 | 
						|
  (define-struct serialized-library (contents))
 | 
						|
 | 
						|
  (define fasl-extension 
 | 
						|
    (cond
 | 
						|
      [(<= (fixnum-width) 32) ".ikarus-32bit-fasl"]
 | 
						|
      [else                   ".ikarus-64bit-fasl"]))
 | 
						|
 | 
						|
  (define fasl-directory 
 | 
						|
    (make-parameter 
 | 
						|
      (cond
 | 
						|
        [(getenv "IKARUS_FASL_DIRECTORY")]
 | 
						|
        [(getenv "HOME") =>
 | 
						|
         (lambda (s)
 | 
						|
           (string-append s "/.ikarus/precompiled"))]
 | 
						|
        [else ""])
 | 
						|
      (lambda (s)
 | 
						|
        (if (string? s)
 | 
						|
            s
 | 
						|
            (die 'fasl-directory "not a string" s)))))
 | 
						|
      
 | 
						|
  (define (fasl-path filename)
 | 
						|
    (let ([d (fasl-directory)])
 | 
						|
      (and (not (string=? d ""))
 | 
						|
        (string-append d (file-real-path filename) fasl-extension))))
 | 
						|
 | 
						|
  (define (load-serialized-library filename sk)
 | 
						|
    (let ([ikfasl (fasl-path filename)])
 | 
						|
      (cond
 | 
						|
        [(or (not ikfasl) (not (file-exists? ikfasl))) #f]
 | 
						|
        [(< (file-mtime ikfasl) (file-mtime filename))
 | 
						|
         (fprintf (current-error-port)
 | 
						|
            "WARNING: not using fasl file ~s because it is older \
 | 
						|
             than the source file ~s\n" 
 | 
						|
           ikfasl
 | 
						|
           filename)
 | 
						|
         #f]
 | 
						|
        [else
 | 
						|
         (let ([x 
 | 
						|
                (let ([p (open-file-input-port ikfasl)])
 | 
						|
                  (let ([x (fasl-read p)])
 | 
						|
                    (close-input-port p)
 | 
						|
                    x))])
 | 
						|
           (if (serialized-library? x)
 | 
						|
               (apply sk (serialized-library-contents x))
 | 
						|
               (begin
 | 
						|
                 (fprintf (current-error-port)
 | 
						|
                    "WARNING: not using fasl file ~s because it was \
 | 
						|
                     compiled with a different instance of ikarus.\n" 
 | 
						|
                    ikfasl)
 | 
						|
                 #f)))])))
 | 
						|
 | 
						|
  (define (do-serialize-library filename contents)
 | 
						|
    (let ([ikfasl (fasl-path filename)])
 | 
						|
      (cond
 | 
						|
        [(not ikfasl) (void)]
 | 
						|
        [else
 | 
						|
         (fprintf (current-error-port) "Serializing ~s ...\n" ikfasl)
 | 
						|
         (let-values ([(dir name) (split-file-name ikfasl)])
 | 
						|
           (make-directory* dir))
 | 
						|
         (let ([p (open-file-output-port ikfasl (file-options no-fail))])
 | 
						|
           (fasl-write (make-serialized-library contents) p)
 | 
						|
           (close-output-port p))])))
 | 
						|
 | 
						|
  (define load-handler
 | 
						|
    (lambda (x)
 | 
						|
      (eval x (interaction-environment))))
 | 
						|
 | 
						|
  (define read-and-eval
 | 
						|
    (lambda (p eval-proc)
 | 
						|
      (let ([x (read p)])
 | 
						|
        (unless (eof-object? x)
 | 
						|
          (eval-proc x)
 | 
						|
          (read-and-eval p eval-proc)))))
 | 
						|
  (define load
 | 
						|
    (case-lambda
 | 
						|
      [(x) (load x load-handler)]
 | 
						|
      [(x eval-proc)
 | 
						|
       (unless (string? x)
 | 
						|
         (die 'load "not a string" x))
 | 
						|
       (unless (procedure? eval-proc)
 | 
						|
         (die 'load "not a procedure" eval-proc))
 | 
						|
       (let ([ls (read-script-source-file x)])
 | 
						|
         (let f ()
 | 
						|
           (unless (null? ls)
 | 
						|
             (let ([a (car ls)])
 | 
						|
               (set! ls (cdr ls))
 | 
						|
               (eval-proc a))
 | 
						|
             (f))))]))
 | 
						|
 | 
						|
  (define load-r6rs-script
 | 
						|
    (lambda (filename serialize? run?)
 | 
						|
      (unless (string? filename) 
 | 
						|
        (die 'load-r6rs-script "file name is not a string" filename))
 | 
						|
      (let ([prog (read-script-source-file filename)])
 | 
						|
        (let([thunk (compile-r6rs-top-level prog)])
 | 
						|
          (when serialize?
 | 
						|
            (serialize-all
 | 
						|
              (lambda (file-name contents)
 | 
						|
                (do-serialize-library file-name contents))
 | 
						|
              (lambda (core-expr) 
 | 
						|
                (compile-core-expr core-expr))))
 | 
						|
          (when run? (thunk))))))
 | 
						|
 | 
						|
  (current-precompiled-library-loader load-serialized-library)
 | 
						|
  
 | 
						|
  )
 |