channel.scm 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. ;;; Guile object channel
  2. ;; Copyright (C) 2001, 2006 Free Software Foundation, Inc.
  3. ;; This library is free software; you can redistribute it and/or
  4. ;; modify it under the terms of the GNU Lesser General Public
  5. ;; License as published by the Free Software Foundation; either
  6. ;; version 2.1 of the License, or (at your option) any later version.
  7. ;;
  8. ;; This library is distributed in the hope that it will be useful,
  9. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. ;; Lesser General Public License for more details.
  12. ;;
  13. ;; You should have received a copy of the GNU Lesser General Public
  14. ;; License along with this library; if not, write to the Free Software
  15. ;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  16. ;;; Commentary:
  17. ;; Now you can use Guile's modules in Emacs Lisp like this:
  18. ;;
  19. ;; (guile-import current-module)
  20. ;; (guile-import module-ref)
  21. ;;
  22. ;; (setq assq (module-ref (current-module) 'assq))
  23. ;; => ("<guile>" %%1%% . "#<primitive-procedure assq>")
  24. ;;
  25. ;; (guile-use-modules (ice-9 documentation))
  26. ;;
  27. ;; (object-documentation assq)
  28. ;; =>
  29. ;; " - primitive: assq key alist
  30. ;; - primitive: assv key alist
  31. ;; - primitive: assoc key alist
  32. ;; Fetches the entry in ALIST that is associated with KEY. To decide
  33. ;; whether the argument KEY matches a particular entry in ALIST,
  34. ;; `assq' compares keys with `eq?', `assv' uses `eqv?' and `assoc'
  35. ;; uses `equal?'. If KEY cannot be found in ALIST (according to
  36. ;; whichever equality predicate is in use), then `#f' is returned.
  37. ;; These functions return the entire alist entry found (i.e. both the
  38. ;; key and the value)."
  39. ;;
  40. ;; Probably we can use GTK in Emacs Lisp. Can anybody try it?
  41. ;;
  42. ;; I have also implemented Guile Scheme mode and Scheme Interaction mode.
  43. ;; Just put the following lines in your ~/.emacs:
  44. ;;
  45. ;; (require 'guile-scheme)
  46. ;; (setq initial-major-mode 'scheme-interaction-mode)
  47. ;;
  48. ;; Currently, the following commands are available:
  49. ;;
  50. ;; M-TAB guile-scheme-complete-symbol
  51. ;; M-C-x guile-scheme-eval-define
  52. ;; C-x C-e guile-scheme-eval-last-sexp
  53. ;; C-c C-b guile-scheme-eval-buffer
  54. ;; C-c C-r guile-scheme-eval-region
  55. ;; C-c : guile-scheme-eval-expression
  56. ;;
  57. ;; I'll write more commands soon, or if you want to hack, please take
  58. ;; a look at the following files:
  59. ;;
  60. ;; guile-core/ice-9/channel.scm ;; object channel
  61. ;; guile-core/emacs/guile.el ;; object adapter
  62. ;; guile-core/emacs/guile-emacs.scm ;; Guile <-> Emacs channels
  63. ;; guile-core/emacs/guile-scheme.el ;; Guile Scheme mode
  64. ;;
  65. ;; As always, there are more than one bugs ;)
  66. ;;; Code:
  67. (define-module (ice-9 channel)
  68. :export (make-object-channel
  69. channel-open
  70. channel-print-value
  71. channel-print-token))
  72. ;;;
  73. ;;; Channel type
  74. ;;;
  75. (define channel-type
  76. (make-record-type 'channel '(stdin stdout printer token-module)))
  77. (define make-channel (record-constructor channel-type))
  78. (define (make-object-channel printer)
  79. (make-channel (current-input-port)
  80. (current-output-port)
  81. printer
  82. (make-module)))
  83. (define channel-stdin (record-accessor channel-type 'stdin))
  84. (define channel-stdout (record-accessor channel-type 'stdout))
  85. (define channel-printer (record-accessor channel-type 'printer))
  86. (define channel-token-module (record-accessor channel-type 'token-module))
  87. ;;;
  88. ;;; Channel
  89. ;;;
  90. (define (channel-open ch)
  91. (let ((stdin (channel-stdin ch))
  92. (stdout (channel-stdout ch))
  93. (printer (channel-printer ch))
  94. (token-module (channel-token-module ch)))
  95. (let loop ()
  96. (catch #t
  97. (lambda ()
  98. (channel:prompt stdout)
  99. (let ((cmd (read stdin)))
  100. (if (eof-object? cmd)
  101. (throw 'quit)
  102. (case cmd
  103. ((eval)
  104. (module-use! (current-module) token-module)
  105. (printer ch (eval (read stdin) (current-module))))
  106. ((destroy)
  107. (let ((token (read stdin)))
  108. (if (module-defined? token-module token)
  109. (module-remove! token-module token)
  110. (channel:error stdout "Invalid token: ~S" token))))
  111. ((quit)
  112. (throw 'quit))
  113. (else
  114. (channel:error stdout "Unknown command: ~S" cmd)))))
  115. (loop))
  116. (lambda (key . args)
  117. (case key
  118. ((quit) (throw 'quit))
  119. (else
  120. (format stdout "exception = ~S\n"
  121. (list key (apply format #f (cadr args) (caddr args))))
  122. (loop))))))))
  123. (define (channel-print-value ch val)
  124. (format (channel-stdout ch) "value = ~S\n" val))
  125. (define (channel-print-token ch val)
  126. (let* ((token (symbol-append (gensym "%%") '%%))
  127. (pair (cons token (object->string val))))
  128. (format (channel-stdout ch) "token = ~S\n" pair)
  129. (module-define! (channel-token-module ch) token val)))
  130. (define (channel:prompt port)
  131. (display "channel> " port)
  132. (force-output port))
  133. (define (channel:error port msg . args)
  134. (display "ERROR: " port)
  135. (apply format port msg args)
  136. (newline port))
  137. ;;;
  138. ;;; Guile 1.4 compatibility
  139. ;;;
  140. (define guile:eval eval)
  141. (define eval
  142. (if (= (car (procedure-property guile:eval 'arity)) 1)
  143. (lambda (x e) (guile:eval x))
  144. guile:eval))
  145. (define object->string
  146. (if (defined? 'object->string)
  147. object->string
  148. (lambda (x) (format #f "~S" x))))
  149. ;;; channel.scm ends here