예제 #1
0
        /// <summary>
        /// Converts the input equation string into a SIL_Equation recursive datastructure
        /// </summary>
        /// <param name="equation">basic input eqaution, must NOT contain any brackets!</param>
        /// <returns>Converted equation class which can be calculated</returns>
        static ISILObject ProcessEquation(string functionspace, string equationString, List <ISILObject> equations)
        {
            //always returns equation
            if (!SIL_Math.IsEquation(equationString))
            {
                return(Retrieve_SIL_Object(functionspace, equationString, equations));
            }

            char[] separators = { '/', '*', '+', '-', '&', '|', '<', '>', '=' };

            string leftVar           = "",
                   rightVar          = "",
                   equationSubstring = "";
            int leftIndex            = 0,
                rightIndex           = 0;
            SILEquation equation     = new SILEquation();

            equationString = equationString.Trim();
            //multiplication and division needs to be taken care of first!


            List <OperatorPosition> firstPos = new List <OperatorPosition>();

            for (int i = 0; i < separators.Length; i++)
            {
                int pos = equationString.IndexOf(separators[i]);
                if (pos >= 0)
                {
                    OperatorPosition op = new OperatorPosition();
                    op.position = pos;
                    op.c        = separators[i];
                    firstPos.Add(op);
                }
                if (i == 1 && firstPos.Count > 0)
                {
                    break;
                }
            }
            firstPos.Sort(SortFirstOperators);

            equation.Operation = ConvertToOperator(firstPos[0].c);
            //now find the two terms this operation applies to and build new SIL_Equation class
            //find left variable
            for (int i = firstPos[0].position - 1; i >= 0; i--)
            {
                leftIndex = i;
                if (SIL_Math.IsOperator(equationString[i]))
                {
                    if (i == 1)
                    {
                        leftIndex--;         //allow negative numbers
                    }
                    break;
                }
                leftVar += equationString[i];
            }
            leftVar = leftVar.Trim();
            if (leftVar.Length == 0)
            {
                leftVar = "0";
            }
            else
            {
                leftVar = Reverse(leftVar);  //reverse the string b/c I read it from right to left
            }
            equation.Argument1 = Retrieve_SIL_Object(functionspace, leftVar, equations);

            //find right variable
            for (int i = firstPos[0].position + 1; i < equationString.Length; i++)
            {
                if (SIL_Math.IsOperator(equationString[i]))
                {
                    break;
                }
                rightIndex = i;
                rightVar  += equationString[i];
            }
            rightIndex++;
            rightVar = rightVar.Trim();
            if (rightVar.Length == 0)
            {
                rightVar = "0";
            }

            equation.Argument2 = Retrieve_SIL_Object(functionspace, rightVar, equations);

            equationSubstring = equationString.Substring(leftIndex, rightIndex - leftIndex);

            string leftPart    = leftIndex > 0 ? equationString.Substring(0, leftIndex + 1) : "";
            int    rightLength = equationString.Length - rightIndex;
            string rightPart   = rightLength > 0 ? equationString.Substring(rightIndex, rightLength) : "";

            equationString = leftPart +
                             "{" + equations.Count.ToString() + "}" +
                             rightPart;
            equations.Add(equation);

            return(ProcessEquation(functionspace, equationString, equations));
        }
예제 #2
0
        /// <summary>
        /// FOR is basically 2 actions: LET and WHILE combined with incrementing equation
        /// </summary>
        /// <param name="unparsedArgs"></param>
        /// <param name="parsedArgs"></param>
        /// <param name="lineNumber"></param>
        /// <returns></returns>
        static ActionType FOR_Parse(string functionspace, string unparsedArgs, ref object[] parsedArgs, ref int lineNumber)
        {
            //FOR i = 3, i < 10, i = i + 1
            //remove the FOR word
            string parameters = unparsedArgs.Substring(4, unparsedArgs.Length - 4);

            //validate and decompose the string
            string[] split = parameters.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
            if (split.Length < 3)
            {
                throw new Exception("Incorrect syntax! Use \"FOR variable, condition, increment\"");
            }

            parsedArgs = new object[3];
            Queue <SIL_Action> actions_ = new Queue <SIL_Action>();

            //Create LET statement
            object[] parsedArgsLET = null;
            parserSymbols_["LET"](
                functionspace,
                "LET " + split[0], //we have to add "LET " string in front for parser to recognize this command as LET
                ref parsedArgsLET,
                ref lineNumber);
            SIL_Action LETaction = new SIL_Action(ActionType.LET, parsedArgsLET, lineNumber, functionspace);

            LETaction.OnAction += new SIL_Action.Action(exeAction_);
            parsedArgs[0]       = LETaction;

            //Parse condition
            try
            {
                SILEquation condition = (SILEquation)ExpressionParse(functionspace, split[1], new List <ISILObject>());
                parsedArgs[1] = condition;
            }
            catch (Exception conidtionEx)
            {
                throw conidtionEx;
                throw new Exception("Condition must be an equation");
            }

            //Parse increment
            object[] parsedArgsINCREMENT = null;
            parserSymbols_["LET"](
                functionspace,
                "LET " + split[2],
                ref parsedArgsINCREMENT,
                ref lineNumber);
            SIL_Action INCREMENTaction = new SIL_Action(ActionType.LET, parsedArgsINCREMENT, lineNumber, functionspace);

            INCREMENTaction.OnAction += new SIL_Action.Action(exeAction_);

            //Parse everythig inside FOR block
            SIL_Action action;

            do
            {
                lineNumber++;
                if (lineNumber >= sourceLines_.Length)
                {
                    throw new Exception("NEXT expected!");
                }
                action = ParseNext(functionspace, ref lineNumber);
                if (action != null)
                {
                    actions_.Enqueue(action);
                }
            } while (action.ActionType != ActionType.NEXT);
            //Add increment action last
            actions_.Enqueue(INCREMENTaction);

            parsedArgs[2] = actions_;

            return(ActionType.FOR);
        }