#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!
(define-type ENV
[EmptyEnv]
[Extend (name : Symbol) (val : VAL) (rest : ENV)])
(define-type VAL
[NumV (n : Number)]
[FunV (arg : Symbol) (body : FLANG) (env : ENV)])
(module+ test
(test/exn (lookup 'x (EmptyEnv)) "no binding")
(test/exn (lookup 'y (Extend 'x (NumV 1) (EmptyEnv))) "no binding")
(test (lookup 'y (Extend 'y (NumV 1) (EmptyEnv))) (NumV 1)))
(define (lookup name env)
(type-case ENV env
[(EmptyEnv) (error 'lookup "no binding")]
[(Extend id val rest-env)
(if (eq? id name)
val
(lookup name rest-env))]))