예제 #1
0
        /// <summary>
        /// Executes a list of strings as a script, line by line, and returns the last calculated number
        /// </summary>
        /// <param name="linesEnumerable"></param>
        /// <returns></returns>
        public double ExecuteLines(IEnumerable <string> linesEnumerable)
        {
            var lines = linesEnumerable.ToArray();

            double lastOutput = 0;
            Stack <IfChainState> chainStates = new Stack <IfChainState>();
            int lineNumber = 0;

            try
            {
                while (lineNumber < lines.Length)
                {
                    var line = lines[lineNumber].Trim().ToLowerInvariant();
                    if (string.IsNullOrWhiteSpace(line))
                    {
                        lineNumber++;
                        continue;
                    }
                    IfChainState currentState = IfChainState.Executing;
                    if (chainStates.Count > 0)
                    {
                        currentState = chainStates.Peek();
                    }
                    if (line.StartsWith("if"))
                    {
                        if (currentState == IfChainState.Executing)
                        {
                            string condition = line.Substring(line.IndexOf("if") + 2).Trim();
                            var    result    = booleanParser.ProgrammaticallyParse(condition);
                            bool   executeIf = booleanParser.ToBoolean(result);
                            chainStates.Push(executeIf ? IfChainState.Executing : IfChainState.NotExecuted);
                        }
                        else
                        {
                            // The if statement this if statement is in is not executing, so we push executed on the stack to make sure the contents of this don't get executed, and any following if else/else statements don't get executed either
                            chainStates.Push(IfChainState.Executed);
                        }
                    }
                    else if (line.StartsWith("else if") || line.StartsWith("elif"))
                    {
                        var oldState = chainStates.Pop();
                        if (oldState == IfChainState.NotExecuted)
                        {
                            string condition = line.Substring(line.IndexOf("if") + 2).Trim();
                            var    result    = booleanParser.ProgrammaticallyParse(condition);
                            bool   executeIf = booleanParser.ToBoolean(result);
                            chainStates.Push(executeIf ? IfChainState.Executing : IfChainState.NotExecuted);
                        }
                        else
                        {
                            chainStates.Push(IfChainState.Executed);
                        }
                    }
                    else if (line.StartsWith("else"))
                    {
                        var oldState = chainStates.Pop();
                        chainStates.Push(oldState == IfChainState.NotExecuted ? IfChainState.Executing : IfChainState.Executed);
                    }
                    else if (line == "end if" || line == "endif")
                    {
                        chainStates.Pop();
                    }
                    else
                    {
                        if (currentState == IfChainState.Executing)
                        {
                            if (line.StartsWith(LogFunctionName + " ") || line.StartsWith(LogFunctionName + "(") || line.StartsWith(LogFunctionName + "\""))
                            {
                                string logExpression = line.Substring(LogFunctionName.Length).Trim();
                                LogString(logExpression);
                            }
                            else
                            {
                                lastOutput = mathParser.ProgrammaticallyParse(line);
                            }
                        }
                    }
                    lineNumber++;
                }
            }
            catch (Exception e)
            {
                throw new ScriptParserException(lineNumber + 1, e);
            }
            return(lastOutput);
        }
예제 #2
0
 public void TruthyConvert()
 {
     Assert.AreEqual(parser.ProgrammaticallyParse("0"), 0);
     Assert.AreEqual(parser.ProgrammaticallyParse("1"), 1);
     Assert.AreEqual(parser.ProgrammaticallyParse("2346"), 1);
     Assert.AreEqual(parser.ProgrammaticallyParse("-1"), 1);
     Assert.AreEqual(parser.ProgrammaticallyParse("1-1"), 0);
     Assert.AreEqual(parser.ProgrammaticallyParse("0.5"), 1);
 }