defsubst
[bpt/guile.git] / emacs / guile.el
index 2676134..25a9b9b 100644 (file)
@@ -2,28 +2,30 @@
 
 ;; Copyright (C) 2001 Keisuke Nishida <kxn30@po.cwru.edu>
 
-;; GNU Emacs is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
-;; any later version.
-
-;; GNU Emacs 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 GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;;;; 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 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
+;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;;;; Lesser General Public License for more details.
+;;;; 
+;;;; You should have received a copy of the GNU Lesser General Public
+;;;; License along with this library; if not, write to the Free
+;;;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+;;;; 02111-1307 USA
 
 ;;; Code:
 
+(require 'cl)
+
 ;;;
 ;;; Low level interface
 ;;;
 
-(defvar gulie-emacs-file
+(defvar guile-emacs-file
   (catch 'return
     (mapc (lambda (dir)
            (let ((file (expand-file-name "guile-emacs.scm" dir)))
          load-path)
     (error "Cannot find guile-emacs.scm")))
 
+(defvar guile-channel-file
+  (catch 'return
+    (mapc (lambda (dir)
+           (let ((file (expand-file-name "channel.scm" dir)))
+             (if (file-exists-p file) (throw 'return file))))
+         load-path)
+    (error "Cannot find channel.scm")))
+
+(defvar guile-libs
+  (nconc (if guile-channel-file (list "-l" guile-channel-file) '())
+        (list "-l" guile-emacs-file)))
+
+;;;###autoload
 (defun guile:make-adapter (command channel)
   (let* ((buff (generate-new-buffer " *guile object channel*"))
-        (proc (start-process "guile-oa" buff command
-                             "-q" "-l" gulie-emacs-file)))
+        (libs (if guile-channel-file (list "-l" guile-channel-file) nil))
+        (proc (apply 'start-process "guile-oa" buff command "-q" guile-libs)))
     (process-kill-without-query proc)
     (accept-process-output proc)
     (guile-process-require proc (format "(%s)\n" channel) "channel> ")
 
 (defun guile-tokenp (x) (and (consp x) (eq (car x) guile-token-tag)))
 
+;;;###autoload
 (defun guile:eval (string adapter)
-  (let ((output (guile-process-require adapter (concat "eval " string "\n")
-                                      "channel> ")))
-    (cond
-     ((string= output "") nil)
-     ((string-match "^\\(\\(value\\)\\|\\(token\\)\\|\\(exception\\)\\) = "
-                   output)
-      (cond
-       ;; value
-       ((match-beginning 2)
-       (car (read-from-string (substring output (match-end 0)))))
-       ;; token
-       ((match-beginning 3)
-       (cons guile-token-tag
-             (car (read-from-string (substring output (match-end 0))))))
-       ;; exception
-       ((match-beginning 4)
-       (signal 'guile-error
-               (car (read-from-string (substring output (match-end 0))))))))
-     (t
-      (error "Unsupported result" output)))))
+  (condition-case error
+      (let ((output (guile-process-require adapter (concat "eval " string "\n")
+                                          "channel> ")))
+       (cond
+        ((string= output "") nil)
+        ((string-match "^\\(\\(value\\)\\|\\(token\\)\\|\\(exception\\)\\) = "
+                       output)
+         (cond
+          ;; value
+          ((match-beginning 2)
+           (car (read-from-string (substring output (match-end 0)))))
+          ;; token
+          ((match-beginning 3)
+           (cons guile-token-tag
+                 (car (read-from-string (substring output (match-end 0))))))
+          ;; exception
+          ((match-beginning 4)
+           (signal 'guile-error
+                   (car (read-from-string (substring output (match-end 0))))))))
+        (t
+         (error "Unsupported result" output))))
+    (quit
+     (signal-process (process-id adapter) 'SIGINT)
+     (signal 'quit nil))))
 
 \f
 ;;;
 (defvar true "#t")
 (defvar false "#f")
 
+(unless (boundp 'keywordp)
+  (defun keywordp (x) (and (symbolp x) (eq (aref (symbol-name x) 0) ?:))))
+
 (defun guile-lisp-adapter ()
   (if (and (processp guile-lisp-adapter)
           (eq (process-status guile-lisp-adapter) 'run))
   (cond
    ((or (eq x true) (eq x false)) x)
    ((null x) "'()")
+   ((keywordp x) (concat "#" (prin1-to-string x)))
    ((stringp x) (prin1-to-string x))
    ((guile-tokenp x) (cadr x))
    ((consp x)
       (cons (guile-lisp-convert (car x)) (guile-lisp-convert (cdr x)))))
    (t x)))
 
-(defun guile-lisp-eval (exp)
-  (guile:eval (format "%s" (guile-lisp-convert exp)) (guile-lisp-adapter)))
+;;;###autoload
+(defun guile-lisp-eval (form)
+  (guile:eval (format "%s" (guile-lisp-convert form)) (guile-lisp-adapter)))
+
+(defun guile-lisp-flat-eval (&rest form)
+  (let ((args (mapcar (lambda (x)
+                       (if (guile-tokenp x) (cadr x) (list 'quote x)))
+                     (cdr form))))
+    (guile-lisp-eval (cons (car form) args))))
 
 ;;;###autoload
-(defmacro guile-import (name)
-  `(guile-process-import ',name))
+(defmacro guile-import (name &optional new-name &rest opts)
+  `(guile-process-import ',name ',new-name ',opts))
 
-(defun guile-process-import (name)
-  (eval (guile-lisp-eval `(guile-emacs-export ',name))))
+(defun guile-process-import (name new-name opts)
+  (let ((real (or new-name name))
+       (docs (if (memq :with-docs opts) true false)))
+    (eval (guile-lisp-eval `(guile-emacs-export ',name ',real ,docs)))))
+
+;;;###autoload
+(defmacro guile-use-module (name)
+  `(guile-lisp-eval '(use-modules ,name)))
 
 ;;;###autoload
-(defmacro guile-use-modules (&rest name-list)
-  `(guile-process-use-modules ',name-list))
+(defmacro guile-import-module (name &rest opts)
+  `(guile-process-import-module ',name ',opts))
 
-(defun guile-process-use-modules (list)
+(defun guile-process-import-module (name opts)
   (unless (boundp 'guile-emacs-export-procedures)
     (guile-import guile-emacs-export-procedures))
-  (guile-lisp-eval `(use-modules ,@list))
-  (mapc (lambda (name) (eval (guile-emacs-export-procedures name))) list))
+  (let ((docs (if (memq :with-docs opts) true false)))
+    (guile-lisp-eval `(use-modules ,name))
+    (eval (guile-emacs-export-procedures name docs))
+    name))
 
 \f
 ;;;