[plt-scheme] a tiny repl

From: Hugh Myers (hsmyers at gmail.com)
Date: Sun Jun 28 16:56:46 EDT 2009

On the off chance that others who read this list are as needy as
myself, what follows is a tiny repl. I use an expanded version to test
and debug my current work--- single stepping through a chess game for
instance. Since I'm new to scheme, I've no knowledge of better ways to
do this, so feel free to criticize. It paid for itself by being
helpful to me, gravy if helpful to someone else...


#lang scheme

(define (test-repl)
  (repl "test> "))

;;; Define and document repl functions

(define (repl-help)
  (printf "~a~%" "Commands are h,p, and q.")
  (printf "~a~%" "Where:")
  (printf "~a~%" "       h =s 'help'")
  (printf "~a~%" "       j n =s 'jmp n plys'")
  (printf "~a~%" "       p =s 'print-board'")
  (printf "~a~%" "       q =s 'quit'")

(define (parse-value str)
  (let ((s (if (regexp-match? #px"\\s" str)
               (car (regexp-split #px"\\s" str))
      [(equal? s "h") 'h]
      [(equal? s "q") 'q]
      [(equal? s "p") 'p]
      [(equal? s "j") 'jmp]
      [else #f]

(define commands (list
                  [cons 'p '(print-board)]
                  [cons 'q '(escape 'Bye!)]
                  [cons 'h '(repl-help)]

;;; A tiny repl

(define (repl prompt)
  (display prompt)
  (let* ([value (read-line)]
         [parameters (rest (regexp-split #px"\\s" value))]
         [command (parse-value value)]
    (if (empty? parameters)
        (if command
            (eval (get-alist command commands))
            (printf "unknown command: ~a~%" value))
        (eval (string->function (cons (symbol->string command) parameters)))))
  (repl prompt))

;;; Support

(define (get-alist prop alist)
  (let ((association (assoc prop alist)))
    (and association (cdr association))))

(define (escape v)
   (lambda () v)))

(define (string->actual s)
  (let ([value (if (string->number s)
                   (string->number s)
                   (string->symbol s))])

(define (string->function s)
  (let ((ss (if (string? s)
                [regexp-split #px"\\s" s]
    (for/list ((c ss))
      (string->actual c))))

;;; Dummied up functions for demonstration and testing

(define (jmp n)
  (printf "jump forward ~A ply in movelist~%" n))

(define (print-board)
  (printf "display board~%"))

Posted on the users mailing list.