racket/collects/tests/eopl/chapter8/full-system/tests-book.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

645 lines
18 KiB
Racket
Executable File

#lang eopl
(require tests/eopl/private/utils)
(require "data-structures.rkt") ; for expval constructors
(require "lang.rkt") ; for scan&parse
(require "check-modules.rkt") ; for type-of-program
(require "interp.rkt") ; for value-of-program
;; run : String -> ExpVal
(define run
(lambda (string)
(value-of-program (scan&parse string))))
(define tcheck
(lambda (string)
(type-to-external-form
(type-of-program (scan&parse string)))))
(define parse
(lambda (string)
(scan&parse string)))
(define equal-answer?
(lambda (ans correct-ans)
(equal? ans (sloppy->expval correct-ans))))
(define sloppy->expval
(lambda (sloppy-val)
(cond
((number? sloppy-val) (num-val sloppy-val))
((boolean? sloppy-val) (bool-val sloppy-val))
(else
(eopl:error 'sloppy->expval
"Can't convert sloppy value to expval: ~s"
sloppy-val)))))
(define-syntax check-parse/type/run
(syntax-rules ()
[(check-parse/type/run (name str typ res) r ...)
(begin
(begin (check-not-exn (lambda () (parse str)))
(check equal-answer? (run str) 'res (symbol->string 'name))
(cond [(eqv? 'typ 'error)
(check-exn always? (lambda () (tcheck str)))]
[else
(check equal? (tcheck str) 'typ (symbol->string 'name))]))
(check-parse/type/run r ...))]
[(check-parse/type/run (name str typ) r ...)
(begin (check-not-exn (lambda () (parse str)))
(cond [(eqv? 'typ 'error)
(check-exn always? (lambda () (tcheck str)))]
[else
(check equal? (tcheck str) 'typ (symbol->string 'name))]))]))
;;;;;;;;;;;;;;;; tests ;;;;;;;;;;;;;;;;
(check-parse/type/run
(modules-dans-simplest "
module m1
interface
[a : int
b : int]
body
[a = 33
c = -(a,1)
b = -(c,a)]
let a = 10
in -(-(from m1 take a, from m1 take b),
a)"
int 24)
(example-8.2 "
module m1
interface
[u : bool]
body
[u = 33]
44"
error 44)
(example-8.3 "
module m1
interface
[u : int
v : int]
body
[u = 33]
44"
error)
(example-8.4 "
module m1
interface
[u : int
v : int]
body
[v = 33
u = 44]
from m1 take u"
error)
(example-8.5a "
module m1
interface
[u : int]
body
[u = 44]
module m2
interface
[v : int]
body
[v = -(from m1 take u,11)]
-(from m1 take u, from m2 take v)"
int)
(example-8.5b "
module m2
interface [v : int]
body
[v = -(from m1 take u,11)]
module m1
interface [u : int]
body [u = 44]
-(from m1 take u, from m2 take v)"
error)
(example-8.10"
module m1
interface
[transparent t = int
z : t
s : (t -> t)
is-z? : (t -> bool)]
body
[type t = int
z = 0
s = proc (x : t) -(x,-1)
is-z? = proc (x : t) zero?(x)]
let foo = proc (z : from m1 take t)
-(0, (from m1 take s
z))
in
(foo
from m1 take z)"
int -1)
(example-8.14 "
module m1
interface [transparent t = int
z : t]
body [type t = int
z = 0]
module m2
interface
[foo : (from m1 take t -> int)]
body
[foo = proc (x : from m1 take t) x]
from m2 take foo"
(int -> int))
(example-8.15 "
module m1
interface
[opaque t
z : t
s : (t -> t)
is-z? : (t -> bool)]
body
[type t = int
z = 0
s = proc (x : t) -(x,-1)
is-z? = proc (x : t) zero?(x)]
let foo = proc (z : from m1 take t)
(from m1 take s
(from m1 take s
z))
-(0, (foo
from m1 take z))"
error)
(example-8.15a "
module m1
interface
[opaque t
z : t
s : (t -> t)
is-z? : (t -> bool)]
body
[type t = int
z = 0
s = proc (x : t) -(x,-1)
is-z? = proc (x : t) zero?(x)]
let foo = proc (z : from m1 take t)
(from m1 take s
z)
in (foo
from m1 take z)"
(from m1 take t))
(example-8.8 "
module colors
interface
[opaque color
red : color
green : color
is-red? : (color -> bool)
switch-colors : (color -> color)]
body
[type color = int
red = 0
green = 1
is-red? = proc (c : color) zero?(c)
switch-colors = proc (c : color)
if (is-red? c) then green else red]
44"
int)
(example-8.9 "
module ints-1
interface [opaque t
zero : t
succ : (t -> t)
pred : (t -> t)
is-zero : (t -> bool)]
body [type t = int
zero = 0
succ = proc(x : t) -(x,-5)
pred = proc(x : t) -(x,5)
is-zero = proc (x : t) zero?(x)]
let zero = from ints-1 take zero
in let succ = from ints-1 take succ
in (succ (succ zero))"
(from ints-1 take t) 10)
(example-8.10 "
module ints-2
interface [opaque t
zero : t
succ : (t -> t)
pred : (t -> t)
is-zero : (t -> bool)]
body [type t = int
zero = 0
succ = proc(x : t) -(x,3)
pred = proc(x : t) -(x,-3)
is-zero = proc (x : t) zero?(x)]
let z = from ints-2 take zero
in let s = from ints-2 take succ
in (s (s z))"
(from ints-2 take t) -6)
(example-8.11 "
module ints-1
interface [opaque t
zero : t
succ : (t -> t)
pred : (t -> t)
is-zero : (t -> bool)]
body [type t = int
zero = 0
succ = proc(x : t) -(x,-5)
pred = proc(x : t) -(x,5)
is-zero = proc (x : t) zero?(x)]
let z = from ints-1 take zero
in let s = from ints-1 take succ
in let p = from ints-1 take pred
in let z? = from ints-1 take is-zero
in letrec int to-int (x : from ints-1 take t) =
if (z? x) then 0
else -((to-int (p x)), -1)
in (to-int (s (s z)))"
int 2)
(example-8.12 "
module ints-2
interface [opaque t
zero : t
succ : (t -> t)
pred : (t -> t)
is-zero : (t -> bool)]
body [type t = int
zero = 0
succ = proc(x : t) -(x,3)
pred = proc(x : t) -(x,-3)
is-zero = proc (x : t) zero?(x)
]
let z = from ints-2 take zero
in let s = from ints-2 take succ
in let p = from ints-2 take pred
in let z? = from ints-2 take is-zero
in letrec int to-int (x : from ints-2 take t) =
if (z? x) then 0
else -((to-int (p x)), -1)
in (to-int (s (s z)))"
int 2)
(example-8.13 "
module mybool
interface [opaque t
true : t
false : t
and : (t -> (t -> t))
not : (t -> t)
to-bool : (t -> bool)]
body [type t = int
true = 0
false = 13
and = proc (x : t)
proc (y : t)
if zero?(x)
then y
else false
not = proc (x : t)
if zero?(x)
then false
else true
to-bool = proc (x : t) zero?(x)]
let true = from mybool take true
in let false = from mybool take false
in let and = from mybool take and
in ((and true) false)"
(from mybool take t) 13)
;; (exercise-8.15 "
;; module tables
;; interface [opaque table
;; empty : table
;; add-to-table : (int -> (int -> (table -> table)))
;; lookup-in-table : (int -> (table -> int))]
;; body
;; [type table = (int -> int)
;; ... % to be filled in for exercise 8.15
;; ]
;; let empty = from tables take empty
;; in let add-binding = from tables take add-to-table
;; in let lookup = from tables take lookup-in-table
;; in let table1 = (((add-binding 3) 301)
;; (((add-binding 4) 400)
;; (((add-binding 3) 301)
;; empty)))
;; in -( ((lookup 4) table1),
;; ((lookup 3) table1))"
;; int 99)
(exercise-8.14 "
module mybool
interface [opaque t
true : t
false : t
and : (t -> (t -> t))
not : (t -> t)
to-bool : (t -> bool)]
body [type t = int
true = 1
false = 0
and = proc (x : t)
proc (y : t)
if zero?(x)
then false
else y
not = proc (x : t)
if zero?(x)
then true
else false
to-bool = proc (x : t)
if zero?(x)
then zero?(1)
else zero?(0)]
44"
int 44)
(alice-bob-and-charlie "
module Alices-point-builder
interface
((database : [opaque db-type
opaque node-type
insert-node : (node-type -> (db-type -> db-type))
])
=> [opaque point
initial-point : (int -> point)])
body
module-proc
(database : [opaque db-type
opaque node-type
insert-node : (node-type -> (db-type -> db-type))])
[type point = int
initial-point = proc (x : int) x]
module Bobs-db-module
interface
[opaque db-type
opaque node-type
insert-node : (node-type -> (db-type -> db-type))]
body
[type db-type = int
type node-type = bool
insert-node = proc (n : node-type) proc (d : db-type) d]
module Alices-points
interface
[opaque point
initial-point : (int -> point)]
body
(Alices-point-builder Bobs-db-module)
module Davids-db-module
interface
[opaque db-type
opaque node-type
insert-node : (node-type -> (db-type -> db-type))]
body
[type db-type = bool
type node-type = int
insert-node = proc (n : node-type) proc (d : db-type) d]
module Charlies-points
interface
[opaque point
initial-point : (int -> point)]
body
(Alices-point-builder Davids-db-module)
44"
int 44)
(example-8.15 "
module to-int-maker
interface
((m1 : [opaque t
zero : t
succ : (t -> t)
pred : (t -> t)
is-zero : (t -> bool)])
=> [to-int : (from m1 take t -> int)])
body
module-proc
(m1 : [opaque t
zero : t
succ : (t -> t)
pred : (t -> t)
is-zero : (t -> bool)])
[to-int
= let z? = from m1 take is-zero
in let p = from m1 take pred
in letrec int to-int (x : from m1 take t)
= if (z? x)
then 0
else -((to-int (p x)), -1)
in to-int]
module ints-1
interface [opaque t
zero : t
succ : (t -> t)
pred : (t -> t)
is-zero : (t -> bool)]
body [type t = int
zero = 0
succ = proc(x : t) -(x,-5)
pred = proc(x : t) -(x,5)
is-zero = proc (x : t) zero?(x)]
module ints-1-to-int
interface [to-int : (from ints-1 take t -> int)]
body
(to-int-maker ints-1)
let two1 = (from ints-1 take succ
(from ints-1 take succ
from ints-1 take zero))
in (from ints-1-to-int take to-int
two1)"
int 2)
(example-8.16 "
module to-int-maker
interface
((m1 : [opaque t
zero : t
succ : (t -> t)
pred : (t -> t)
is-zero : (t -> bool)])
=> [to-int : (from m1 take t -> int)])
body
module-proc
(m1 : [opaque t
zero : t
succ : (t -> t)
pred : (t -> t)
is-zero : (t -> bool)])
[to-int
= let z? = from m1 take is-zero
in let p = from m1 take pred
in letrec int to-int (x : from m1 take t)
= if (z? x)
then 0
else -((to-int (p x)), -1)
in to-int]
module ints-1
interface [opaque t
zero : t
succ : (t -> t)
pred : (t -> t)
is-zero : (t -> bool)]
body [type t = int
zero = 0
succ = proc(x : t) -(x,-5)
pred = proc(x : t) -(x,5)
is-zero = proc (x : t) zero?(x)]
module ints-2
interface [opaque t
zero : t
succ : (t -> t)
pred : (t -> t)
is-zero : (t -> bool)]
body [type t = int
zero = 0
succ = proc(x : t) -(x,3)
pred = proc(x : t) -(x,-3)
is-zero = proc (x : t) zero?(x)
]
module ints-1-to-int
interface [to-int : (from ints-1 take t -> int)]
body
(to-int-maker ints-1)
module ints-2-to-int
interface [to-int : (from ints-2 take t -> int)]
body
(to-int-maker ints-2)
let s1 = from ints-1 take succ
in let z1 = from ints-1 take zero
in let to-ints-1 = from ints-1-to-int take to-int
in let s2 = from ints-2 take succ
in let z2 = from ints-2 take zero
in let to-ints-2 = from ints-2-to-int take to-int
in let two1 = (s1 (s1 z1))
in let two2 = (s2 (s2 z2))
in -((to-ints-1 two1), (to-ints-2 two2))"
int 0)
;; (exercise-8.19 "
;; module sum-prod-maker
;; interface
;; ((m1 : [opaque t
;; zero : t
;; succ : (t -> t)
;; pred : (t -> t)
;; is-zero : (t -> bool)])
;; => [plus : (from m1 take t
;; -> (from m1 take t
;; -> from m1 take t))
;; times : (from m1 take t
;; -> (from m1 take t
;; -> from m1 take t))])
;; body
;; ... % to be filled in for exer. 8.19
;; 44"
;; int 44)
;; (exercise-8.22 "
;; module equality-maker
;; interface
;; ((m1 : [opaque t
;; zero : t
;; succ : (t -> t)
;; pred : (t -> t)
;; is-zero : (t -> bool)])
;; => [equal : (from m1 take t
;; -> (from m1 take t
;; -> bool))])
;; body
;; ...
;; 33"
;; int 33)
;; (exercise-8.19 "
;; module from-int-maker
;; interface
;; ((m1 : [opaque t
;; zero : t
;; succ : (t -> t)
;; pred : (t -> t)
;; is-zero : (t -> bool)])
;; => [from-int : (int -> from m1 take t)])
;; body
;; ...
;; 33"
;; int 33)
)
#;
(define tests-for-run
(let loop ((lst the-test-suite))
(cond
((null? lst) '())
((= (length (car lst)) 4)
;; (printf "creating item: ~s~%" (caar lst))
(cons
(list
(list-ref (car lst) 0)
(list-ref (car lst) 1)
(list-ref (car lst) 3))
(loop (cdr lst))))
(else (loop (cdr lst))))))
;; ok to have extra members in a test-item.
;;(define tests-for-check the-test-suite)
;;(define tests-for-parse the-test-suite)