interp
recursivo
Descarga aquí
#lang plai
(define-type RCFAE-Value
[numV (n number?)]
[closureV (param symbol?)
(body RCFAE?)
(env Env?)])
(define (boxed-RCFAE-Value? v)
(and (box? v)
(RCFAE-Value? (unbox v))))
(define-type Env
[mtSub]
[aSub (name symbol?)
(value RCFAE-Value?)
(env Env?)]
[aRecSub (name symbol?)
(value boxed-RCFAE-Value?)
(env Env?)])
;; lookup : symbol env → RCFAE-Value
(define (lookup name env)
(type-case Env env
[ mtSub () (error ’ lookup ”no binding for identifier” )]
[ aSub (bound-name bound-value rest-env)
(if (symbol=? bound-name name)
bound-value
(lookup name rest-env))]
[ aRecSub (bound-name boxed-bound-value rest-env)
(if (symbol=? bound-name name)
(unbox boxed-bound-value)
(lookup name rest-env))]))
;; cyclically-bind-and-interp : symbol RCFAE env → env
(define (cyclically-bind-and-interp bound-id named-expr env)
(local ([define value-holder (box (numV 1729))]
[define new-env (aRecSub bound-id value-holder env)]
[define named-expr-val (interp named-expr new-env)])
(begin
(set-box! value-holder named-expr-val)
new-env)))
;; interp : RCFAE env → RCFAE-Value
(define (interp expr env)
(type-case RCFAE expr
[num (n) (numV n)]
[add (l r) (num+ (interp l env) (interp r env))]
[mult (l r) (num∗ (interp l env) (interp r env))]
[if0 (test truth falsity)
(if (num-zero? (interp test env))
(interp truth env)
(interp falsity env))]
[id (v) (lookup v env)]
[fun (bound-id bound-body)
(closureV bound-id bound-body env)]
[app (fun-expr arg-expr)
(local ([define fun-val (interp fun-expr env)])
(interp (closureV-body fun-val)
(aSub (closureV-param fun-val)
(interp arg-expr env)
(closureV-env fun-val))))]
[rec (bound-id named-expr bound-body)
(interp bound-body
(cyclically-bind-and-interp bound-id
named-expr
env))]))