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);
}
}