/// <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)); }
/// <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); }