; AR ::= (make-var symbol) | (make-const integer) | (make-proc var AR) |
;        (make-app AR AR) | (make-add AR AR)

(define-struct var (name))
(define-struct const (number))
(define-struct proc (param body))
(define-struct app (rator rand))
(define-struct add (left right))

(define Eval
  (lambda (M)
    (cond
      ((var? M) (error "unbound variable ~a in program text" M))
      ((const? M) M)
      ((proc? M) M)
      ((add? M) (add-num
		  (Eval (add-left M))
		  (Eval (add-right M))))
      (else ; (app? M) ==> #t
	(Apply
	  (Eval (app-rator M))
	  (Eval (app-rand M)))))))

(define Apply
  (lambda (a-proc a-value)
    (Eval (substitute a-value ; for
	    (proc-param a-proc) ; in
	    (proc-body a-proc)))))

(define substitute
  (lambda (v x M)
    (cond ; M
      ... cases go here ...
      )))

(define (add-num const1 const2)
  (make-const (+ (const-number const1) (const-number const2))))
     
