whalesong/test-compiler.rkt
2011-03-07 21:51:55 -05:00

163 lines
3.5 KiB
Racket

#lang racket
(require "simulator.rkt"
"simulator-structs.rkt"
"compile.rkt"
"parse.rkt")
(define (run-compiler code)
(compile (parse code) 'val 'next))
;; Test out the compiler, using the simulator.
(define-syntax (test stx)
(syntax-case stx ()
[(_ code exp)
(with-syntax ([stx stx])
(syntax/loc #'stx
(begin
(printf "Running ~s...\n" 'code)
(let*-values([(a-machine num-steps)
(run (new-machine (run-compiler 'code)))]
[(actual) (machine-val a-machine)])
(unless (equal? actual exp)
(raise-syntax-error #f (format "Expected ~s, got ~s" exp actual)
#'stx))
(printf "ok. ~s steps\n\n" num-steps)))))]))
;; test, and expect an error
(define-syntax (test/exn stx)
(syntax-case stx ()
[(_ code)
(with-syntax ([stx stx])
(syntax/loc #'stx
(begin
(printf "Running/exn ~s ...\n" 'code)
(let/ec return
(with-handlers ([exn:fail? (lambda (exn)
(printf "ok\n\n")
(return))])
(run (new-machine (run-compiler 'code))))
(raise-syntax-error #f (format "Expected an exception")
#'stx)))))]))
;; run: machine -> (machine number)
;; Run the machine to completion.
(define (run m)
(let loop ([m m]
[steps 0])
(cond
[(can-step? m)
(loop (step m) (add1 steps))]
[else
(values m steps)])))
;; Atomic expressions
(test 42 42)
(test "hello world" "hello world")
(test #t true)
(test #f false)
;; quoted
(test '(+ 3 4)
'(+ 3 4))
;; Simple definitions
(test (begin (define x 42)
(+ x x))
84)
(test (begin (define x 6)
(define y 7)
(define z 8)
(* x y z))
(* 6 7 8))
;; Simple branching
(test (if #t 'ok 'not-ok)
'ok)
(test (if #f 'not-ok 'ok)
'ok)
;; Sequencing
(test (begin 1
2
3)
3)
(test (begin 1)
1)
;; Simple application
(test ((lambda (x) x) 42)
42)
(test ((lambda (x)
(begin (* x x))) 42)
1764)
(test ((lambda (x y z) x) 3 4 5)
3)
(test ((lambda (x y z) y) 3 4 5)
4)
(test ((lambda (x y z) z) 3 4 5)
5)
;; We should see an error here, since the arity is wrong
(test/exn ((lambda (x y z) x) 3))
(test/exn ((lambda (x y z) z) 3))
(test/exn ((lambda (x y z) x) 3 4 5 6))
;; And this should fail because it's not a lambda
(test/exn (not-a-procedure 5))
;; Square
(test (begin (define (f x)
(* x x))
(f 3))
9)
;; composition of square
(test (begin (define (f x)
(* x x))
(f (f 3)))
81)
; factorial
(test (begin (define (f x)
(if (= x 0)
1
(* f (sub1 x))))
(f 0))
1)
(test (begin (define (f x)
(if (= x 0)
1
(* f (sub1 x))))
(f 1))
1)
(test (begin (define (f x)
(if (= x 0)
1
(* f (sub1 x))))
(f 2))
2)
(test (begin (define (f x)
(if (= x 0)
1
(* f (sub1 x))))
(f 3))
6)
;(simulate (compile (parse '42) 'val 'next))
;(compile (parse '(+ 3 4)) 'val 'next)