When a variable appears in an expression, we first look up the identifier in the environment to find the location to which it is bound, and then we look up in the store to find the value at that location. Hence we have a “two-level” system for var-exp.
The contents of a location can be changed by a set expression. We use the syntax
Expression ::= set Identifier = Expression
**If** (value-of exp1 ρ σ0) = (val1, σ1)
**Then** (value-of (assign-exp var exp1) ρ σ0) = ([27], [ρ(var) = val1]σ1)
(define value-of
...
(var-exp (var) (deref (apply-env env var)))
...
(assign-exp (var exp1)
(begin (setref!
(apply-env env var)
(value-of exp1 env))
(num-val 27)))
...
(let-exp (var exp1 body)
(let ((val1 (value-of exp1 env)))
(value-of body (extend-env var (newref val1) env))))
...)
;; apply-procedure : Proc × ExpVal → ExpVal
(define apply-procedure
(lambda (proc1 val)
(cases proc proc1
(procedure (var body saved-env)
(value-of body (extend-env var (newref val) saved-env))))))
(define apply-env
...
(extend-env-rec (p-names b-vars p-bodies saved-env)
(let ((n (location search-var p-names)))
(if n
(newref
(proc-val (procedure (list-ref b-vars n)
(list-ref p-bodies n)
env)))
(apply-env saved-env search-var))))
...)