Esempio n. 1
0
        /*private IEnumerable<TInput> Next(IEnumerable<TInput> input)
         * {
         *  foreach(TInput t in input)
         *  {
         *      if (!Ignore.Contains(t))
         *      {
         *          yield return t;
         *      }
         *  }
         * }*/

        private TOutput Close(Evaluator quantity)
        {
            for (int j = 0; j < quantity.Operations.Length; j++)
            {
                LinkedList <LinkedListNode <object> > stack = quantity.Operations[j];

                while (stack?.Count > 0)
                {
                    LinkedListNode <object> node = stack.Dequeue().Value;
                    Operator <TOutput>      op   = quantity.Operators[j].Dequeue().Value;

                    // Operator was removed by someone else
                    if (node.List == null)
                    {
                        continue;
                    }
                    //Operator<TOutput> op = (Operator<TOutput>)node.Value;

                    IEditEnumerator <object>[] operandNodes = new IEditEnumerator <object> [op.Targets.Length];

                    for (int k = 0; k < op.Targets.Length; k++)
                    {
                        operandNodes[k] = new Parse.Collections.Generic.LinkedList <object> .Enumerator(node);

                        //op.Targets[k](operandNodes[k]);
                    }

                    TOutput[] operands = new TOutput[operandNodes.Length];
                    for (int k = 0; k < operands.Length; k++)
                    {
                        operands[k] = (TOutput)operandNodes[k].Current;
                        operandNodes[k].Remove(0);
                    }

                    Print.Log("operating", op.GetType(), operands.Length);
                    foreach (object o in operands)
                    {
                        Print.Log(o, o.GetType());
                    }
                    Print.Log("done");

                    node.Value = op.Operate(operands);
                }
            }

            if (quantity.Input.Count == 0)
            {
                throw new Exception();
            }

            //IOrdered<object> itr = new LinkedListBiEnumerator<object>(input);
            //itr.MoveNext();
            //Other.LinkedList<object> list = input;
            return(Juxtapose(quantity.Input.GetEnumerator()));
        }
Esempio n. 2
0
        public T ParseOperand(IEditEnumerator <T> itr)
        {
            Member member = Classify(itr.Current);

            if (member == Member.Opening || member == Member.Closing)
            {
                itr.Add(0, Parse(itr, (ProcessingOrder)(-(int)member)));
            }

            return(itr.Current);
        }
Esempio n. 3
0
            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);
                }
            }
Esempio n. 4
0
            public static void Next(IEditEnumerator <Token> itr)
            {
                // Is the next thing a minus sign?
                if (itr.MoveNext() && IsString(itr.Current, "-"))
                {
                    // Move off the negative sign (to the thing after)
                    itr.MoveNext();
                    // Delete the negative sign
                    itr.Remove(-1);

                    // Negate the value after
                    Operand next = (Operand)Math.MathReader.Parser.ParseOperand(itr).Value;
                    next.Multiply(-1);
                    // Replace with the negated value
                    itr.Add(0, new Token.Operand <Operand>(next));
                }
            }
Esempio n. 5
0
        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);
            }
        }
Esempio n. 6
0
 public static void Prev(IEditEnumerator itr) => itr.MovePrev();
Esempio n. 7
0
        public TOutput Parse(IEditEnumerable <TInput> input)
        {
            string parsing = "parsing |";

            foreach (TInput s in input)
            {
                parsing += s + "|";
            }
            Print.Log(parsing);

            Stack <Evaluator> quantities = new Stack <Evaluator>();

            IEditEnumerator <TInput> itr = input.GetEnumerator();

            quantities.Push(new Evaluator(new Parse.Collections.Generic.LinkedList <object>(), new LinkedList <LinkedListNode <object> > [Count], new LinkedList <Operator <TOutput> > [Count]));

            while (true)
            {
                Evaluator quantity = quantities.Peek();

                bool done = !itr.MoveNext();

                if (done || Closing.Contains(itr.Current))
                {
                    Evaluator e = quantities.Pop();
                    Print.Log("close", e.Input.Count);
                    LinkedListNode <object> a = e.Input.First;
                    while (a != null)
                    {
                        Print.Log(a.Value, a.Value?.GetType());
                        a = a.Next;
                    }
                    Print.Log("\n");

                    TOutput answer = Close(e);

                    if (quantities.Count == 0)
                    {
                        if (done)
                        {
                            return(answer);
                        }
                        else
                        {
                            Parse.Collections.Generic.LinkedList <object> front = new Parse.Collections.Generic.LinkedList <object>();
                            front.AddFirst(answer);
                            quantities.Push(new Evaluator(front, new LinkedList <LinkedListNode <object> > [Count], new LinkedList <Operator <TOutput> > [Count]));
                        }
                    }
                    else
                    {
                        quantities.Peek().Input.AddLast(answer);
                    }
                }
                else if (Opening.Contains(itr.Current))
                {
                    Print.Log("open");
                    quantities.Push(new Evaluator(new Parse.Collections.Generic.LinkedList <object>(), new LinkedList <LinkedListNode <object> > [Count], new LinkedList <Operator <TOutput> > [Count]));
                }
                else
                {
                    Operator <TOutput> operation;
                    if (Operations.TryGetValue(itr.Current, out operation))
                    {
                        Print.Log("found operator", itr.Current);

                        int index = IndexOf(itr.Current);

                        // Put the operator in the linked list as a node
                        LinkedListNode <object> node = new LinkedListNode <object>(itr.Current);

                        // Get the list of all of this type of operator (e.g. all instances of "+")
                        if (quantity.Operations[index] == null)
                        {
                            quantity.Operations[index] = new LinkedList <LinkedListNode <object> >();
                            quantity.Operators[index]  = new LinkedList <Operator <TOutput> >();
                        }

                        if (operation.Order == ProcessingOrder.RightToLeft)
                        {
                            quantity.Operations[index].AddFirst(node);
                            quantity.Operators[index].AddFirst(operation);
                        }
                        else
                        {
                            quantity.Operations[index].AddLast(node);
                            quantity.Operators[index].AddLast(operation);
                        }

                        quantity.Input.AddLast(node);
                    }
                    else
                    {
                        Print.Log("found operand", itr.Current);

                        foreach (TOutput o in ParseOperand(itr.Current))
                        {
                            Print.Log("\t" + o);
                            quantity.Input.AddLast(o);
                        }
                    }
                }
            }
        }
Esempio n. 8
0
 protected virtual TOutput Juxtapose(IEditEnumerator <object> expression) => throw new Exception();
Esempio n. 9
0
        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);
        }