common.scm 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. ;;; Repl common routines
  2. ;; Copyright (C) 2001, 2008, 2009, 2010, 2011, 2012,
  3. ;; 2013, 2014 Free Software Foundation, Inc.
  4. ;;; This library is free software; you can redistribute it and/or
  5. ;;; modify it under the terms of the GNU Lesser General Public
  6. ;;; License as published by the Free Software Foundation; either
  7. ;;; version 3 of the License, or (at your option) any later version.
  8. ;;;
  9. ;;; This library is distributed in the hope that it will be useful,
  10. ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. ;;; Lesser General Public License for more details.
  13. ;;;
  14. ;;; You should have received a copy of the GNU Lesser General Public
  15. ;;; License along with this library; if not, write to the Free Software
  16. ;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. ;;; Code:
  18. (define-module (system repl common)
  19. #:use-module (system base syntax)
  20. #:use-module (system base compile)
  21. #:use-module (system base language)
  22. #:use-module (system base message)
  23. #:use-module (system vm program)
  24. #:use-module (system vm loader)
  25. #:autoload (language tree-il optimize) (optimize)
  26. #:use-module (ice-9 control)
  27. #:use-module (ice-9 history)
  28. #:export (<repl> make-repl repl-language repl-options
  29. repl-tm-stats repl-gc-stats repl-debug
  30. repl-welcome repl-prompt
  31. repl-read repl-compile repl-prepare-eval-thunk repl-eval
  32. repl-expand repl-optimize
  33. repl-parse repl-print repl-option-ref repl-option-set!
  34. repl-default-option-set! repl-default-prompt-set!
  35. puts ->string user-error
  36. *warranty* *copying* *version*))
  37. (define *version*
  38. (format #f "GNU Guile ~A
  39. Copyright (C) 1995-2014 Free Software Foundation, Inc.
  40. Guile comes with ABSOLUTELY NO WARRANTY; for details type `,show w'.
  41. This program is free software, and you are welcome to redistribute it
  42. under certain conditions; type `,show c' for details." (version)))
  43. (define *copying*
  44. "Guile is free software: you can redistribute it and/or modify
  45. it under the terms of the GNU Lesser General Public License as
  46. published by the Free Software Foundation, either version 3 of
  47. the License, or (at your option) any later version.
  48. Guile is distributed in the hope that it will be useful, but
  49. WITHOUT ANY WARRANTY; without even the implied warranty of
  50. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  51. Lesser General Public License for more details.
  52. You should have received a copy of the GNU Lesser General Public
  53. License along with this program. If not, see
  54. <http://www.gnu.org/licenses/lgpl.html>.")
  55. (define *warranty*
  56. "Guile is distributed WITHOUT ANY WARRANTY. The following
  57. sections from the GNU General Public License, version 3, should
  58. make that clear.
  59. 15. Disclaimer of Warranty.
  60. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
  61. APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
  62. HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY
  63. OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
  64. THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  65. PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
  66. IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
  67. ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
  68. 16. Limitation of Liability.
  69. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
  70. WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
  71. THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
  72. GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
  73. USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
  74. DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
  75. PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
  76. EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
  77. SUCH DAMAGES.
  78. 17. Interpretation of Sections 15 and 16.
  79. If the disclaimer of warranty and limitation of liability provided
  80. above cannot be given local legal effect according to their terms,
  81. reviewing courts shall apply local law that most closely approximates
  82. an absolute waiver of all civil liability in connection with the
  83. Program, unless a warranty or assumption of liability accompanies a
  84. copy of the Program in return for a fee.
  85. See <http://www.gnu.org/licenses/lgpl.html>, for more details.")
  86. ;;;
  87. ;;; Repl type
  88. ;;;
  89. (define-record/keywords <repl>
  90. language options tm-stats gc-stats debug)
  91. (define repl-default-options
  92. (copy-tree
  93. `((compile-options ,%auto-compilation-options #f)
  94. (trace #f #f)
  95. (interp #f #f)
  96. (prompt #f ,(lambda (prompt)
  97. (cond
  98. ((not prompt) #f)
  99. ((string? prompt) (lambda (repl) prompt))
  100. ((thunk? prompt) (lambda (repl) (prompt)))
  101. ((procedure? prompt) prompt)
  102. (else (error "Invalid prompt" prompt)))))
  103. (print #f ,(lambda (print)
  104. (cond
  105. ((not print) #f)
  106. ((procedure? print) print)
  107. (else (error "Invalid print procedure" print)))))
  108. (value-history
  109. ,(value-history-enabled?)
  110. ,(lambda (x)
  111. (if x (enable-value-history!) (disable-value-history!))
  112. (->bool x)))
  113. (on-error
  114. debug
  115. ,(let ((vals '(debug backtrace report pass)))
  116. (lambda (x)
  117. (if (memq x vals)
  118. x
  119. (error "Bad on-error value ~a; expected one of ~a" x vals))))))))
  120. (define %make-repl make-repl)
  121. (define* (make-repl lang #:optional debug)
  122. (%make-repl #:language (if (language? lang)
  123. lang
  124. (lookup-language lang))
  125. #:options (copy-tree repl-default-options)
  126. #:tm-stats (times)
  127. #:gc-stats (gc-stats)
  128. #:debug debug))
  129. (define (repl-welcome repl)
  130. (display *version*)
  131. (newline)
  132. (newline)
  133. (display "Enter `,help' for help.\n"))
  134. (define (repl-prompt repl)
  135. (cond
  136. ((repl-option-ref repl 'prompt)
  137. => (lambda (prompt) (prompt repl)))
  138. (else
  139. (format #f "~A@~A~A> " (language-name (repl-language repl))
  140. (module-name (current-module))
  141. (let ((level (length (cond
  142. ((fluid-ref *repl-stack*) => cdr)
  143. (else '())))))
  144. (if (zero? level) "" (format #f " [~a]" level)))))))
  145. (define (repl-read repl)
  146. (let ((reader (language-reader (repl-language repl))))
  147. (reader (current-input-port) (current-module))))
  148. (define (repl-compile-options repl)
  149. (repl-option-ref repl 'compile-options))
  150. (define (repl-compile repl form)
  151. (let ((from (repl-language repl))
  152. (opts (repl-compile-options repl)))
  153. (compile form #:from from #:to 'bytecode #:opts opts
  154. #:env (current-module))))
  155. (define (repl-expand repl form)
  156. (let ((from (repl-language repl))
  157. (opts (repl-compile-options repl)))
  158. (decompile (compile form #:from from #:to 'tree-il #:opts opts
  159. #:env (current-module))
  160. #:from 'tree-il #:to from)))
  161. (define (repl-optimize repl form)
  162. (let ((from (repl-language repl))
  163. (opts (repl-compile-options repl)))
  164. (decompile (optimize (compile form #:from from #:to 'tree-il #:opts opts
  165. #:env (current-module))
  166. (current-module)
  167. opts)
  168. #:from 'tree-il #:to from)))
  169. (define (repl-parse repl form)
  170. (let ((parser (language-parser (repl-language repl))))
  171. (if parser (parser form) form)))
  172. (define (repl-prepare-eval-thunk repl form)
  173. (let* ((eval (language-evaluator (repl-language repl))))
  174. (if (and eval
  175. (or (null? (language-compilers (repl-language repl)))
  176. (repl-option-ref repl 'interp)))
  177. (lambda () (eval form (current-module)))
  178. (load-thunk-from-memory (repl-compile repl form)))))
  179. (define (repl-eval repl form)
  180. (let ((thunk (repl-prepare-eval-thunk repl form)))
  181. (% (thunk))))
  182. (define (repl-print repl val)
  183. (if (not (eq? val *unspecified*))
  184. (begin
  185. (run-hook before-print-hook val)
  186. (cond
  187. ((repl-option-ref repl 'print)
  188. => (lambda (print) (print repl val)))
  189. (else
  190. ;; The result of an evaluation is representable in scheme, and
  191. ;; should be printed with the generic printer, `write'. The
  192. ;; language-printer is something else: it prints expressions of
  193. ;; a given language, not the result of evaluation.
  194. (write val)
  195. (newline))))))
  196. (define (repl-option-ref repl key)
  197. (cadr (or (assq key (repl-options repl))
  198. (error "unknown repl option" key))))
  199. (define (repl-option-set! repl key val)
  200. (let ((spec (or (assq key (repl-options repl))
  201. (error "unknown repl option" key))))
  202. (set-car! (cdr spec)
  203. (if (procedure? (caddr spec))
  204. ((caddr spec) val)
  205. val))))
  206. (define (repl-default-option-set! key val)
  207. (let ((spec (or (assq key repl-default-options)
  208. (error "unknown repl option" key))))
  209. (set-car! (cdr spec)
  210. (if (procedure? (caddr spec))
  211. ((caddr spec) val)
  212. val))))
  213. (define (repl-default-prompt-set! prompt)
  214. (repl-default-option-set! 'prompt prompt))
  215. ;;;
  216. ;;; Utilities
  217. ;;;
  218. (define (puts x) (display x) (newline))
  219. (define (->string x)
  220. (object->string x display))
  221. (define (user-error msg . args)
  222. (throw 'user-error #f msg args #f))