racket/collects/tests/eopl/chapter4/call-by-reference/data-structures.rkt
David Van Horn 7491e172ea EOPL test suite re-written in Racket-based #lang eopl and rackunit
The eopl language is now racket-based rather than mzscheme-based.  This
test-suite, which was originally distributed on the book's web-site has
been re-written in the new language.  Changes include dropping all
drscheme-init.scm and top.scm files.  Remaining files were renamed to
use the .rkt extension and edited to use the #lang syntax (instead of
modulue).  Require and provide forms were changed to reflect racket's
syntax instead of mzscheme's (eg, only-in vs. only).  Several
occurrences of one-armed ifs were changed to use when and unless.  All
tests have been run successfully.
2012-02-24 14:46:18 -05:00

117 lines
2.9 KiB
Racket
Executable File

#lang eopl
;; data structures for call-by-reference language
(require "lang.rkt") ; for expression?
(require "store.rkt") ; for reference?
(require "pairvals.rkt")
(provide (all-defined-out)) ; too many things to list
;;;;;;;;;;;;;;;; expressed values ;;;;;;;;;;;;;;;;
;;; an expressed value is either a number, a boolean, a procval, a
;;; reference, or a mutable pair.
(define-datatype expval expval?
(num-val
(value number?))
(bool-val
(boolean boolean?))
(proc-val
(proc proc?))
(ref-val
(ref reference?))
(mutpair-val
(p mutpair?))
)
;;; extractors:
(define expval->num
(lambda (v)
(cases expval v
(num-val (num) num)
(else (expval-extractor-error 'num v)))))
(define expval->bool
(lambda (v)
(cases expval v
(bool-val (bool) bool)
(else (expval-extractor-error 'bool v)))))
(define expval->proc
(lambda (v)
(cases expval v
(proc-val (proc) proc)
(else (expval-extractor-error 'proc v)))))
(define expval->ref
(lambda (v)
(cases expval v
(ref-val (ref) ref)
(else (expval-extractor-error 'reference v)))))
(define expval->mutpair
(lambda (v)
(cases expval v
(mutpair-val (ref) ref)
(else (expval-extractor-error 'mutable-pair v)))))
(define expval-extractor-error
(lambda (variant value)
(eopl:error 'expval-extractors "Looking for a ~s, found ~s"
variant value)))
;;;;;;;;;;;;;;;; procedures ;;;;;;;;;;;;;;;;
(define-datatype proc proc?
(procedure
(bvar symbol?)
(body expression?)
(env environment?)))
;;;;;;;;;;;;;;;; environment data structures ;;;;;;;;;;;;;;;;
(define-datatype environment environment?
(empty-env)
(extend-env
(bvar symbol?)
(bval reference?)
(saved-env environment?))
(extend-env-rec*
(proc-names (list-of symbol?))
(b-vars (list-of symbol?))
(proc-bodies (list-of expression?))
(saved-env environment?)))
;; env->list : Env -> List
;; used for pretty-printing and debugging
(define env->list
(lambda (env)
(cases environment env
(empty-env () '())
(extend-env (sym val saved-env)
(cons
(list sym val) ; val is a denoted value-- a
; reference.
(env->list saved-env)))
(extend-env-rec* (p-names b-vars p-bodies saved-env)
(cons
(list 'letrec p-names '...)
(env->list saved-env))))))
;; expval->printable : ExpVal -> List
;; returns a value like its argument, except procedures get cleaned
;; up with env->list
(define expval->printable
(lambda (val)
(cases expval val
(proc-val (p)
(cases proc p
(procedure (var body saved-env)
(list 'procedure var '... (env->list saved-env)))))
(else val))))