In store-based language, any expression may have an effect. To specify these effects, we need to describe what store should be used for each evaluation and how each evaluation can modify the store.
σ to range over stores. We write [*l* = *v*]σ to mean a store just like σ, except that location *l* is mapped to *v*. When we refer to a particular value of σ, we sometimes call it the state of the store.In a store-passing specification, the store is passed as an explicit argument to value-of and is returned as an explicit result from value-of. Thus we write (value-of exp1 ρ σ0) = (val1,σ1). This asserts that expression *exp*1, evaluated in environment ρ and with the store in state σ0, returns the value *val*1 and leaves the store in a possibly different state σ1.
Thus we can specify an effect-free operation like const-exp by writing (value-of (const-exp *n*) ρ σ) = (*n*,σ) showing that the store is unchanged by evaluation of this expression.
We represent the state of the store as a Scheme value, but we do not explicitly pass and return it, as the specification suggests. Instead, we keep the state in a single global variable, to which all the procedures of the implementation have access.
;; the-store
(define the-store ’uninitialized)
;; empty-store : () → Sto
(define empty-store (lambda () ’()))
;; get-store : () → Sto
(define get-store (lambda () the-store))
;; initialize-store! : () → Unspecified
(define initialize-store! (lambda () (set! the-store (empty-store))))
;; reference? : SchemeVal → Bool
(define reference? (lambda (v) (integer? v)))
;; newref : ExpVal → Ref
(define newref
(lambda (val)
(let ((next-ref (length the-store)))
(set! the-store (append the-store (list val))) next-ref)))
;; deref : Ref → ExpVal
(define deref (lambda (ref) (list-ref the-store ref)))
;; setref! : Ref x ExpVal → Unspecified
(define setref!
(lambda (ref val)
(set! the-store
(letrec ((setref-inner
(lambda (store1 ref1)
(cond ((null? store1) (report-invalid-reference ref the-store))
((zero? ref1) (cons val (cdr store1)))
(else (cons (car store1) (setref-inner (cdr store1) (- ref1 1))))))))
(setref-inner the-store ref)))))