UNB/ CS/ David Bremner/ teaching/ cs4613/ lectures/ lecture8/ snippet-003.rkt
#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"))