mini-command.scm 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. ; Copyright (c) 1993-2008 by Richard Kelsey and Jonathan Rees. See file COPYING.
  2. ; Miniature command processor.
  3. (define (command-processor ignore args)
  4. (let ((in (current-input-port))
  5. (out (current-output-port))
  6. (err (current-error-port))
  7. (batch? (member "batch" (map os-string->string args))))
  8. (let loop ()
  9. ((call-with-current-continuation
  10. (lambda (go)
  11. (with-handler
  12. (lambda (c punt)
  13. (cond ((or (serious-condition? c) (interrupt-condition? c))
  14. (display-condition c err)
  15. (go (if batch?
  16. (lambda () 1)
  17. loop)))
  18. ((warning? c)
  19. (display-condition c err))
  20. (else (punt))))
  21. (lambda ()
  22. (if (not batch?)
  23. (display "- " out))
  24. (let ((form (read in)))
  25. (cond ((eof-object? form)
  26. (newline out)
  27. (go (lambda () 0)))
  28. ((and (pair? form) (eq? (car form) 'unquote))
  29. (case (cadr form)
  30. ((load)
  31. (mini-load in)
  32. (go loop))
  33. ((go)
  34. (let ((form (read in)))
  35. (go (lambda ()
  36. (eval form (interaction-environment))))))
  37. (else (error 'command-processor
  38. "unknown command" (cadr form) 'go 'load (eq? (cadr form) 'load)))))
  39. (else
  40. (call-with-values
  41. (lambda () (eval form (interaction-environment)))
  42. (lambda results
  43. (for-each (lambda (result)
  44. (write result out)
  45. (newline out))
  46. results)
  47. (go loop))))))))))))))
  48. (define (mini-load in)
  49. (let ((c (peek-char in)))
  50. (cond ((char=? c #\newline) (read-char in) #t)
  51. ((char-whitespace? c) (read-char in) (mini-load in))
  52. ((char=? c #\")
  53. (let ((filename (read in)))
  54. (load filename)
  55. (mini-load in)))
  56. (else
  57. (let ((filename (read-string in char-whitespace?)))
  58. (load filename)
  59. (mini-load in))))))
  60. (define (read-string port delimiter?)
  61. (let loop ((l '()) (n 0))
  62. (let ((c (peek-char port)))
  63. (cond ((or (eof-object? c)
  64. (delimiter? c))
  65. (list->string (reverse l)))
  66. (else
  67. (loop (cons (read-char port) l) (+ n 1)))))))
  68. (define (byte-vector->string b)
  69. (let ((size (- (byte-vector-length b) 1)))
  70. (do ((s (make-string size))
  71. (i 0 (+ 1 i)))
  72. ((= i size)
  73. s)
  74. (string-set! s i (ascii->char (vector-ref b i))))))