Código: faev2.rkt
Descarga aquí
#lang plai
(define-type FWAE
[idS (i symbol?)]
[numS (n number?)]
[binopS (f procedure?) (izq FWAE?) (der FWAE?)]
[withS (id symbol?) (val FWAE?) (body FWAE?)]
[funS (param symbol?) (body FWAE?)]
[appS (fun FWAE?) (arg FWAE?)])
(define-type FAE
[id (i symbol?)]
[num (n number?)]
[binop (f procedure?) (izq FAE?) (der FAE?)]
[fun (param symbol?) (body FAE?)]
[app (fun FAE?) (arg FAE?)])
(define (parse sexp)
(match sexp
[(? symbol?) (idS sexp)]
[(? number?) (numS sexp)]
[(list 'with (list id val) body) (withS id (parse val) (parse body))]
[(list 'fun (list param) body) (funS param (parse body))]
[(list op l r) (binopS (elige op) (parse l) (parse r))]
[else (appS (parse (car sexp)) (parse (cadr sexp)))]))
(define (elige sexp)
(match sexp
['+ +]
['- -]
['* *]
['/ /]))
(define (desugar sexp)
(match sexp
[(idS i) (id i)]
[(numS n) (num n)]
[(binopS f izq der) (binop f (desugar izq) (desugar der))]
[(withS id val body) (app (fun id (desugar body)) (desugar val))]
[(funS param body) (fun param (desugar body))]
[(appS fun arg) (app (desugar fun) (desugar arg))]))
(define (subst expr sub-id val)
(match expr
[(id i) (if (symbol=? i sub-id) val expr)]
[(num n) expr]
[(binop f izq der) (binop f (subst izq sub-id val) (subst der sub-id val))]
[(fun param body)
(if (symbol=? param sub-id)
(fun param body)
(fun param (subst body sub-id val)))]
[(app fun arg)
(app (subst fun sub-id val) (subst arg sub-id val))]))
(define (interp sexp)
(match sexp
[(id i) (error 'interp "Identificador libre")]
[(num n) sexp]
[(binop f izq der) (num (f (num-n (interp izq)) (num-n (interp der))))]
[(fun param body) sexp]
[(app fun args) (interp (subst (fun-body fun) (fun-param fun) args))]))