(define reduce!
(lambda (expr-stack)
(cond ((equal? (top-minus expr-stack 0) 'rparen)
(let ((value (top-minus expr-stack 1)))
(pop! expr-stack) ; remove rparen
(pop! expr-stack) ; remove the value
(pop! expr-stack) ; remove lparen
(push! expr-stack value)))
(else ; a simple arithmetic operation
(let ((left-operand (top-minus expr-stack 2))
(operator (top-minus expr-stack 1))
(right-operand (top-minus expr-stack 0)))
(pop! expr-stack) ; remove right operand
(pop! expr-stack) ; remove operator
(pop! expr-stack) ; remove left operand
(push! expr-stack ((look-up-value operator)
left-operand
right-operand)))))))