예제 #1
0
        public static ISILObject ExpressionParse(string functionspace, string unparsedArgs, List <ISILObject> equations)
        {
            unparsedArgs = unparsedArgs.Trim();

            //Check if it is not an equation but a variable, otherwise recurse until it is a single object
            if (!SIL_Math.IsEquation(unparsedArgs) && !unparsedArgs.Contains('['))
            {
                return(Retrieve_SIL_Object(functionspace, unparsedArgs, equations));
            }

            int leftIndex  = 0,
                rightIndex = 0;
            string deepestEquation;

            //parse arrays first
            if (unparsedArgs.Contains('['))
            {
                deepestEquation = FindDeepest(unparsedArgs, '[', ']', ref rightIndex, ref leftIndex);

                ISILObject arrIndex = ProcessEquation(functionspace, deepestEquation, equations);
                string     arrName  = "";
                leftIndex--;
                while (leftIndex > 0 ?
                       (!SIL_Math.IsOperator(unparsedArgs[leftIndex - 1]) &&
                        unparsedArgs[leftIndex - 1] != '[' &&
                        unparsedArgs[leftIndex - 1] != '(') : false)
                {
                    leftIndex--;
                    arrName += unparsedArgs[leftIndex];
                }
                arrName = Reverse(arrName).Trim();
                int    leftLength = leftIndex;
                string leftPart   = leftLength > 0 ? unparsedArgs.Substring(0, leftLength) : "";
                rightIndex = rightIndex == unparsedArgs.Length ? rightIndex : rightIndex + 1;
                int    rightLength = unparsedArgs.Length - rightIndex;
                string rightPart   = rightLength > 0 ? unparsedArgs.Substring(rightIndex, rightLength) : "";

                equations.Add(new SILArrayElement(functionspace + "." + arrName, arrIndex));
                unparsedArgs = leftPart +
                               "{" + (equations.Count - 1).ToString() + "}" +
                               rightPart;

                return(ExpressionParse(functionspace, unparsedArgs, equations));
            }
            deepestEquation = FindDeepest(unparsedArgs, '(', ')', ref rightIndex, ref leftIndex);

            if (leftIndex > 1)
            {
                if (char.IsLetterOrDigit(unparsedArgs[leftIndex - 2]))
                {
                    string functionName = "";
                    leftIndex--;
                    while (leftIndex > 0 ?
                           (!SIL_Math.IsOperator(unparsedArgs[leftIndex - 1]) &&
                            unparsedArgs[leftIndex - 1] != '[' &&
                            unparsedArgs[leftIndex - 1] != '(') : false)
                    {
                        leftIndex--;
                        functionName += unparsedArgs[leftIndex];
                    }
                    functionName = Reverse(functionName).Trim();

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

                    string      function_s = unparsedArgs.Substring(leftLength, rightIndex - leftLength).Trim();
                    SILFunction function;
                    object[]    functionArgs = null;
                    int         linenumber   = 0;
                    CALL_Parse(functionspace, "CALL " + function_s, ref functionArgs, ref linenumber);
                    function = (SILFunction)functionArgs[0];

                    equations.Add(function);
                    unparsedArgs = leftPart +
                                   "{" + (equations.Count - 1).ToString() + "}" +
                                   rightPart;

                    return(ExpressionParse(functionspace, unparsedArgs, equations));
                }
            }

            if (!SIL_Math.IsEquation(deepestEquation))
            {
                unparsedArgs = unparsedArgs.Replace("(" + deepestEquation + ")", deepestEquation.Trim());
            }
            else
            {
                equations.Add((SILEquation)ProcessEquation(functionspace, deepestEquation, equations));
                int    leftLength = leftIndex > 0 ? leftIndex - 1 : 0;
                string leftPart   = leftLength > 0 ? unparsedArgs.Substring(0, leftLength) : "";
                rightIndex = rightIndex == unparsedArgs.Length ? rightIndex : rightIndex + 1;
                int    rightLength = unparsedArgs.Length - rightIndex;
                string rightPart   = rightLength > 0 ? unparsedArgs.Substring(rightIndex, rightLength) : "";
                unparsedArgs = leftPart +
                               "{" + (equations.Count - 1).ToString() + "}" +
                               rightPart;
            }
            return(ExpressionParse(functionspace, unparsedArgs, equations));
        }
예제 #2
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));
        }
예제 #3
0
        static ActionType CALL_Parse(string functionspace, string unparsedArgs, ref object[] parsedArgs, ref int lineNumber)
        {
            string parameters = unparsedArgs.Substring(5, unparsedArgs.Length - 5);

            if (!parameters.Contains("("))
            {
                throw new Exception("\"(\" Expected!");
            }
            string[] split = parameters.Split(new char[] { '(' }, StringSplitOptions.RemoveEmptyEntries);
            if (split.Length != 2)
            {
                throw new SyntaxErrorException();
            }
            string            functionName = split[0];
            FunctionPrototype prototype    = FunctionTable.Get(functionName);

            //Parse parameters & their types
            split[1] = split[1].Trim();
            if (split[1][split[1].Length - 1] != ')')
            {
                throw new Exception("\")\" Expected!");
            }
            split[1] = split[1].Substring(0, split[1].Length - 1);
            string[] split2 = split[1].Split(',');
            if (split2.Length == 1 && split2[0].Trim() == "")
            {
                split2 = new string[] { }
            }
            ;
            if (split2.Length != prototype.ParameterTypes.Length)
            {
                throw new Exception("Incorrect number of arguments!");
            }
            List <ISILObject> functionParameters = new List <ISILObject>();

            for (int i = 0; i < split2.Length; i++)
            {
                string parameter_s = split2[i].Trim();
                if (parameter_s == "")
                {
                    throw new Exception(string.Format("Missing parameter type and name for argument #{0}!", i));
                }
                ISILObject parameter;
                if (SIL_Math.IsEquation(parameter_s))
                {
                    parameter = ExpressionParse(functionspace, parameter_s, new List <ISILObject>());
                }
                else
                {
                    parameter = Retrieve_SIL_Object(functionspace, parameter_s, null);
                }

                if ((prototype.ParameterTypes[i] == ObjectType.Array && parameter.Type != ObjectType.Array) ||
                    (prototype.ParameterTypes[i] == ObjectType.Integer && parameter.Type == ObjectType.Array))
                {
                    throw new Exception(
                              string.Format("Incorrect type of parameter #{0}, {1} expexted!",
                                            i, Enum.GetName(typeof(ObjectType), prototype.ParameterTypes[i])));
                }
                functionParameters.Add(parameter);
            }

            SILFunction function = new SILFunction(functionName, functionParameters.ToArray());

            parsedArgs = new object[] { function };
            return(ActionType.CALL);
        }