package interpreter; /////////////////////////////////////////////////////////////////////////////// // // Evaluation environments // /////////////////////////////////////////////////////////////////////////////// import jazz.util.*; public class Env<T> { // The universal empty environment public static empty: Env<T> {T} = new Env(alist = List.nil); // Lookup and extension of environments public lookup(name: String): CstExpr<T>; public extend(name: String, value: T): Env<T>; // Association list for the environment alist: List<(String, CstExpr<T>)>; } /////////////////////////////////////////////////////////////////////////////// // // Implementation // /////////////////////////////////////////////////////////////////////////////// // Display toString@Env() = alist.fold(" ", f1, f2) { fun f1(t) = format("%a=%a", k, v) { (k, v) = t; } fun f2(t, u) = format("%s, %s", u, f1(t)); } // Environment extension extend@Env(name, value) = new Env(alist = alist.cons((name, Expr.constant(value)))); // Environment lookup lookup@Env<T>(name) = lookup(alist) { fun lookup(list: List<(String, CstExpr<T>)>): CstExpr<T>; lookup(list@Nil) = error("undefined variable: %s\n", name); lookup(list@Cons) = (name.equals(k) ? v : v') { (k, v) = list.head; v' = lookup(list.tail); } }