Port c2 to rvar

This commit is contained in:
Enrico Lumetti 2021-10-21 13:15:37 +02:00
parent bad45de00a
commit 7b8ea0b6f4
4 changed files with 85 additions and 62 deletions

43
c2.rkt
View File

@ -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)]))

46
rvar.rkt Normal file
View File

@ -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))

View File

@ -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)

39
test-rvar.rkt Normal file
View File

@ -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)