#lang racket
(define (calc-rpn text)
(let ((table (hash "+" + "-" - "*" * "/" / "%" modulo)))
(car
(foldl (lambda (tok stack)
(when (non-empty-string? tok)
(cond ((string->number tok) => (lambda (x)
(cons x stack)))
(else (let ((b (car stack)) (a (cadr stack)))
(cons ((hash-ref table tok) a b) (cddr stack)))))))
'() (string-split text)))))
(define (main)
(printf ">>> ")
(let ((expr (read-line)))
(with-handlers ((exn:fail:contract?
(lambda (exn)
(printf "不正な入力です~%")
(main))))
(unless (char=? (string-ref expr 0) #\q)
(printf "~a = ~a~%" expr (calc-rpn expr))
(main)))))
I2xhbmcgcmFja2V0CgooZGVmaW5lIChjYWxjLXJwbiB0ZXh0KQogIChsZXQgKCh0YWJsZSAoaGFzaCAiKyIgKyAiLSIgLSAiKiIgKiAiLyIgLyAiJSIgbW9kdWxvKSkpCiAgICAoY2FyCiAgICAgKGZvbGRsIChsYW1iZGEgKHRvayBzdGFjaykKICAgICAgICAgICAgICAod2hlbiAobm9uLWVtcHR5LXN0cmluZz8gdG9rKQogICAgICAgICAgICAgICAgKGNvbmQgKChzdHJpbmctPm51bWJlciB0b2spID0+IChsYW1iZGEgKHgpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY29ucyB4IHN0YWNrKSkpCiAgICAgICAgICAgICAgICAgICAgICAoZWxzZSAobGV0ICgoYiAoY2FyIHN0YWNrKSkgKGEgKGNhZHIgc3RhY2spKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNvbnMgKChoYXNoLXJlZiB0YWJsZSB0b2spIGEgYikgKGNkZHIgc3RhY2spKSkpKSkpCiAgICAgICAgICAgICcoKSAoc3RyaW5nLXNwbGl0IHRleHQpKSkpKQoKKGRlZmluZSAobWFpbikKICAocHJpbnRmICI+Pj4gIikKICAobGV0ICgoZXhwciAocmVhZC1saW5lKSkpCiAgICAod2l0aC1oYW5kbGVycyAoKGV4bjpmYWlsOmNvbnRyYWN0PwogICAgICAgICAgICAgICAgICAgICAobGFtYmRhIChleG4pCiAgICAgICAgICAgICAgICAgICAgICAgKHByaW50ZiAi5LiN5q2j44Gq5YWl5Yqb44Gn44GZfiUiKQogICAgICAgICAgICAgICAgICAgICAgIChtYWluKSkpKQogICAgICAodW5sZXNzIChjaGFyPT8gKHN0cmluZy1yZWYgZXhwciAwKSAjXHEpCiAgICAgICAgKHByaW50ZiAifmEgPSB+YX4lIiBleHByIChjYWxjLXJwbiBleHByKSkKICAgICAgICAobWFpbikpKSkpCiAgICAgICAgCg==