// Returns the current stack *if* it can be inferred down to single types *and* is either based or verifiable to the given depth public LinqStack <TypeOnStack> InferStack(int ofDepth) { var res = CollapseAndVerify(); if (res.Stack.Count < ofDepth) { return(null); } var ret = new LinqStack <TypeOnStack>(); for (var i = ofDepth - 1; i >= 0; i--) { var couldBe = res.Stack.ElementAt(i); if (couldBe.Count() > 1) { return(null); } ret.Push(couldBe.Single()); } return(ret); }
private LinqStack <LinqList <TypeOnStack> > CopyStack(LinqStack <LinqList <TypeOnStack> > toCopy) { var ret = new LinqStack <LinqList <TypeOnStack> >(toCopy.Count); for (var i = toCopy.Count - 1; i >= 0; i--) { ret.Push(toCopy.ElementAt(i)); } return(ret); }
private static void UpdateStack(LinqStack <LinqList <TypeOnStack> > stack, InstructionAndTransitions wrapped, bool isBaseless) { var legal = wrapped.Transitions; var instr = wrapped.Instruction; var legalSize = 0; legal.Each( t => { legalSize += t.PushedToStack.Length; if (t.Before != null) { t.Before(stack, isBaseless); } } ); if (legal.Any(l => LinqAlternative.Any(l.PoppedFromStack, u => u == TypeOnStack.Get <PopAllType>()))) { if (instr.HasValue) { for (var i = 0; i < stack.Count; i++) { var ix = stack.Count - i - 1; stack.ElementAt(i).Each(y => y.Mark(wrapped, ix)); } } stack.Clear(); } else { var toPop = legal.First().PoppedCount; for (var j = 0; j < toPop && stack.Count > 0; j++) { var popped = stack.Pop(); if (instr.HasValue) { var ix = toPop - j - 1; popped.Each(y => y.Mark(wrapped, ix)); } } } var toPush = new LinqList <TypeOnStack>(legalSize); var pushed = new LinqHashSet <TypeOnStack>(); for (var i = 0; i < legal.Count; i++) { foreach (var p in legal[i].PushedToStack) { if (pushed.Contains(p)) { continue; } toPush.Add(p); pushed.Add(p); } } if (toPush.Count > 0) { stack.Push(toPush); } }