#lang racket (provide (all-defined-out)) (require eopl) (require racket/contract) (require racket/match) (require rackunit) (require "ast.rkt") (define-datatype proc proc? [prim-proc ;; prim refers to a racket procedure (prim procedure?) ;; sig is the signature, a list of type predicates (sig (list-of procedure?))] [closure (formals (list-of symbol?)) (body ast?) (env env?)] [continuation-proc (kont procedure?)]) (define prim-proc? (lambda (p) (cases proc p [prim-proc (prim sig) #t] [else #f]))) (define closure? (lambda (p) (cases proc p [closure (formals body env) #t] [else #f]))) (define continuation-proc? (lambda (p) (cases proc p [continuation-proc (kont) #t] [else #f]))) (define-datatype env env? [empty-env] [extended-env (syms (list-of symbol?)) (vals (list-of any/c)) (outer-env env?)] [extended-rec-env (fsyms (list-of symbol?)) (lformals (list-of (list-of symbol?))) (bodies (list-of ast?)) (outer-env env?)]) (define *empty-env* (empty-env)) (define *top-env* (extended-env '(x y z) '(2 4 6) *empty-env*)) ;;; lookup-env/k: ;;; [env? symbol? (K any/c) (K)] -> (define lookup-env/k (lambda (e x succ fail) (cases env e [empty-env () (fail)] [extended-env (syms vals outer-env) (list-index/k syms x (lambda (j) (succ (list-ref vals j))) (lambda () (lookup-env/k outer-env x succ fail)))] [extended-rec-env (fsyms lformals bodies outer-env) (list-index/k fsyms x (lambda (j) (let ([formals (list-ref lformals j)] [body (list-ref bodies j)]) (succ (closure formals body e)))) ;; builds closure (lambda () (lookup-env/k outer-env x succ fail)))]))) (define list-index/k (lambda (ls a succ fail) (letrec ([loop (lambda (ls ans) (cond [(null? ls) (fail)] [(eq? (first ls) a) (succ ans)] [#t (loop (rest ls) (+ 1 ans))]))]) (loop ls 0))))