private void SetFreeVars(CatVarScopes scopes, Stack<CatFxnType> visited) { if (visited.Contains(this)) return; foreach (CatKind k in GetDescendantKinds()) { // iterate over the values if (IsFreeVar(k, scopes)) mpFreeVars.Add(k); else if (k is CatFxnType) { visited.Push(this); (k as CatFxnType).SetFreeVars(scopes, visited); visited.Pop(); } } }
private CatVarScopes ComputeVarScopes() { CatVarScopes scopes = new CatVarScopes(); ComputeVarScopes(scopes, new Stack<CatFxnType>()); return scopes; }
private bool IsFreeVar(CatKind k, CatVarScopes scopes) { return scopes.IsFreeVar(this, k); }
/* TODO: LOWPRI: remove private CatTypeVarList GetVarsExcept(CatFxnType except) { CatTypeVarList ret = new CatTypeVarList(); GetVarsExcept(except, ret); return ret; } private void GetVarsExcept(CatFxnType except, CatTypeVarList vars) { foreach (CatKind k in GetChildKinds()) { if (k is CatFxnType) { CatFxnType ft = k as CatFxnType; if (ft != except) ft.GetVarsExcept(except, vars); } else { if (k.IsKindVar()) vars.Add(k); } } } */ /// <summary> /// Every kind variable has a scope in which it is free. /// This allows us to compute whether a variable is free or bound. /// The purpose of figuring whether a variable is free or bound, is so /// that when we copy a function, we can make sure that any free variables /// are given new unique names. Basically we want to make new names, /// but we can't always do that. /// </summary> /// <param name="scopes"></param> private void ComputeVarScopes(CatVarScopes scopes, Stack<CatFxnType> visited) { if (visited.Contains(this)) return; foreach (CatKind k in GetChildKinds()) { if (k.IsKindVar()) { scopes.Add(k, this); } else if (k is CatFxnType) { CatFxnType ft = k as CatFxnType; visited.Push(ft); ft.ComputeVarScopes(scopes, visited); visited.Pop(); } } }