// a map of assignments that can be rolled back to some state static class SNLMatches { new HashMap map; new L log; boolean put(S key, Lisp val) { if (map.containsKey(key)) // existing ret eq(map.get(key), val); // new map.put(key, val); log.add(key); ret true; } Lisp get(S key) { ret map.get(key); } S raw(S key) { Lisp x = get(key); if (x == null) fail("var not set: " + key); ret x.raw(); } boolean containsKey(S key) { ret map.containsKey(key); } int save() { ret l(log); } void restore(int i) { while (l(log) > i) { S key = log.get(l(log)-1); map.remove(key); log.remove(l(log)-1); } } boolean addAll(SNLMatches m) { for (S var : m.keySet()) if (!put(var, m.get(var))) ret false; ret true; } Set keySet() { ret map.keySet(); } }