sclass LASScope { // do we use FixedVarContext instead of FlexibleVarContext settable bool useFixedVars; // variables declared in this scope, with type/value description gettable new Map declaredVars; // optional parent scope // (we can see the parent's variables in this scope too, unless they // are redeclared) settable LASScope parentScope; // true = we may outlive the parent scope // (e.g. when we're a lambda) settable bool parentIsDetached; // sorted names when scope is finalized (resolved) S[] names; *() {} *(LASScope *parentScope) {} bool resolved() { ret names != null; } void addDeclaredVar(S name, LASValueDescriptor type) { if (resolved()) fail("Can't add variables to resolved scope"); declaredVars.put(name, type); } int resolveVar(S name) { resolve(); int idx = indexOfInSortedArray(names, name); if (idx < 0) fail("Variable not found in scope: " + name); ret idx; } void resolve { if (names != null) ret; names = empty(declaredVars) ? null : toStringArray(sortedKeys(declaredVars)); } }