2014-07-27 22:37:46 -04:00
|
|
|
(define-library (picrin repl)
|
|
|
|
(import (scheme base)
|
|
|
|
(scheme read)
|
|
|
|
(scheme file)
|
|
|
|
(scheme write)
|
|
|
|
(scheme eval)
|
|
|
|
(scheme process-context))
|
|
|
|
|
2014-07-29 02:57:26 -04:00
|
|
|
(define (join sep strs)
|
|
|
|
(let loop ((result (car strs)) (rest (cdr strs)))
|
|
|
|
(if (null? rest)
|
|
|
|
result
|
|
|
|
(loop (string-append result sep (car rest)) (cdr rest)))))
|
|
|
|
|
2014-07-27 22:37:46 -04:00
|
|
|
(define (file->string file)
|
|
|
|
(with-input-from-file file
|
|
|
|
(lambda ()
|
2014-07-29 02:57:26 -04:00
|
|
|
(let loop ((line (read-line)) (acc '()))
|
2014-07-27 22:37:46 -04:00
|
|
|
(if (eof-object? line)
|
2014-07-29 02:57:26 -04:00
|
|
|
(join "\n" (reverse acc))
|
|
|
|
(loop (read-line) (cons line acc)))))))
|
2014-07-27 22:37:46 -04:00
|
|
|
|
2014-07-29 02:42:52 -04:00
|
|
|
(define (print obj . port)
|
2014-07-29 02:56:50 -04:00
|
|
|
(let ((port (if (null? port) (current-output-port) (car port))))
|
|
|
|
(write obj port)
|
|
|
|
(newline port)
|
|
|
|
obj))
|
2014-07-29 02:42:52 -04:00
|
|
|
|
2014-07-27 22:37:46 -04:00
|
|
|
(define (print-help)
|
|
|
|
(display "picrin scheme\n")
|
|
|
|
(display "\n")
|
|
|
|
(display "Usage: picrin [options] [file]\n")
|
|
|
|
(display "\n")
|
|
|
|
(display "Options:\n")
|
|
|
|
(display " -e [program] run one liner script\n")
|
2014-07-29 02:42:35 -04:00
|
|
|
(display " -h or --help show this help\n"))
|
2014-07-27 22:37:46 -04:00
|
|
|
|
|
|
|
(define (getopt)
|
|
|
|
(let ((args (cdr (command-line))))
|
|
|
|
(if (null? args)
|
|
|
|
#f
|
2014-07-29 02:42:35 -04:00
|
|
|
(case (string->symbol (car args))
|
|
|
|
((-h --help)
|
2014-07-27 22:37:46 -04:00
|
|
|
(print-help)
|
2014-07-29 02:44:22 -04:00
|
|
|
(exit 1))
|
2014-07-29 02:42:35 -04:00
|
|
|
((-e)
|
2014-07-27 22:37:46 -04:00
|
|
|
(cadr args))
|
|
|
|
(else
|
|
|
|
(file->string (car args)))))))
|
|
|
|
|
2014-08-03 01:38:38 -04:00
|
|
|
(define (main-loop in out on-err)
|
2014-07-29 02:43:43 -04:00
|
|
|
(display "> " out)
|
|
|
|
(let ((expr (read in)))
|
2014-07-27 22:37:46 -04:00
|
|
|
(if (eof-object? expr)
|
2014-07-29 02:43:43 -04:00
|
|
|
(newline out) ; exit
|
2014-07-27 22:37:46 -04:00
|
|
|
(begin
|
|
|
|
(call/cc
|
|
|
|
(lambda (leave)
|
|
|
|
(with-exception-handler
|
|
|
|
(lambda (condition)
|
2014-07-29 02:43:43 -04:00
|
|
|
(display (error-object-message condition) (current-error-port))
|
2014-07-27 22:37:46 -04:00
|
|
|
(newline)
|
2014-08-03 01:38:38 -04:00
|
|
|
(if on-err
|
|
|
|
(on-err)
|
|
|
|
(leave)))
|
2014-07-27 22:37:46 -04:00
|
|
|
(lambda ()
|
2014-07-29 02:43:43 -04:00
|
|
|
(print (eval expr '(picrin user)) out)))))
|
2014-08-03 01:38:38 -04:00
|
|
|
(main-loop in out on-err)))))
|
2014-07-29 02:43:43 -04:00
|
|
|
|
|
|
|
(define (run-repl program)
|
|
|
|
(let ((in (if program
|
|
|
|
(open-input-string program)
|
|
|
|
(current-input-port)))
|
|
|
|
(out (if program
|
|
|
|
(open-output-string) ; ignore output
|
2014-08-03 01:38:38 -04:00
|
|
|
(current-output-port)))
|
|
|
|
(on-err (if program
|
|
|
|
(lambda () (exit 1))
|
|
|
|
#f)))
|
|
|
|
(main-loop in out on-err)))
|
2014-07-27 22:37:46 -04:00
|
|
|
|
|
|
|
(define (repl)
|
|
|
|
(let ((program (getopt)))
|
2014-07-29 02:43:43 -04:00
|
|
|
(run-repl program)))
|
2014-07-27 22:37:46 -04:00
|
|
|
|
|
|
|
(export repl))
|
2014-08-30 10:30:04 -04:00
|
|
|
|