(define (apply operator operands)
(cond ((primitive? operator)
(scheme-apply (get-scheme-procedure operator)
(extend-env-with-new-frame
(error "operator not a procedure: " operator))))
(define (extend-env-with-new-frame names values env)
(let ((new-frame (make-table)))
(make-bindings! names values new-frame)
(cons new-frame env))) ; 注意:这里 new-frame 在 env 之前,体现 lookup 顺序
(define (make-bindings names values table)
(lambda (name value) (table-put! table name value))
; the initial global environment
(extend-env-with-new-frame
(list 'true* 'plus* 'greater*)
(list #t (make-primitive +) (make-primitive >))
; lookup searches the list of frames for the first match
(define (lookup name env)
(error "unbound variable: " name)
(let ((binding (table-get (car env) name)))
(binding-value binding)))))
; define changes the first frame in the environment
(define (eval-define exp env)
(defined-to-be (caddr exp)))
(table-put! (car env) name (eval defined-to-be env))