ikarus/lib/ikarus/include.ss

78 lines
3.0 KiB
Scheme

;;; Ikarus Scheme -- A compiler for R6RS Scheme.
;;; Copyright (C) 2009 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 include)
(export include include/lexical-context)
(import (ikarus))
(define-syntax include/lexical-context/form
(lambda (x)
(syntax-case x ()
[(_ filename id form who)
(let* ([filename
(let ([x (syntax->datum #'filename)])
(if (and (string? x) (not (string=? x "")))
(if (char=? (string-ref x 0) #\/)
x
(let f ([ls (library-path)])
(if (null? ls)
(syntax-violation #f
"file does not exist in library path"
#'form #'filename)
(let ([x (string-append (car ls) "/" x)])
(if (file-exists? x)
(file-real-path x)
(f (cdr ls)))))))
(syntax-violation #f
"file name must be a nonempty string"
#'form #'filename)))]
[content
(with-exception-handler
(lambda (x)
(raise-continuable
(condition
(make-who-condition (syntax->datum #'who))
x)))
(lambda ()
(with-input-from-file filename
(lambda ()
(let loop ()
(let ([x (read-annotated)])
(if (eof-object? x)
'()
(cons (datum->syntax #'id x)
(loop)))))))))])
#`(stale-when
(or (not (file-exists? #,filename))
(> (file-mtime #,filename) #,(file-mtime filename)))
#,@content))])))
(define-syntax include/lexical-context
(lambda (x)
(syntax-case x ()
[(kwd filename id)
(if (identifier? #'id)
#`(include/lexical-context/form filename id #,x kwd)
(syntax-violation #f "not an identifier" x #'id))])))
(define-syntax include
(lambda (x)
(syntax-case x ()
[(kwd filename)
#`(include/lexical-context/form filename kwd #,x kwd)]))))