split repl and main loop

This commit is contained in:
Yuichi Nishiwaki 2014-08-31 00:36:20 +09:00
parent 75ae0cad12
commit 029d98338d
4 changed files with 64 additions and 73 deletions

View File

@ -1,87 +1,26 @@
(define-library (picrin repl) (define-library (picrin repl)
(import (scheme base) (import (scheme base)
(scheme read) (scheme read)
(scheme file)
(scheme write) (scheme write)
(scheme eval) (scheme eval))
(scheme process-context))
(define (join sep strs) (define (repl)
(let loop ((result (car strs)) (rest (cdr strs))) (display "> ")
(if (null? rest) (let ((expr (read)))
result
(loop (string-append result sep (car rest)) (cdr rest)))))
(define (file->string file)
(with-input-from-file file
(lambda ()
(let loop ((line (read-line)) (acc '()))
(if (eof-object? line)
(join "\n" (reverse acc))
(loop (read-line) (cons line acc)))))))
(define (print obj . port)
(let ((port (if (null? port) (current-output-port) (car port))))
(write obj port)
(newline port)
obj))
(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")
(display " -h or --help show this help\n"))
(define (getopt)
(let ((args (cdr (command-line))))
(if (null? args)
#f
(case (string->symbol (car args))
((-h --help)
(print-help)
(exit 1))
((-e)
(cadr args))
(else
(file->string (car args)))))))
(define (main-loop in out on-err)
(display "> " out)
(let ((expr (read in)))
(if (eof-object? expr) (if (eof-object? expr)
(newline out) ; exit (newline) ; exit
(begin (begin
(call/cc (call/cc
(lambda (leave) (lambda (exit)
(with-exception-handler (with-exception-handler
(lambda (condition) (lambda (condition)
(display (error-object-message condition) (current-error-port)) (display (error-object-message condition) (current-error-port))
(newline) (newline)
(if on-err (exit))
(on-err)
(leave)))
(lambda () (lambda ()
(print (eval expr '(picrin user)) out))))) (write (eval expr '(picrin user)))
(main-loop in out on-err))))) (newline)))))
(repl)))))
(define (run-repl program)
(let ((in (if program
(open-input-string program)
(current-input-port)))
(out (if program
(open-output-string) ; ignore output
(current-output-port)))
(on-err (if program
(lambda () (exit 1))
#f)))
(main-loop in out on-err)))
(define (repl)
(let ((program (getopt)))
(run-repl program)))
(export repl)) (export repl))

View File

@ -0,0 +1 @@
list(APPEND PICLIB_CONTRIB_LIBS ${PROJECT_SOURCE_DIR}/contrib/30.main/main.scm)

51
contrib/30.main/main.scm Normal file
View File

@ -0,0 +1,51 @@
(define-library (picrin main)
(import (scheme base)
(scheme read)
(scheme write)
(scheme process-context)
(scheme load)
(scheme eval)
(picrin repl))
(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")
(display " -h or --help show this help\n"))
(define (getopt)
(let ((args (cdr (command-line))))
(if (null? args)
(values 'repl #f)
(case (string->symbol (car args))
((-h --help)
(print-help)
(exit 1))
((-e)
(values 'line (cadr args)))
(else
(values 'file (car args)))))))
(define (exec-file filename)
(load filename))
(define (exec-line str)
(call-with-port (open-input-string str)
(lambda (in)
(let loop ((expr (read in)))
(unless (eof-object? expr)
(eval expr '(picrin user))
(loop (read in)))))))
(define (main)
(call-with-values getopt
(lambda (type dat)
(case type
((repl) (repl))
((line) (exec-line dat))
((file) (exec-file dat))))))
(export main))

View File

@ -14,8 +14,8 @@ main(int argc, char *argv[], char **envp)
pic = pic_open(argc, argv, envp); pic = pic_open(argc, argv, envp);
pic_try { pic_try {
pic_import(pic, pic_read_cstr(pic, "(picrin repl)")); pic_import(pic, pic_read_cstr(pic, "(picrin main)"));
pic_funcall(pic, "repl", pic_nil_value()); pic_funcall(pic, "main", pic_nil_value());
} }
pic_catch { pic_catch {
pic_print_backtrace(pic, pic->err); pic_print_backtrace(pic, pic->err);