private static void Move(Action <IEditEnumerator <Token> > mover, IEditEnumerator <Token> itr, int juxtapose) { mover(itr); if (juxtapose != 0) { // itr is pointing at the thing we ultimately want to return - we need to move off it to make sure it's juxtaposed too itr.Move(-juxtapose); // Juxtapose will delete the thing we were just on - add the result where it was itr.Add(-juxtapose, Math.MathReader.Juxtapose(Math.MathReader.Parser.CollectOperands(itr, (ProcessingOrder)juxtapose))); // Move back to where we were (which is now the juxtaposed value) itr.Move(-juxtapose); } }
public IEnumerable <T> CollectOperands(IEditEnumerator <T> itr, ProcessingOrder direction = ProcessingOrder.LeftToRight) { while (itr.Move((int)direction)) { Member member = Classify(itr.Current); // Stop if we get an operator or a bracket indicating the end of expression (which bracket depends on the processing direction) if (member == Member.Operator || (int)direction == (int)member) { break; } yield return(ParseOperand(itr)); itr.Move(-(int)direction); itr.Remove((int)direction); } }
private T Parse(IEditEnumerator <T> start, ProcessingOrder direction = ProcessingOrder.LeftToRight) { SortedDictionary <int, ProcessingOrder> order = new SortedDictionary <int, ProcessingOrder>(); IEditEnumerator <T> end = start.Copy(); int count = 0; #if DEBUG string parsing = ""; while (end.Move((int)direction)) { if (direction == ProcessingOrder.LeftToRight) { parsing += end.Current + "|"; } else { parsing = end.Current + "|" + parsing; } } Print.Log("parsing section |" + parsing); Print.Log("start is " + start.Current + " and end is " + end.Current); end = start.Copy(); #endif // Initial pass over the input to figure out: // Where the beginning and end are (match parentheses) // What operators we should look for (so we can skip iterating empty tiers) // Also delete anything that's supposed to be ignored while (end.Move((int)direction)) { if (!(end.Current is T)) { continue; } T current = (T)end.Current; Member member = Classify(current); // This is the "close" bracket for the direction we're moving if ((int)direction == (int)member) { // This is the end of the expression we're working on if (count == 0) { break; } else { count--; } } // This is the "open" bracket for the direction we're moving else if ((int)direction == -(int)member) { count++; } else if (Ignore.Contains(current)) { end.Move(-1); end.Remove(1); } // Keep track of what operators we find so we can skip them later else if (member == Member.Operator) { Tuple <Operator <T>, int> temp = Operations[current]; order[temp.Item2] = temp.Item1.Order; } } foreach (KeyValuePair <int, ProcessingOrder> kvp in order) { IEditEnumerator <T> itr = kvp.Value == ProcessingOrder.LeftToRight ^ direction == ProcessingOrder.LeftToRight ? end.Copy() : start.Copy(); while (itr.Move((int)kvp.Value) && !itr.Equals(start) && !itr.Equals(end)) { if (!(itr.Current is T)) { continue; } Tuple <Operator <T>, int> tuple; if (Operations.TryGetValue((T)itr.Current, out tuple) && kvp.Key == tuple.Item2) { Print.Log("doing operation", itr.Current); Operator <T> operation = tuple.Item1; IEditEnumerator <T>[] operandItrs = new IEditEnumerator <T> [operation.Targets.Length]; for (int j = 0; j < operation.Targets.Length; j++) { //operation.Targets[j](operandItrs[j] = itr.Copy()); } T[] operands = new T[operandItrs.Length]; for (int j = 0; j < operandItrs.Length; j++) { Print.Log("\t" + operandItrs[j].Current); operands[j] = ParseOperand(operandItrs[j]); operandItrs[j].Remove(0); } itr.Add(0, operation.Operate(operands)); } } } #if DEBUG Print.Log("done"); IEditEnumerator <T> printer = start.Copy(); while (printer.MoveNext()) { Print.Log("\t" + printer.Current); } #endif IEditEnumerator <T> juxtapose = start.Copy(); T result = Juxtapose(CollectOperands(juxtapose, direction)); juxtapose.Remove(0); return(result); }