예제 #1
0
        private NovelExpression UnfoldArguments(NovelExpression expression, ref List <NovelInstruction> instructions)
        {
            //Get the term
            var term = expression.Term;

            for (int i = 0; i < term.Count; i++)
            {
                int functionEndIndex = -1;
                int functionElements = 2;
                //Look for function start operator
                if (term[i] is NovelFunctionStartOperator && term[i - 1] is NovelExpressionFunctionCall)
                {
                    //Check if inside function are only comma characters
                    bool onlyCommas = true;
                    for (int j = i + 1; j < term.Count; j++)
                    {
                        var test = term[j];
                        functionElements++;

                        //Read until novel function end
                        if (term[j] is NovelFunctionEndOperator)
                        {
                            functionEndIndex = j;
                            break;
                        }

                        //If its an operator
                        if (term[j] is NovelExpressionOperator)
                        {
                            //If its different than comma
                            if (!(term[j] is NovelCommaOperator))
                            {
                                onlyCommas = false;
                                break;
                            }
                        }
                    }

                    if (onlyCommas)
                    {
                        //Fill function with arguments
                        var function = term[i - 1] as NovelExpressionFunctionCall;
                        for (int j = i; j < functionEndIndex; j++)
                        {
                            if (term[j] is NovelExpressionOperand)
                            {
                                function.Arguments.Add(term[j] as NovelExpressionOperand);
                            }
                        }
                        //TODO
                        //here i have number of arguments in function
                        //so i can check if its the right number
                        int newIndex = ParsedScript.DelegateFunctionList.
                                       ContainsFunction(function.Name, function.Arguments.Count);

                        //If found new delegated function
                        if (newIndex > -1)
                        {
                            function.Offset = newIndex;
                        }
                        else
                        {
                            throw new NovelException("Could not find delegated method "
                                                     + function.Name + " with " + function.Arguments.Count() +
                                                     " arguments.", "", 0);
                        }

                        //Now create new expression
                        var lastStackOperator = Variables.GetStackVariables();
                        var temporaryVariable = new NovelExpressionVariable("temp_" + lastStackOperator, lastStackOperator);
                        Variables.AddVaraible(temporaryVariable.Name);

                        //instructions.Add(new NovelExpandStack(1));
                        var newExpression = new NovelExpression();
                        //newExpression.Term.Add(temporaryVariable);
                        newExpression.Term.Add(function);
                        //newExpression.Term.Add(new NovelAssignOperator());
                        instructions.Add(newExpression);

                        //Remove from expression
                        for (int j = 0; j < functionElements; j++)
                        {
                            expression.Term.RemoveAt(i - 1);
                        }

                        if (expression.Term.Count > 0)
                        {
                            expression.Term.Insert(i - 1, temporaryVariable);
                        }

                        i -= 1;
                    }
                }
            }
            return(expression);
        }
예제 #2
0
        public List <NovelInstruction> ParseExpression(string text)
        {
            //Trim the expression
            text = text.Trim();

            //Create empty expression object
            NovelExpression novelExpression = new NovelExpression();

            //Declare instructions
            List <NovelInstruction> instructions = new List <NovelInstruction>();

            //For RPN algorithm purpose
            string output = "";
            string buffer = "";

            for (int i = 0; i < text.Length; i++)
            {
                //Check if the i is pointing at operator name
                var operatorIndex = IsOperator(text, i);

                //operatorIndex = -1 means that its regular character
                if (operatorIndex >= 0)
                {
                    //Build expression here based on whats in buffer
                    if (!buffer.Equals(""))
                    {
                        if (IsDeclaredVariable(buffer))
                        {
                            buffer = buffer.Substring(3);

                            if (!Variables.ContainsVariable(buffer))
                            {
                                instructions.Add(new NovelExpandStack(1));
                                Variables.AddVaraible(buffer);
                            }
                            //TODO functions name
                            else
                            {
                                throw new NovelException("Variable or function name " + buffer + " already exists.", ParsedFile, ParsedLine);
                            }
                        }

                        //Handle the operands
                        novelExpression = HandleOperand(novelExpression, buffer);

                        //Push variable to the output
                        output += buffer;
                        buffer  = "";
                    }

                    //Get the new operator
                    var op = Operators[operatorIndex];

                    //Parentheses close operator
                    if (op is NovelCloseCurvedParenthesesOperator)
                    {
                        //Pop all operators till (
                        while (OperatorStack.Count() > 0)
                        {
                            var opFromStack = OperatorStack.Pop();
                            if (opFromStack is NovelOpenCurvedParenthesesOperator)
                            {
                                var parentheses = parenthesesType.Pop();

                                if (parentheses == ParenthesesType.Function)
                                {
                                    novelExpression.Term.Add(new NovelFunctionEndOperator());
                                }

                                break;
                            }
                            else
                            {
                                if (!(opFromStack is NovelOpenCurvedParenthesesOperator ||
                                      opFromStack is NovelCloseCurvedParenthesesOperator))
                                {
                                    novelExpression.Term.Add(opFromStack);
                                }
                            }
                        }
                    }
                    //If every other operator
                    else
                    {
                        //Iteratore over OperatorStack
                        while (OperatorStack.Count() > 0)
                        {
                            //If priority of new operator is lower or equal pop stack operators
                            //
                            if (op.GetPriority() <= OperatorStack.First().GetPriority() &&
                                !(op is NovelOpenCurvedParenthesesOperator))
                            {
                                var opFromStack = OperatorStack.Pop();

                                if (!(opFromStack is NovelOpenCurvedParenthesesOperator ||
                                      opFromStack is NovelCloseCurvedParenthesesOperator))
                                {
                                    novelExpression.Term.Add(opFromStack);
                                }
                            }
                            else
                            {
                                break;
                            }
                        }
                    }

                    //Now put the operator on the stack if not close curved
                    if (!(op is NovelCloseCurvedParenthesesOperator))
                    {
                        //If previous term part was function call
                        if (novelExpression.Term.Count >= 1 &&
                            op is NovelOpenCurvedParenthesesOperator &&
                            novelExpression.Term[novelExpression.Term.Count - 1] is NovelExpressionFunctionCall)
                        {
                            parenthesesType.Push(ParenthesesType.Function);
                            novelExpression.Term.Add(new NovelFunctionStartOperator());
                        }
                        //If normal paretheses
                        else if (op is NovelOpenCurvedParenthesesOperator)
                        {
                            parenthesesType.Push(ParenthesesType.Normal);
                        }

                        OperatorStack.Push(op);
                    }

                    //Move pointer by a length of operator
                    i += op.GetName().Length - 1;
                }
                //If its not an operator
                else
                {
                    if (text[i].Equals(' '))
                    {
                        continue;
                    }
                    else if (text[i].Equals('\t'))
                    {
                        continue;
                    }
                    else if (text[i].Equals('\r'))
                    {
                        continue;
                    }
                    else if (text[i].Equals('\n'))
                    {
                        continue;
                    }

                    //If its a quote
                    if (text[i].Equals('\"'))
                    {
                        int len = text.IndexOf('\"', i + 1) - i + 1;
                        buffer += text.Substring(i, len);
                        i      += len - 1;
                    }
                    //If its not add single character
                    else
                    {
                        buffer += text[i];
                    }
                }
            }

            //Empty buffer first
            if (!buffer.Equals(""))
            {
                novelExpression = HandleOperand(novelExpression, buffer);
            }

            //Empty operator stack
            while (OperatorStack.Count() > 0)
            {
                var opFromStack = OperatorStack.Pop();
                if (!(opFromStack is NovelOpenCurvedParenthesesOperator ||
                      opFromStack is NovelCloseCurvedParenthesesOperator))
                {
                    novelExpression.Term.Add(opFromStack);
                }
            }

            Variables.AddScope();
            int reservedVariables = Variables.GetStackVariables();

            while (novelExpression.Term.Count > 0)
            {
                novelExpression = UnfoldOperations(novelExpression, ref instructions);
                novelExpression = UnfoldArguments(novelExpression, ref instructions);
                //For single variables or literals
                if (novelExpression.Term.Count == 1)
                {
                    var newExpression = new NovelExpression();
                    newExpression.Term.Add(novelExpression.Term[0]);
                    instructions.Add(newExpression);
                    novelExpression.Term.Clear();
                }
            }

            //How many of temporary variables expression has
            reservedVariables = Variables.GetStackVariables() - reservedVariables;

            //Shrink stack to remove them
            if (reservedVariables > 0)
            {
                instructions.Add(new NovelExpandStack(-reservedVariables));
            }

            Variables.RemoveScope();

            foreach (var instruction in instructions)
            {
                string buff = "";
                buff += " " + instruction;
                Console.WriteLine(buff);
            }
            Console.WriteLine("");

            return(instructions);
        }
예제 #3
0
        private NovelExpression UnfoldOperations(NovelExpression expression, ref List <NovelInstruction> instructions)
        {
            //Get the term
            var term = expression.Term;

            //Look for
            for (int i = 0; i < term.Count; i++)
            {
                var part = term[i];
                //Look for operator different
                //comma
                //fnc start
                //fnc end
                //fnc call
                if (part is NovelExpressionOperator)
                {
                    if (!(part is NovelExpressionFunctionCall) &&
                        !(part is NovelCommaOperator) &&
                        !(part is NovelFunctionStartOperator) &&
                        !(part is NovelFunctionEndOperator))
                    {
                        //If its one argument operator
                        if (part is NovelNegationOperator &&
                            term[i - 1] is NovelExpressionOperand)
                        {
                            var operand           = term[i - 1] as NovelExpressionOperand;
                            var lastStackOperator = Variables.GetStackVariables();
                            var temporaryVariable = new NovelExpressionVariable("temp_" + lastStackOperator, lastStackOperator);
                            Variables.AddVaraible(temporaryVariable.Name);

                            instructions.Add(new NovelExpandStack(1));
                            var newExpression = new NovelExpression();
                            newExpression.Term.Add(temporaryVariable);
                            newExpression.Term.Add(operand);
                            newExpression.Term.Add(part);
                            newExpression.Term.Add(new NovelAssignOperator());
                            instructions.Add(newExpression);
                            //Replace last operation with temporary variable
                            expression.Term.RemoveAt(i - 1);
                            expression.Term.RemoveAt(i - 1);
                            //Don't put temporary variable to expression if its empty
                            if (expression.Term.Count > 0)
                            {
                                expression.Term.Insert(i - 1, temporaryVariable);
                            }

                            i -= 1;
                        }
                        //Get the two operands if its not negation
                        else
                        {
                            //If its the end of expression
                            if (part is NovelAssignOperator &&
                                expression.Term.Count == 3 &&
                                term[i - 1] is NovelExpressionOperand &&
                                term[i - 2] is NovelExpressionOperand)
                            {
                                var newExpression = new NovelExpression();
                                newExpression.Term.Add(term[i - 2]);
                                newExpression.Term.Add(term[i - 1]);
                                newExpression.Term.Add(part);
                                instructions.Add(newExpression);
                                expression.Term.Clear();
                            }
                            //If both previous parts in term are operands
                            else if (
                                term[i - 1] is NovelExpressionOperand &&
                                term[i - 2] is NovelExpressionOperand)
                            {
                                var operandLeft  = term[i - 2] as NovelExpressionOperand;
                                var operandRight = term[i - 1] as NovelExpressionOperand;

                                var lastStackOperator = Variables.GetStackVariables();
                                var temporaryVariable = new NovelExpressionVariable("temp_" + lastStackOperator, lastStackOperator);
                                Variables.AddVaraible(temporaryVariable.Name);

                                instructions.Add(new NovelExpandStack(1));
                                //Create new operation of two operands
                                //and assign the result to temporary variable
                                var newExpression = new NovelExpression();
                                newExpression.Term.Add(temporaryVariable);
                                newExpression.Term.Add(operandLeft);
                                newExpression.Term.Add(operandRight);
                                newExpression.Term.Add(part);
                                newExpression.Term.Add(new NovelAssignOperator());
                                instructions.Add(newExpression);
                                //Replace last operation with temporary variable
                                expression.Term.RemoveAt(i - 2);
                                expression.Term.RemoveAt(i - 2);
                                expression.Term.RemoveAt(i - 2);
                                if (expression.Term.Count > 0)
                                {
                                    expression.Term.Insert(i - 2, temporaryVariable);
                                }

                                i -= 2;
                            }
                        }
                    }
                }
            }
            return(expression);
        }