r4rs.scm 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. ;;;; r4rs.scm --- definitions needed for libguile to be R4RS compliant
  2. ;;;; Jim Blandy <jimb@cyclic.com> --- October 1996
  3. ;;;; Copyright (C) 1996, 1997, 1998, 2000, 2001, 2006, 2010, 2011 Free Software Foundation, Inc.
  4. ;;;;
  5. ;;;; This library is free software; you can redistribute it and/or
  6. ;;;; modify it under the terms of the GNU Lesser General Public
  7. ;;;; License as published by the Free Software Foundation; either
  8. ;;;; version 3 of the License, or (at your option) any later version.
  9. ;;;;
  10. ;;;; This library is distributed in the hope that it will be useful,
  11. ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. ;;;; Lesser General Public License for more details.
  14. ;;;;
  15. ;;;; You should have received a copy of the GNU Lesser General Public
  16. ;;;; License along with this library; if not, write to the Free Software
  17. ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  18. (eval-when (compile)
  19. (set-current-module (resolve-module '(guile))))
  20. ;;;; apply and call-with-current-continuation
  21. ;;; The deal with these is that they are the procedural wrappers around the
  22. ;;; primitives of Guile's language. There are about 20 different kinds of
  23. ;;; expression in Guile, and e.g. @apply is one of them. (It has to be that way
  24. ;;; to preserve tail recursion.)
  25. ;;;
  26. ;;; Usually we recognize (apply foo bar) to be an instance of @apply, but in the
  27. ;;; case that apply is passed to apply, or we're bootstrapping, we need a
  28. ;;; trampoline -- and here they are.
  29. (define (apply fun . args)
  30. (@apply fun (apply:nconc2last args)))
  31. (define (call-with-current-continuation proc)
  32. (@call-with-current-continuation proc))
  33. (define (call-with-values producer consumer)
  34. (@call-with-values producer consumer))
  35. (define (dynamic-wind in thunk out)
  36. "All three arguments must be 0-argument procedures.
  37. Guard @var{in} is called, then @var{thunk}, then
  38. guard @var{out}.
  39. If, any time during the execution of @var{thunk}, the
  40. continuation of the @code{dynamic_wind} expression is escaped
  41. non-locally, @var{out} is called. If the continuation of
  42. the dynamic-wind is re-entered, @var{in} is called. Thus
  43. @var{in} and @var{out} may be called any number of
  44. times.
  45. @lisp
  46. (define x 'normal-binding)
  47. @result{} x
  48. (define a-cont
  49. (call-with-current-continuation
  50. (lambda (escape)
  51. (let ((old-x x))
  52. (dynamic-wind
  53. ;; in-guard:
  54. ;;
  55. (lambda () (set! x 'special-binding))
  56. ;; thunk
  57. ;;
  58. (lambda () (display x) (newline)
  59. (call-with-current-continuation escape)
  60. (display x) (newline)
  61. x)
  62. ;; out-guard:
  63. ;;
  64. (lambda () (set! x old-x)))))))
  65. ;; Prints:
  66. special-binding
  67. ;; Evaluates to:
  68. @result{} a-cont
  69. x
  70. @result{} normal-binding
  71. (a-cont #f)
  72. ;; Prints:
  73. special-binding
  74. ;; Evaluates to:
  75. @result{} a-cont ;; the value of the (define a-cont...)
  76. x
  77. @result{} normal-binding
  78. a-cont
  79. @result{} special-binding
  80. @end lisp"
  81. (@dynamic-wind in (thunk) out))
  82. ;;;; Basic Port Code
  83. ;;; Specifically, the parts of the low-level port code that are written in
  84. ;;; Scheme rather than C.
  85. ;;;
  86. ;;; WARNING: the parts of this interface that refer to file ports
  87. ;;; are going away. It would be gone already except that it is used
  88. ;;; "internally" in a few places.
  89. ;;; OPEN_READ, OPEN_WRITE, and OPEN_BOTH are used to request the
  90. ;;; proper mode to open files in.
  91. ;;;
  92. ;;; If we want to support systems that do CRLF->LF translation, like
  93. ;;; Windows, then we should have a symbol in scmconfig.h made visible
  94. ;;; to the Scheme level that we can test here, and autoconf magic to
  95. ;;; #define it when appropriate. Windows will probably just have a
  96. ;;; hand-generated scmconfig.h file.
  97. (define OPEN_READ "r")
  98. (define OPEN_WRITE "w")
  99. (define OPEN_BOTH "r+")
  100. (define *null-device* "/dev/null")
  101. (define (open-input-file str)
  102. "Takes a string naming an existing file and returns an input port
  103. capable of delivering characters from the file. If the file
  104. cannot be opened, an error is signalled."
  105. (open-file str OPEN_READ))
  106. (define (open-output-file str)
  107. "Takes a string naming an output file to be created and returns an
  108. output port capable of writing characters to a new file by that
  109. name. If the file cannot be opened, an error is signalled. If a
  110. file with the given name already exists, the effect is unspecified."
  111. (open-file str OPEN_WRITE))
  112. (define (open-io-file str)
  113. "Open file with name STR for both input and output."
  114. (open-file str OPEN_BOTH))
  115. (define close-io-port close-port)
  116. (define (call-with-input-file str proc)
  117. "PROC should be a procedure of one argument, and STR should be a
  118. string naming a file. The file must
  119. already exist. These procedures call PROC
  120. with one argument: the port obtained by opening the named file for
  121. input or output. If the file cannot be opened, an error is
  122. signalled. If the procedure returns, then the port is closed
  123. automatically and the values yielded by the procedure are returned.
  124. If the procedure does not return, then the port will not be closed
  125. automatically unless it is possible to prove that the port will
  126. never again be used for a read or write operation."
  127. (let ((p (open-input-file str)))
  128. (call-with-values
  129. (lambda () (proc p))
  130. (lambda vals
  131. (close-input-port p)
  132. (apply values vals)))))
  133. (define (call-with-output-file str proc)
  134. "PROC should be a procedure of one argument, and STR should be a
  135. string naming a file. The behaviour is unspecified if the file
  136. already exists. These procedures call PROC
  137. with one argument: the port obtained by opening the named file for
  138. input or output. If the file cannot be opened, an error is
  139. signalled. If the procedure returns, then the port is closed
  140. automatically and the values yielded by the procedure are returned.
  141. If the procedure does not return, then the port will not be closed
  142. automatically unless it is possible to prove that the port will
  143. never again be used for a read or write operation."
  144. (let ((p (open-output-file str)))
  145. (call-with-values
  146. (lambda () (proc p))
  147. (lambda vals
  148. (close-output-port p)
  149. (apply values vals)))))
  150. (define (with-input-from-port port thunk)
  151. (let* ((swaports (lambda () (set! port (set-current-input-port port)))))
  152. (dynamic-wind swaports thunk swaports)))
  153. (define (with-output-to-port port thunk)
  154. (let* ((swaports (lambda () (set! port (set-current-output-port port)))))
  155. (dynamic-wind swaports thunk swaports)))
  156. (define (with-error-to-port port thunk)
  157. (let* ((swaports (lambda () (set! port (set-current-error-port port)))))
  158. (dynamic-wind swaports thunk swaports)))
  159. (define (with-input-from-file file thunk)
  160. "THUNK must be a procedure of no arguments, and FILE must be a
  161. string naming a file. The file must already exist. The file is opened for
  162. input, an input port connected to it is made
  163. the default value returned by `current-input-port',
  164. and the THUNK is called with no arguments.
  165. When the THUNK returns, the port is closed and the previous
  166. default is restored. Returns the values yielded by THUNK. If an
  167. escape procedure is used to escape from the continuation of these
  168. procedures, their behavior is implementation dependent."
  169. (call-with-input-file file
  170. (lambda (p) (with-input-from-port p thunk))))
  171. (define (with-output-to-file file thunk)
  172. "THUNK must be a procedure of no arguments, and FILE must be a
  173. string naming a file. The effect is unspecified if the file already exists.
  174. The file is opened for output, an output port connected to it is made
  175. the default value returned by `current-output-port',
  176. and the THUNK is called with no arguments.
  177. When the THUNK returns, the port is closed and the previous
  178. default is restored. Returns the values yielded by THUNK. If an
  179. escape procedure is used to escape from the continuation of these
  180. procedures, their behavior is implementation dependent."
  181. (call-with-output-file file
  182. (lambda (p) (with-output-to-port p thunk))))
  183. (define (with-error-to-file file thunk)
  184. "THUNK must be a procedure of no arguments, and FILE must be a
  185. string naming a file. The effect is unspecified if the file already exists.
  186. The file is opened for output, an output port connected to it is made
  187. the default value returned by `current-error-port',
  188. and the THUNK is called with no arguments.
  189. When the THUNK returns, the port is closed and the previous
  190. default is restored. Returns the values yielded by THUNK. If an
  191. escape procedure is used to escape from the continuation of these
  192. procedures, their behavior is implementation dependent."
  193. (call-with-output-file file
  194. (lambda (p) (with-error-to-port p thunk))))
  195. (define (with-input-from-string string thunk)
  196. "THUNK must be a procedure of no arguments.
  197. The test of STRING is opened for
  198. input, an input port connected to it is made,
  199. and the THUNK is called with no arguments.
  200. When the THUNK returns, the port is closed.
  201. Returns the values yielded by THUNK. If an
  202. escape procedure is used to escape from the continuation of these
  203. procedures, their behavior is implementation dependent."
  204. (call-with-input-string string
  205. (lambda (p) (with-input-from-port p thunk))))
  206. (define (with-output-to-string thunk)
  207. "Calls THUNK and returns its output as a string."
  208. (call-with-output-string
  209. (lambda (p) (with-output-to-port p thunk))))
  210. (define (with-error-to-string thunk)
  211. "Calls THUNK and returns its error output as a string."
  212. (call-with-output-string
  213. (lambda (p) (with-error-to-port p thunk))))
  214. (define the-eof-object (call-with-input-string "" (lambda (p) (read-char p))))