The interpreter from the book is changed so that (read)
takes an argument
specifying what the result of reading would be. This is done so that tests can
be batched instead of needing user intervention.
(require racket/fixnum)
(define (interp-exp e)
(match e
[(? fixnum?) e]
[`(read ,r)
(cond [(fixnum? r) r]
[else (error 'interp-R0 "input not an integer" r)])]
[`(- ,e1) (fx- 0 (interp-exp e1))]
[`(+ ,e1 ,e2) (fx+ (interp-exp e1) (interp-exp e2))]))
(define (interp-R0 p)
(match p
[`(program ,e) (interp-exp e)]))
(define large 999999999999999999)
(interp-R0 `(program (+ (+ (+ ,large ,large) (+ ,large ,large))
(+ (+ ,large ,large) (+ ,large ,large)))))
(interp-R0 '(program (+ (read 50) (- 8))))
Result
42
(require racket/fixnum)
(define (pe-neg r)
(cond [(fixnum? r) (fx- 0 r)]
[else `(- ,r)]))
(define (pe-add r1 r2)
(cond [(and (fixnum? r1) (fixnum? r2)) (fx+ r1 r2)]
[else `(+ ,r1 ,r2)]))
(define (pe-arith e)
(match e
[(? fixnum?) e]
[`(read ,n) e]
[`(- ,(app pe-arith r1))
(pe-neg r1)]
[`(+ ,(app pe-arith r1) ,(app pe-arith r2))
(pe-add r1 r2)]))
(define (test-pe p)
(define e (pe-arith p))
(define i (interp-R0 `(program ,p)))
(define r (if (equal? i (interp-R0 `(program ,e))) "#t" "#f"))
(list p e i r))
(test-pe '(+ 13 (- 9)))
(test-pe '(+ 1 (+ 2 (+ 3 (+ 4 (+ 5 (- 5)))))))
(test-pe '(+ (read 1) 2))
(test-pe '(+ (read 1) (+ (+ 1 (+ 1 1)) (+ (read 2) (- 1)))))
expression | partial eval | result | eval eq? |
---|---|---|---|
(+ 13 (- 9)) | 4 | 4 | #t |
(+ 1 (+ 2 (+ 3 (+ 4 (+ 5 (- 5)))))) | 10 | 10 | #t |
(+ (read 1) 2) | (+ (read 1) 2) | 3 | #t |
(+ (read 1) (+ (+ 1 (+ 1 1)) (+ (read 2) (- 1)))) | (+ (read 1) (+ 3 (+ (read 2) -1))) | 5 | #t |