racket/collects/tests/eopl/chapter8/simplemodules/static-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

110 lines
3.5 KiB
Racket
Executable File

#lang eopl
(require "lang.rkt") ; for expression?, type?, etc.
(provide (all-defined-out)) ; too many things to list
(define-datatype type-environment type-environment?
(empty-tenv)
(extend-tenv
(bvar symbol?)
(bval type?)
(saved-tenv type-environment?))
(extend-tenv-with-module
(name symbol?)
(interface interface?)
(saved-tenv type-environment?))
)
;;;;;;;;;;;;;;;; procedures for looking things up tenvs ;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;; lookup or die
;; lookup-qualified-var-in-tenv : Sym * Sym * Tenv -> Type
;; Page: 285
(define lookup-qualified-var-in-tenv
(lambda (m-name var-name tenv)
(let ((iface (lookup-module-name-in-tenv tenv m-name)))
(cases interface iface
(simple-iface (decls)
(lookup-variable-name-in-decls var-name decls)) ))))
(define lookup-variable-name-in-tenv
(lambda (tenv search-sym)
(let ((maybe-answer
(variable-name->maybe-binding-in-tenv tenv search-sym)))
(if maybe-answer maybe-answer
(raise-tenv-lookup-failure-error 'variable search-sym tenv)))))
(define lookup-module-name-in-tenv
(lambda (tenv search-sym)
(let ((maybe-answer
(module-name->maybe-binding-in-tenv tenv search-sym)))
(if maybe-answer maybe-answer
(raise-tenv-lookup-failure-error 'module search-sym tenv)))))
(define apply-tenv lookup-variable-name-in-tenv)
(define raise-tenv-lookup-failure-error
(lambda (kind var tenv)
(eopl:pretty-print
(list 'tenv-lookup-failure: (list 'missing: kind var) 'in:
tenv))
(eopl:error 'lookup-variable-name-in-tenv)))
(define lookup-variable-name-in-decls
(lambda (var-name decls0)
(let loop ((decls decls0))
(cond
((null? decls)
(raise-lookup-variable-in-decls-error! var-name decls0))
((eqv? var-name (decl->name (car decls)))
(decl->type (car decls)))
(else (loop (cdr decls)))))))
(define raise-lookup-variable-in-decls-error!
(lambda (var-name decls)
(eopl:pretty-print
(list 'lookup-variable-decls-failure:
(list 'missing-variable var-name)
'in:
decls))))
;;;;;;;;;;;;;;;; lookup or return #f.
;; variable-name->maybe-binding-in-tenv : Tenv * Sym -> Maybe(Type)
(define variable-name->maybe-binding-in-tenv
(lambda (tenv search-sym)
(let recur ((tenv tenv))
(cases type-environment tenv
(empty-tenv () #f)
(extend-tenv (name ty saved-tenv)
(if (eqv? name search-sym)
ty
(recur saved-tenv)))
(else (recur (tenv->saved-tenv tenv)))))))
;; module-name->maybe-binding-in-tenv : Tenv * Sym -> Maybe(Iface)
(define module-name->maybe-binding-in-tenv
(lambda (tenv search-sym)
(let recur ((tenv tenv))
(cases type-environment tenv
(empty-tenv () #f)
(extend-tenv-with-module (name m-type saved-tenv)
(if (eqv? name search-sym)
m-type
(recur saved-tenv)))
(else (recur (tenv->saved-tenv tenv)))))))
;; assumes tenv is non-empty.
(define tenv->saved-tenv
(lambda (tenv)
(cases type-environment tenv
(empty-tenv ()
(eopl:error 'tenv->saved-tenv
"tenv->saved-tenv called on empty tenv"))
(extend-tenv (name ty saved-tenv) saved-tenv)
(extend-tenv-with-module (name m-type saved-tenv) saved-tenv)
)))