逆ポーランド電卓(再帰版)

id:ha-tan:20050908:1126130413
id:ha-tan:20050906:1125958858
副作用をなくして、再帰で書いてみました。ちょっとSchemeぽくなりました。

#!/usr/bin/env gosh

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

(define (rpcalc args stack)
  (cond ((null? args)
	 (if (not (eqv? (length stack) 1))
	     (error "illegal expression."))
	 (car stack))
	(else
	 (let ((operator (car args))
	       (rest-args (cdr args)))
	   (cond ((equal? "+" operator)
		  (rpcalc rest-args
			  (cons (+ (cadr stack) (car stack))
				(cddr stack))))
		 ((equal? "-" operator)
		  (rpcalc rest-args
			  (cons (- (cadr stack) (car stack))
				(cddr stack))))
		 ((equal? "*" operator)
		  (rpcalc rest-args
			  (cons (* (cadr stack) (car stack))
				(cddr stack))))
		 ((equal? "/" operator)
		  (if (eqv? (car stack) 0)
		      (error "can't divid by 0."))
		  (rpcalc rest-args
			  (cons (/ (cadr stack) (car stack))
				(cddr stack))))
		 (else
		  (let ((n (string->number operator)))
		    (if (not (number? n))
			(error "not number."))
		    (rpcalc rest-args (cons n stack)))))))))

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