internal static GStack Make(XType[] topCombo, GStack tail) { GStackElt tos = tail.tos; for (int i = topCombo.Length - 1; i >= 0; i--) { XTypeSet xts = new XTypeSet(); xts.Add(topCombo[i]); tos = new GStackElt(tos, xts); } return(new GStack(tos)); }
internal GStackElt(GStackElt upper, XTypeSet xts) { this.upper = upper; this.xts = xts; if (upper == null) { rank = 0; } else { rank = upper.rank + 1; } }
static GStackElt MakeTOS(CCStack src) { if (src == null) { return(null); } GStackElt tos = null; GStackElt r = null; int num = 0; IEnumerator <CCTypeSet> iter = src.EnumerateFromTop(); for (;;) { if (!iter.MoveNext()) { break; } XTypeSet ss = new XTypeSet(); foreach (CCType ct in iter.Current) { ss.Add(ct.xType); } if (ss.Count == 0) { throw new Exception(string.Format("internal error: no element in CCStack at depth {0}", num)); } GStackElt r2 = new GStackElt(null, ss); if (r == null) { tos = r2; } else { r.upper = r2; } r = r2; num++; } /* * We assembled the GStack in reverse order, so all * ranks are wrong and we must fix them. */ for (r = tos; r != null; r = r.upper) { r.rank = --num; } return(tos); }
/* * Make a decision tree node. On input, all currently matching * calls are provided, up to the specified depth (excluded). * If the tree cannot be built, then null is returned. * * TODO: this can suffer from combinatorial explosion, so there * should be some safeguard here. */ static DNode MakeNode(List <DCall> calls, int depth) { /* * If all calls map to the same function, then make a leaf. */ Function f = null; bool single = true; foreach (DCall dc in calls) { if (f == null) { f = dc.f; } else if (f != dc.f) { single = false; break; } } if (single) { if (f == null) { throw new Exception("internal error: no calls at all"); } return(new DNodeLeaf(f)); } /* * There are multiple targets. We must read the next * stack element. Failure conditions: * - The bottom of one of the stacks has been reached. * - Reading on one stack yields a restricted type, * and not all stacks have that exact restricted type * at that emplacement. */ XTypeSet xtsAll = new XTypeSet(); foreach (DCall dc in calls) { if (depth >= dc.gs.Depth) { return(null); } XTypeSet xts = dc.gs.Peek(depth); if (xts.IsRestricted || xtsAll.IsRestricted) { if (!xtsAll.Equals(xts)) { return(null); } continue; } foreach (XType xt in xts) { xtsAll.Add(xt); } } /* * For all possible types at this point, get the * corresponding child subtree. For that, we must prune * the list of calls of non-matching elements. */ SortedDictionary <XType, DNode> children = new SortedDictionary <XType, DNode>(); foreach (XType xt in xtsAll) { List <DCall> calls2 = new List <DCall>(); foreach (DCall dc in calls) { if (dc.gs.Peek(depth).Contains(xt)) { calls2.Add(dc); } } children[xt] = MakeNode(calls2, depth + 1); } return(new DNodeInner(children)); }
CCTypeSet() { types = new SortedSet <CCType>(); xTypes = new XTypeSet(); cachedHashCode = Int32.MinValue; }