#lang plai ;; (calc (parse '{with {x {+ 5 5}} {+ x x}}) ) ;; (calc (parse '{with {x 5} {with {y x} y}}) ) ;; (test (calc (parse ’{with {x 5} {with {x x} x}})) 5) (define-type WAE [num (n number?)] [add (lhs WAE?) (rhs WAE?)] [sub (lhs WAE?) (rhs WAE?)] [with (name symbol?) (named-expr WAE?) (body WAE?)] [id (name symbol?)]) ;; newer parse (define parse (lambda (sexp) (cond [(number? sexp) (num sexp)] [(symbol? sexp) (id sexp)] [(list? sexp) (case (first sexp) [(+)(add (parse (second sexp)) (parse (third sexp)))] [(-) (sub (parse (second sexp)) (parse (third sexp)))] [(with) (with (first (second sexp)) (parse (second (second sexp))) (parse (third sexp)))] )]))) (define (subst expr sub-id val) (type-case WAE expr [num (n) expr] [add (l r) (add (subst l sub-id val) (subst r sub-id val))] [sub (l r) (sub (subst l sub-id val) (subst r sub-id val))] [with (bound-id named-expr bound-body) (if (symbol=? bound-id sub-id) expr (with bound-id (subst named-expr sub-id val) (subst bound-body sub-id val)))] [id (v) (if (symbol=? v sub-id) val expr)]))