-;;; installed-scm-file
+;;; -*- mode: scheme; coding: utf-8; -*-
-;;;; Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2009
+;;;; Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009
;;;; Free Software Foundation, Inc.
;;;;
;;;; This library is free software; you can redistribute it and/or
;;;; modify it under the terms of the GNU Lesser General Public
;;;; License as published by the Free Software Foundation; either
-;;;; version 2.1 of the License, or (at your option) any later version.
+;;;; version 3 of the License, or (at your option) any later version.
;;;;
;;;; This library is distributed in the hope that it will be useful,
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
(define pk peek)
+
(define (warn . stuff)
(with-output-to-port (current-error-port)
(lambda ()
(syntax-rules ()
((_ exp) (make-promise (lambda () exp)))))
+(include-from-path "ice-9/quasisyntax")
+
+;;; @bind is used by the old elisp code as a dynamic scoping mechanism.
+;;; Please let the Guile developers know if you are using this macro.
+;;;
+(define-syntax @bind
+ (lambda (x)
+ (define (bound-member id ids)
+ (cond ((null? ids) #f)
+ ((bound-identifier=? id (car ids)) #t)
+ ((bound-member (car ids) (cdr ids)))))
+
+ (syntax-case x ()
+ ((_ () b0 b1 ...)
+ #'(let () b0 b1 ...))
+ ((_ ((id val) ...) b0 b1 ...)
+ (and-map identifier? #'(id ...))
+ (if (let lp ((ids #'(id ...)))
+ (cond ((null? ids) #f)
+ ((bound-member (car ids) (cdr ids)) #t)
+ (else (lp (cdr ids)))))
+ (syntax-violation '@bind "duplicate bound identifier" x)
+ (with-syntax (((old-v ...) (generate-temporaries #'(id ...)))
+ ((v ...) (generate-temporaries #'(id ...))))
+ #'(let ((old-v id) ...
+ (v val) ...)
+ (dynamic-wind
+ (lambda ()
+ (set! id v) ...)
+ (lambda () b0 b1 ...)
+ (lambda ()
+ (set! id old-v) ...)))))))))
+
+
\f
;;; {Defmacros}
(define (apply-to-args args fn) (apply fn args))
(defmacro false-if-exception (expr)
- `(catch #t (lambda () ,expr)
- (lambda args #f)))
+ `(catch #t
+ (lambda ()
+ ;; avoid saving backtraces inside false-if-exception
+ (with-fluid* the-last-stack (fluid-ref the-last-stack)
+ (lambda () ,expr)))
+ (lambda args #f)))
\f
(set! %load-hook %load-announce)
(define (load name . reader)
+ ;; Returns the .go file corresponding to `name'. Does not search load
+ ;; paths, only the fallback path. If the .go file is missing or out of
+ ;; date, and autocompilation is enabled, will try autocompilation, just
+ ;; as primitive-load-path does internally. primitive-load is
+ ;; unaffected. Returns #f if autocompilation failed or was disabled.
+ (define (autocompiled-file-name name)
+ (catch #t
+ (lambda ()
+ (let* ((cfn ((@ (system base compile) compiled-file-name) name))
+ (scmstat (stat name))
+ (gostat (stat cfn #f)))
+ (if (and gostat (= (stat:mtime gostat) (stat:mtime scmstat)))
+ cfn
+ (begin
+ (if gostat
+ (format (current-error-port)
+ ";;; note: source file ~a\n;;; newer than compiled ~a\n"
+ name cfn))
+ (cond
+ (%load-should-autocompile
+ (%warn-autocompilation-enabled)
+ (format (current-error-port) ";;; compiling ~a\n" name)
+ (let ((cfn ((@ (system base compile) compile-file) name
+ #:env (current-module))))
+ (format (current-error-port) ";;; compiled ~a\n" cfn)
+ cfn))
+ (else #f))))))
+ (lambda (k . args)
+ (format (current-error-port)
+ ";;; WARNING: compilation of ~a failed:\n;;; key ~a, throw_args ~s\n"
+ name k args)
+ #f)))
(with-fluid* current-reader (and (pair? reader) (car reader))
(lambda ()
- (start-stack 'load-stack
- (primitive-load name)))))
+ (let ((cfn (autocompiled-file-name name)))
+ (if cfn
+ (load-compiled cfn)
+ (start-stack 'load-stack
+ (primitive-load name)))))))
\f
;;; See the file `COPYING' for terms applying to this program.
;;;
-(define expt
- (let ((integer-expt integer-expt))
- (lambda (z1 z2)
- (cond ((and (exact? z2) (integer? z2))
- (integer-expt z1 z2))
- ((and (real? z2) (real? z1) (>= z1 0))
- ($expt z1 z2))
- (else
- (exp (* z2 (log z1))))))))
-
(define (sinh z)
(if (real? z) ($sinh z)
(let ((x (real-part z)) (y (imag-part z)))
;; NOTE: This binding is used in libguile/modules.c.
(define module-eval-closure (record-accessor module-type 'eval-closure))
-(define module-transformer (record-accessor module-type 'transformer))
+;; (define module-transformer (record-accessor module-type 'transformer))
(define set-module-transformer! (record-modifier module-type 'transformer))
;; (define module-name (record-accessor module-type 'name)) wait until mods are booted
(define set-module-name! (record-modifier module-type 'name))
;; Make it possible to lookup the module from the environment.
;; This implementation is correct since an eval closure can belong
;; to maximally one module.
- (set-procedure-property! closure 'module module))))
+
+ ;; XXX: The following line introduces a circular reference that
+ ;; precludes garbage collection of modules with the current weak hash
+ ;; table semantics (see
+ ;; http://lists.gnu.org/archive/html/guile-devel/2009-01/msg00102.html and
+ ;; http://thread.gmane.org/gmane.comp.programming.garbage-collection.boehmgc/2465
+ ;; for details). Since it doesn't appear to be used (only in
+ ;; `scm_lookup_closure_module ()', which has 1 caller), we just comment
+ ;; it out.
+
+ ;(set-procedure-property! closure 'module module)
+ )))
\f
;; Import the default set of bindings (from the SCM module) in MODULE.
(module-use! module the-scm-module)))
+(define (make-fresh-user-module)
+ (let ((m (make-module)))
+ (beautify-user-module! m)
+ m))
+
;; NOTE: This binding is used in libguile/modules.c.
;;
(define resolve-module
(let ((accessor (record-accessor module-type 'name)))
(lambda (mod)
(or (accessor mod)
- (begin
- (set-module-name! mod (list (gensym)))
+ (let ((name (list (gensym))))
+ ;; Name MOD and bind it in THE-ROOT-MODULE so that it's visible
+ ;; to `resolve-module'. This is important as `psyntax' stores
+ ;; module names and relies on being able to `resolve-module'
+ ;; them.
+ (set-module-name! mod name)
+ (nested-define! the-root-module `(%app modules ,@name) mod)
(accessor mod))))))
;; (define-special-value '(%app modules new-ws) (lambda () (make-scm-module)))
;;;
(defmacro define-option-interface (option-group)
- (let* ((option-name car)
- (option-value cadr)
- (option-documentation caddr)
+ (let* ((option-name 'car)
+ (option-value 'cadr)
+ (option-documentation 'caddr)
;; Below follow the macros defining the run-time option interfaces.
(,interface (car args)) (,interface))
(else (for-each
(lambda (option)
- (display (option-name option))
+ (display (,option-name option))
(if (< (string-length
- (symbol->string (option-name option)))
+ (symbol->string (,option-name option)))
8)
(display #\tab))
(display #\tab)
- (display (option-value option))
+ (display (,option-value option))
(display #\tab)
- (display (option-documentation option))
+ (display (,option-documentation option))
(newline))
(,interface #t)))))))
(apply make-stack #t save-stack primitive-eval #t 0 narrowing))
((load-stack)
(apply make-stack #t save-stack 0 #t 0 narrowing))
- ((tk-stack)
- (apply make-stack #t save-stack tk-stack-mark #t 0 narrowing))
((#t)
(apply make-stack #t save-stack 0 1 narrowing))
(else
;;; The default repl-reader function. We may override this if we've
;;; the readline library.
(define repl-reader
- (lambda (prompt)
+ (lambda (prompt . reader)
(display (if (string? prompt) prompt (prompt)))
(force-output)
(run-hook before-read-hook)
- ((or (fluid-ref current-reader) read) (current-input-port))))
+ ((or (and (pair? reader) (car reader))
+ (fluid-ref current-reader)
+ read)
+ (current-input-port))))
(define (scm-style-repl)
(display ";;; QUIT executed, repl exitting")
(newline)
(repl-report)))
- args))
-
- (-abort (lambda ()
- (if scm-repl-verbose
- (begin
- (display ";;; ABORT executed.")
- (newline)
- (repl-report)))
- (repl -read -eval -print))))
+ args)))
(let ((status (error-catching-repl -read
-eval
(process-use-modules (list (list ,@(compile-interface-spec spec))))
*unspecified*))
-;; Dirk:FIXME:: This incorrect (according to R5RS) syntax needs to be changed
-;; as soon as guile supports hygienic macros.
(define-syntax define-private
(syntax-rules ()
((_ foo bar)
(defmacro name args . body)
(export-syntax name)))))
+;; And now for the most important macro.
+(define-syntax λ
+ (syntax-rules ()
+ ((_ formals body ...)
+ (lambda formals body ...))))
+
+\f
;; Export a local variable
;; This function is called from "modules.c". If you change it, be
(define %cond-expand-features
;; Adjust the above comment when changing this.
'(guile
+ guile-2
r5rs
srfi-0 ;; cond-expand itself
srfi-4 ;; homogenous numeric vectors
(append (hashq-ref %cond-expand-table mod '())
features)))))
-(define cond-expand
- (procedure->memoizing-macro
- (lambda (exp env)
- (let ((clauses (cdr exp))
- (syntax-error (lambda (cl)
- (error "invalid clause in `cond-expand'" cl))))
- (letrec
- ((test-clause
- (lambda (clause)
- (cond
- ((symbol? clause)
- (or (memq clause %cond-expand-features)
- (let lp ((uses (module-uses (env-module env))))
- (if (pair? uses)
- (or (memq clause
- (hashq-ref %cond-expand-table
- (car uses) '()))
- (lp (cdr uses)))
- #f))))
- ((pair? clause)
- (cond
- ((eq? 'and (car clause))
- (let lp ((l (cdr clause)))
- (cond ((null? l)
- #t)
- ((pair? l)
- (and (test-clause (car l)) (lp (cdr l))))
- (else
- (syntax-error clause)))))
- ((eq? 'or (car clause))
- (let lp ((l (cdr clause)))
- (cond ((null? l)
- #f)
- ((pair? l)
- (or (test-clause (car l)) (lp (cdr l))))
- (else
- (syntax-error clause)))))
- ((eq? 'not (car clause))
- (cond ((not (pair? (cdr clause)))
- (syntax-error clause))
- ((pair? (cddr clause))
- ((syntax-error clause))))
- (not (test-clause (cadr clause))))
- (else
- (syntax-error clause))))
- (else
- (syntax-error clause))))))
- (let lp ((c clauses))
- (cond
- ((null? c)
- (error "Unfulfilled `cond-expand'"))
- ((not (pair? c))
- (syntax-error c))
- ((not (pair? (car c)))
- (syntax-error (car c)))
- ((test-clause (caar c))
- `(begin ,@(cdar c)))
- ((eq? (caar c) 'else)
- (if (pair? (cdr c))
- (syntax-error c))
- `(begin ,@(cdar c)))
- (else
- (lp (cdr c))))))))))
+(define-macro (cond-expand . clauses)
+ (let ((syntax-error (lambda (cl)
+ (error "invalid clause in `cond-expand'" cl))))
+ (letrec
+ ((test-clause
+ (lambda (clause)
+ (cond
+ ((symbol? clause)
+ (or (memq clause %cond-expand-features)
+ (let lp ((uses (module-uses (current-module))))
+ (if (pair? uses)
+ (or (memq clause
+ (hashq-ref %cond-expand-table
+ (car uses) '()))
+ (lp (cdr uses)))
+ #f))))
+ ((pair? clause)
+ (cond
+ ((eq? 'and (car clause))
+ (let lp ((l (cdr clause)))
+ (cond ((null? l)
+ #t)
+ ((pair? l)
+ (and (test-clause (car l)) (lp (cdr l))))
+ (else
+ (syntax-error clause)))))
+ ((eq? 'or (car clause))
+ (let lp ((l (cdr clause)))
+ (cond ((null? l)
+ #f)
+ ((pair? l)
+ (or (test-clause (car l)) (lp (cdr l))))
+ (else
+ (syntax-error clause)))))
+ ((eq? 'not (car clause))
+ (cond ((not (pair? (cdr clause)))
+ (syntax-error clause))
+ ((pair? (cddr clause))
+ ((syntax-error clause))))
+ (not (test-clause (cadr clause))))
+ (else
+ (syntax-error clause))))
+ (else
+ (syntax-error clause))))))
+ (let lp ((c clauses))
+ (cond
+ ((null? c)
+ (error "Unfulfilled `cond-expand'"))
+ ((not (pair? c))
+ (syntax-error c))
+ ((not (pair? (car c)))
+ (syntax-error (car c)))
+ ((test-clause (caar c))
+ `(begin ,@(cdar c)))
+ ((eq? (caar c) 'else)
+ (if (pair? (cdr c))
+ (syntax-error c))
+ `(begin ,@(cdar c)))
+ (else
+ (lp (cdr c))))))))
;; This procedure gets called from the startup code with a list of
;; numbers, which are the numbers of the SRFIs to be loaded on startup.