#lang plait
(define-type FLANG
[Num (val : Number)]
[Add (l : FLANG) (r : FLANG)]
[Sub (l : FLANG) (r : FLANG)]
[Mul (l : FLANG) (r : FLANG)]
[Div (l : FLANG) (r : FLANG)]
[Id (name : Symbol)]
[Let1 (id : Symbol) (named-expr : FLANG) (bound-body : FLANG)]
[Lam (param : Symbol) (body : FLANG)]
[Call (fun : FLANG) (val : FLANG)]) ; first type!
;; a type for substitution caches:
(define-type Binding
[bind (name : Symbol) (val : FLANG)])
(define-type-alias SubstCache (Listof Binding))
(define empty-subst empty)
;
(define (extend id expr sc)
(cons (bind id expr) sc))
;
(define (lookup name sc)
(cond
[(empty? sc)
(error 'lookup (string-append "missing binding: "
(to-string name)))]
[(eq? name (bind-name (first sc)))
(bind-val (first sc))]
[else (lookup name (rest sc))]))
(module+ test
(test/exn (lookup 'x empty) "missing")
(define env (extend 'x (Num 1) (extend 'y (Num 2) (extend 'z (Num 3) empty-subst))))
(test (lookup 'x env) (Num 1))
(test (lookup 'y env) (Num 2))
(test/exn (lookup 'a env) "missing"))