48 lines
2.1 KiB
Racket
48 lines
2.1 KiB
Racket
#lang racket
|
|
; if we `for` over the port, we won't have the program in memory for 'Q'
|
|
(define (parse-HQ9+ the-program)
|
|
(define oTW " on the wall")
|
|
(and ; ensures the accumulator is never seen!
|
|
(for/fold ((A 0))
|
|
((token (in-string the-program)))
|
|
(case token
|
|
((#\H) (display "hello, world") A)
|
|
((#\Q) (display the-program) A)
|
|
;; official esolang version of 99-BoB at:
|
|
;; http://esolangs.org/wiki/99_bottles_of_beer
|
|
((#\9)
|
|
(displayln
|
|
(let ((BoB (lambda (n)
|
|
(string-append
|
|
(case n ((1) "1 bottle") ((0) "No bottles")
|
|
(else (format "~a bottles" n)))
|
|
" of beer"))))
|
|
(string-join
|
|
(for/list ((btls (in-range 99 0 -1)))
|
|
(string-append (BoB btls)oTW",\n"(BoB btls)
|
|
".\nTake one down, pass it around,\n"
|
|
(BoB (sub1 btls))oTW"."))
|
|
"\n\n"))) A)
|
|
((#\+) (add1 A))
|
|
((#\newline) ; language extension, makes getting standard in easier
|
|
(eprintf "warning: HQ9+: language extension ~s" token)
|
|
A)
|
|
(else (error "syntax error: HQ9+: unrecognised token ~s" token))))
|
|
(void)))
|
|
|
|
(module+ main (parse-HQ9+ (port->string)))
|
|
|
|
(module+ test
|
|
(require rackunit)
|
|
(check-equal? (with-output-to-string (lambda () (parse-HQ9+ ""))) "")
|
|
(check-equal? (with-output-to-string (lambda () (parse-HQ9+ "H"))) "hello, world")
|
|
(check-equal? (with-output-to-string (lambda () (parse-HQ9+ "Q"))) "Q")
|
|
(check-equal? (with-output-to-string (lambda () (parse-HQ9+ "QQ"))) "QQQQ")
|
|
(check-equal? (with-output-to-string (lambda () (parse-HQ9+ "+"))) "")
|
|
(check-equal? (with-output-to-string (lambda () (parse-HQ9+ "+"))) "")
|
|
(check-equal? (with-output-to-string (lambda () (parse-HQ9+ "++"))) "")
|
|
(check-equal? (with-output-to-string (lambda () (parse-HQ9+ "+++"))) "")
|
|
(check-equal? (with-output-to-string (lambda () (parse-HQ9+ "+++++++++++++++++"))) "")
|
|
(check-equal? (with-output-to-string (lambda () (parse-HQ9+ (make-string 10000 #\+)))) "")
|
|
;;; you can jolly well read (and sing along to) the output of '9'
|
|
)
|