Q1 ---------------------------------------------------------------------------- [(with) (app (fun (first (second sexp)) (parse (third sexp))) (parse (second (second sexp))))] Q2(a) ------------------------------------------------------------------------- (define-type CFAE-Value [numV (n number?)] [closureV (param symbol?) (body CFAE?) (env Env?)] [exprV (expr CFAE?) (env Env?)]) Q2(b) ------------------------------------------------------------------------- Linha Novo conteudo 5 [add (l r) (numV (+ (numV-n (strict (interp l env))) 6 (numV-n (strict ((interp r env))))] 8 (if (zero? (numV-n (strict (interp test env)))) 15 (local ([define fun-val (strict (interp fun-expr env))]) 18 (exprV arg-expr env) Q2(c) ------------------------------------------------------------------------- ;; strict : CFAE-Value -> CFAE-Value [exceto exprV] (define (strict e) (type-case CFAE-Value e [exprV (expr env) (strict (interp expr env))] [else e])) Q3 ---------------------------------------------------------------------------- Na chamada recursiva a interp nas linhas 16-19, o ambiente passado como parametro deve deixar de estender o ambiente da definicao da funcao (o qual e' capturado pelo fechamento fun-val) e passar a estender o ambiente de uso da funcao. Para isso, basta alterar a linha 19, que deixa de ser 19 (closureV-env fun-val))))])) e passa a ser 19 env)))])) Q4 ---------------------------------------------------------------------------- [set (var value) (type-case Value*Store (interp value env store) [v*s (value-value value-store) (local ([define the-loc (env-lookup var env)]) (v*s value-value (aSto the-loc value-value value-store)))])] Q5 ---------------------------------------------------------------------------- Restringiremos nossa atencao `as "chamadas mais interessantes" de interp, isto e', as chamadas que tem alguma novidade no ambiente. Em outras palavras, vamos ignorar as chamadas recursivas a interp que receberem um ambiente igual ao da execucao de interp que efetuou a chamada recursiva. Esta solucao mostra detalhes de representacao de ambientes (mtSub, aSub, aRecSub) mas esses detalhes nao sao importantes. 1. Ambiente externo (ambiente passado como parametro na chamada a interp que avalia a forma rec): (mtSub) 2. Ambiente E passado como parametro na chamada recursiva a interp que avalia o corpo da forma rec: (aRecSub 'fac (box (closureV 'n (if0 ...) E)) (mtSub)) [Aqui o importante e' que o ambiente contido no closureV e' o proprio E!] 3. Ambiente passado como parametro na chamada recursiva a interp que avalia o corpo da funcao na aplicacao {fac 2}: (aSub 'n (numV 2) (aRecSub 'fac (box (closureV 'n (if0 ...) E)) (mtSub)) Como o identificador n nao esta' vinculado a zero, a avaliacao do if0 gera a aplicacao {fac 1}. 4. Ambiente passado como parametro na chamada recursiva a interp que avalia o corpo da funcao na aplicacao {fac 1}: (aSub 'n (numV 1) (aRecSub 'fac (box (closureV 'n (if0 ...) E)) (mtSub)) Como o identificador n nao esta' vinculado a zero, a avaliacao do if0 gera uma chamada {fac 0}. 5. Ambiente passado como parametro na chamada recursiva a interp que avalia o corpo da funcao na aplicacao {fac 0}: (aSub 'n (numV 0) (aRecSub 'fac (box (closureV 'n (if0 ...) E)) (mtSub)) Agora a avaliacao do if0 produz (numV 1). A chamada a interp para {fac 0} devolve esse valor. 6. O valor de {fac 0} e' multiplicado pelo n do ambiente 4 (que tambem e' (numV 1)), produzindo (numV 1), que e' o valor devolvido pela chamada a interp para {fac 1}. 7. O (numV 1) e' multiplicado pelo n do ambiente 3 (que e' (numV 2)), produzindo (numV 2), que e' o valor devolvido pela chamada a interp para {fac 2}. 8. A primeira chamada a interp recebe o resultado da chamada recursiva que interpretou {fac 2} e o devolve como valor da forma rec.