Arithmetic and the Stack

Many programming languages are implemented on top of a stack-based virtual machine. Source code is compiled from an abstract syntax tree into a linear sequence of byte-code instructions. Its fast, efficient, and highly portable.

Reverse Polish Notation is highly amenable to stack-based evaluation. You simply evaluate from left to right. -(1 + 2 * 3) becomes 2 3 * 1 + -. No order of operations required.

;; Stack Based Calculator.
;; (compute-stack '(2 3 × 1 + -)) -> -7
;;
;; Side Note: Unlike reverse polish notation, upon which this
;; calculator is based, operators have variable arity, meaning
;; (compute-stack '(1 2 3 4 5 6 7 8 9 10 +)) -> 55.

(define compute-stack
  ;; === calculator environment ===
  (let ([stack '()]
        [table (list (cons '+ +)
                     (cons '- -)
                     (cons '* *)
                     (cons  *)
                     (cons '/ /)
                     (cons  /)
                     (cons '^ expt)
                     (cons '= =))]
        [lookup (lambda (var env)
                  (let ([result (assq var env)])
                    (if result
                        (cdr result)
                        (error "undefined operator:" var))))]
        [return (lambda (stack)
                  (if (= (length stack) 1)
                      (car stack)
                      (error "incomplete expression:" (reverse stack))))])
    ;; === calculator function ===
    (lambda (expression)
      (return (fold-left (lambda (x total)
                           (if (number? x)
                               (cons x total)
                               (cons (apply (lookup x table)
                                            (reverse total))
                                     stack)))
                         stack
                         expression)))))
A stack-based calculator implemented in the Scheme programming language.