diff --git a/c2.rkt b/c2.rkt deleted file mode 100644 index bbdc2af..0000000 --- a/c2.rkt +++ /dev/null @@ -1,43 +0,0 @@ -#lang racket - -(require racket/fixnum) - -(provide interp-R1 interp-exp env-head-value env-head-symbol eval-symbol add-binding) - -(define (interp-R1 env) - (lambda (p) - (match p - [`(program ,data ,exp) ((interp-exp env) exp)]))) - -(define (interp-exp env) - (lambda (sexp) - (match sexp - [(? fixnum?) sexp] - [(? symbol?) (eval-symbol env sexp)] - [`(read) (read-fixnum)] - [`(- ,e) (fx- 0 ((interp-exp env) e))] - [`(+ ,e1 ,e2) (fx+ ((interp-exp env) e1) ((interp-exp env) e2))] - [`(let ([,var ,rexp]) ,body) - (let ([value ((interp-exp env) rexp)]) - ((interp-exp (add-binding env (list var value))) body))]))) - -(define (read-fixnum) - (let ([r (read)]) - (cond - [(fixnum? r) r] - [else (error "invalid fixnum in input: " r)]))) - -(define (env-head-symbol env) - (car (car env))) - -(define (env-head-value env) - (cadr (car env))) - -(define (add-binding env binding) - (cons binding env)) - -(define (eval-symbol env s) - (cond - [(equal? env `()) (error "Symbol " s " not found")] - [(equal? (env-head-symbol env) s) (env-head-value env)] - [else (eval-symbol (cdr env) s)])) diff --git a/rvar.rkt b/rvar.rkt new file mode 100644 index 0000000..5009dc0 --- /dev/null +++ b/rvar.rkt @@ -0,0 +1,46 @@ +#lang racket + +(require racket/fixnum) +(require racket/dict) + +(provide Int Prim Var Let Program interp-RVar-class interp-RVar) + +(struct Int (value)) +(struct Var (var)) +(struct Prim (op args)) +(struct Let (var expr body)) + +(struct Program (info body)) + +(define interp-RVar-class + (class object% + (super-new) + + (define/public ((interp-exp env) exp) + (match exp + [(Int n) n] + [(Var v) (eval-symbol env v)] + [(Prim 'read '()) (read-fixnum)] + [(Prim '- (list e)) (fx- 0 ((interp-exp env) e))] + [(Prim '+ `(,e1 ,e2)) (fx+ ((interp-exp env) e1) ((interp-exp env) e2))] + [(Let var rexp body) + (let ([value ((interp-exp env) rexp)]) + ((interp-exp (dict-set env var value)) body))])) + + (define/public (interp-program program) + (match program + [(Program _ body) ((interp-exp (make-immutable-hash)) body)])))) + +(define (read-fixnum) + (let ([r (read)]) + (cond + [(fixnum? r) r] + [else (error "invalid fixnum in input: " r)]))) + +(define (eval-symbol env s) + (if (dict-has-key? env s) + (dict-ref env s) + (error "Symbol " s " not found"))) + +(define (interp-RVar program) + (send (new interp-RVar-class) interp-program program)) diff --git a/test-c2.rkt b/test-c2.rkt deleted file mode 100644 index dd98e64..0000000 --- a/test-c2.rkt +++ /dev/null @@ -1,19 +0,0 @@ -#lang racket - -(require "test-util.rkt") -(require "c2.rkt") - -(test-eq (env-head-value `((a 1))) 1) -(test-eq (env-head-symbol `((a 1))) `a) -(test-eq (eval-symbol `((a 1)) `a) 1) -(test-eq - (let ([env `((a 1) (b 2))]) - ((interp-exp env) `(+ a (- b)))) - -1) -(test-eq - ((interp-exp `()) `(let ([a (+ 1 2)]) (+ a 3))) - 6) - -(test-eq - ((interp-R1 `()) `(program `() (let ([a (+ 1 2)]) (+ a 3)))) - 6) diff --git a/test-rvar.rkt b/test-rvar.rkt new file mode 100644 index 0000000..539ecdd --- /dev/null +++ b/test-rvar.rkt @@ -0,0 +1,39 @@ +#lang racket + +(require "test-util.rkt") +(require "rvar.rkt") + +(define (interp-exp env e) + ((send (new interp-RVar-class) interp-exp env) e)) + +(test-eq + (let ([env `((a . 1) (b . 2))]) + (interp-exp env (Var 'a))) + 1) + +(test-eq + (let ([env `((a . 1) (b . 2))]) + (interp-exp env (Prim '+ (list (Var 'a) (Int 3))))) + 4) + +(test-eq + (let ([env `((a . 1) (b . 2))]) + (interp-exp env (Prim '- `(,(Int 3))))) + -3) + +(test-eq + (let ([env `((a . 1) (b . 2))]) + (interp-exp env (Prim '+ (list (Var 'a) (Prim `- (list (Var 'b))))))) + -1) + +(test-eq + (interp-exp `() (Let 'a + (Prim '+ (list (Int 1) (Int 2))) + (Prim '+ (list (Var 'a) (Int 3))))) + 6) + +(test-eq + (interp-RVar (Program `() (Let 'a + (Prim '+ (list (Int 1) (Int 2))) + (Prim '+ (list (Var 'a) (Int 3)))))) + 6)