逆ポーランド電卓(高階関数でリファクタリング)

id:ha-tan:20050913:1126563315
ひらいさん、コメントありがとうございます。eval…の前に、高階関数を使ってリファクタリングしてみました。こんなところでしょうか。うーん、いまいちエラー処理がかっこ悪いような気がします。

#!/usr/bin/env gosh

(define (error mesg)
  (display mesg (current-error-port))
  (newline (current-error-port))
  (exit 1))

(define (op stack operator)
  (cons (operator (cadr stack) (car stack))
	(cddr stack)))

(define (op+ stack)
  (op stack +))

(define (op- stack)
  (op stack -))

(define (op* stack)
  (op stack *))

(define (op/ stack)
  (if (eqv? (car stack) 0)
      (error "can't divid by 0."))
  (op stack /))

(define (rpcalc args stack)
  (cond ((null? args)
	 (if (not (eqv? (length stack) 1))
	     (error "illegal expression."))
	 (car stack))
	(else
	 (cond ((equal? "+" (car args)) (rpcalc (cdr args) (op+ stack)))
	       ((equal? "-" (car args)) (rpcalc (cdr args) (op- stack)))
	       ((equal? "*" (car args)) (rpcalc (cdr args) (op* stack)))
	       ((equal? "/" (car args)) (rpcalc (cdr args) (op/ stack)))
	       (else
		(let ((n (string->number (car args))))
		  (if (not (number? n))
		      (error "not number."))
		  (rpcalc (cdr args) (cons n stack))))))))

(define (main args)
  (display (rpcalc (cdr args) (list)))
  (newline)
  0)