Inheritance: CommandBase
示例#1
0
        static Script BuildScriptTree(List <IScriptCommand> commands)
        {
            Stack <List <IScriptCommand> > context = new Stack <List <IScriptCommand> >();

            foreach (IScriptCommand command in commands)
            {
                if (context.Count() == 0)
                {
                    context.Push(new List <IScriptCommand>());
                }
                ;
                if (command.Type.Equals("basic") &&
                    command.GetType() != typeof(LoopStartCommand) &&
                    command.GetType() != typeof(LoopEndCommand))
                {
                    context.Peek().Add(command);
                }
                if (command.GetType() == typeof(LoopStartCommand))
                {
                    List <IScriptCommand> newContext = new List <IScriptCommand>();
                    newContext.Add(command);
                    context.Push(newContext);
                }
                if (command.GetType() == typeof(LoopEndCommand))
                {
                    List <IScriptCommand> currentContext = context.Pop();
                    LoopStartCommand      loopStart      = (LoopStartCommand)currentContext[0];
                    currentContext.RemoveAt(0);
                    LoopCommand loop = new LoopCommand(loopStart, currentContext, (LoopEndCommand)command);
                    context.Peek().Add(loop);
                }
            }
            return(new Script(context.Pop()));
        }
示例#2
0
 private void startDisplayLoop(LoopCommand loopCommand)
 {
     foreach (var builders in displayValueBuilders)
     {
         builders.Value.StartDisplayLoop(loopCommand);
     }
 }
示例#3
0
        public LoopCommand StartLoopGroup(double startTime, int loopCount)
        {
            var loopCommand = new LoopCommand(startTime, loopCount);

            addCommand(loopCommand);
            startDisplayLoop(loopCommand);
            return(loopCommand);
        }
示例#4
0
        public IEnumerable <Command> Parse(IEnumerable <string> data_arr)
        {
            LoopCommand command = new LoopCommand();

            command.StartTime = data_arr.ElementAt(1).ToInt();
            command.LoopCount = data_arr.ElementAt(2).ToInt();

            yield return(command);
        }
示例#5
0
        public void LoopCommandObjectCreatedIsSameAsAConstructedObject(LoopType loopType)
        {
            ILoopCommand commandFromFactory = (LoopCommand)commandFactory.NewLoopCommand(loopType);
            ILoopCommand commandConstructedDirectly = new LoopCommand(loopType);

            Assert.IsNotNull(commandFromFactory);
            Assert.AreEqual(typeof(LoopCommand), commandFromFactory.GetType());
            Assert.AreEqual(commandConstructedDirectly.CommandType, commandFromFactory.CommandType);
            Assert.AreEqual(commandConstructedDirectly.LoopType, commandFromFactory.LoopType);
        }
示例#6
0
 public void VisitLoop(LoopCommand Loop)
 {
     Loop.Start.Accept(this);
     for (int i = 0; i < Loop.Start.Loops.Value; i++)
     {
         foreach (IScriptCommand command in Loop.Commands)
         {
             command.Accept(this);
         }
     }
     Loop.End.Accept(this);
 }
示例#7
0
        public LoopSubTimelineCommand(LoopCommand loop_command, Event bind_event)
        {
            this.loop_command = loop_command;
            Event             = bind_event;
            timeline          = loop_command.SubCommands[bind_event];

            var offset = loop_command.SubCommands.SelectMany(l => l.Value).Min(x => x.StartTime);

            CostTime  = loop_command.CostTime - offset;
            StartTime = loop_command.StartTime + offset;
            EndTime   = StartTime + CostTime * loop_command.LoopCount;

            RelativeLine = loop_command.RelativeLine;
        }
        public void StartDisplayLoop(LoopCommand loopCommand)
        {
            if (composite != null)
            {
                throw new InvalidOperationException("Cannot start loop: already inside a loop or trigger");
            }

            decorate = (command) =>
            {
                if (loopCommand.CommandsStartTime != 0)
                {
                    throw new InvalidOperationException($"Commands in a loop must start at 0ms, but start at {loopCommand.CommandsStartTime}ms");
                }
                return(new LoopDecorator <TValue>(command, loopCommand.StartTime, loopCommand.CommandsDuration, loopCommand.LoopCount));
            };
            composite = new CompositeCommand <TValue>();
        }
 private void AddLoopCommand(LoopCommand loop_command)
 {
     if (Setting.EnableLoopCommandUnrolling)
     {
         //将Loop命令各个类型的子命令时间轴封装成一个命令,并添加到物件本体各个时间轴上
         foreach (var cmd in loop_command.SubCommandExpand())
         {
             AddCommand(cmd);
         }
     }
     else
     {
         //将Loop命令里面的子命令展开
         foreach (var @event in loop_command.SubCommands.Keys)
         {
             var sub_command_wrapper = new LoopSubTimelineCommand(loop_command, @event);
             AddCommand(sub_command_wrapper);
         }
     }
 }
示例#10
0
        public void Update(LoopCommand command, int?slotIndex = null)
        {
            // Cannot use loop player while networked
            var skipLoopsBecauseNetwork = false;

            if (IsNetworked != null && IsNetworked())
            {
                LoopStopAllRecording();
                LoopStopPlaying();
                skipLoopsBecauseNetwork = true;
            }

            if (command.HasFlag(LoopCommand.RecordHasFocus))
            {
                for (var i = 0; i < loopSlots.Length; i++)
                {
                    if (slotIndex.HasValue && slotIndex.Value == i)
                    {
                        // Record the loop (can't record to the playing loop!)
                        if (command.HasFlag(LoopCommand.Record) && !(playingLoop.HasValue && i == playingLoop.Value))
                        {
                            // If we were already recording on that slot, stop recording - this closes the file so we can re-open it!
                            if (loopSlots[i] != null)
                            {
                                loopSlots[i].StopRecording();
                            }

                            var saveState = Serialize();

                            loopSlots[i] = Loop.StartRecording(string.Format("loop{0}.bin", i), saveState, definitionHash, "");
                            if (command.HasFlag(LoopCommand.SnapshotOnly) || skipLoopsBecauseNetwork)
                            {
                                loopSlots[i].StopRecording();                                 // <- just the snapshot
                            }
                        }

                        SelectedLoop = i;
                    }
                }
            }

            if (skipLoopsBecauseNetwork)
            {
                return;
            }

            if (droppedLoopFilename != null)
            {
                if (command.HasFlag(LoopCommand.NextLoop) || command.HasFlag(LoopCommand.PreviousLoop))
                {
                    var dir   = Path.GetDirectoryName(droppedLoopFilename);
                    var files = Directory.GetFiles(dir, "*.bin", SearchOption.TopDirectoryOnly);
                    Array.Sort(files, new NaturalStringComparer());
                    var index = Array.IndexOf(files, droppedLoopFilename);
                    if (index >= 0)
                    {
                        if (command == LoopCommand.NextLoop)
                        {
                            index += 1;
                        }
                        else
                        {
                            index += files.Length - 1;
                        }
                        index %= files.Length;
                        HandleDroppedLoop(files[index]);
                    }
                }
            }

            if (command.HasFlag(LoopCommand.Stop))
            {
                LoopStopAllRecording();
                LoopStopPlaying();
            }

            if (command.HasFlag(LoopCommand.StartPlaying))
            {
                // Lazy-load from working directory:
                if (loopSlots[SelectedLoop] == null)
                {
                    var filename = "loop" + SelectedLoop + ".bin";
                    if (File.Exists(filename))
                    {
                        loopSlots[SelectedLoop] = Loop.TryLoadFromFile(filename, ref definitionHash);
                    }
                }

                LoopStartPlaying(SelectedLoop);
            }
        }
示例#11
0
        private static void ProcessCommands(Command[] commands, ref int currentCommandIndex, int depth)
        {
            if (depth > Constants.MaxProcessingStack)
            {
                throw new Exception(Resources.ProcessingStackOverflow);
            }

            if (depth < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(depth));
            }

            while (currentCommandIndex < commands.Length)
            {
                Command currentCommand = commands[currentCommandIndex];

                //Console.WriteLine(currentCommand.Name);

                if (currentCommand.Name.Equals(Constants.StartDefinition))
                {
                    currentCommandIndex++;
                    ParseDefinition(commands, ref currentCommandIndex, false);
                }
                else if (currentCommand.Name.Equals(Constants.RedefineDefinition))
                {
                    currentCommandIndex++;
                    ParseDefinition(commands, ref currentCommandIndex, true);
                }
                else if (currentCommand is IfCommand)
                {
                    IfCommand ifCommand = currentCommand as IfCommand;
                    FInteger  intValue  = new FInteger(BitConverter.ToInt32(Stack.Pop().Bytes, 0));
                    if (intValue.Value == Constants.True)
                    {
                        int ifCommandIndex = 0;
                        ProcessCommands(ifCommand.IfCommands.ToArray(), ref ifCommandIndex, depth + 1);
                    }
                    else
                    {
                        int elseCommandIndex = 0;
                        ProcessCommands(ifCommand.ElseCommands.ToArray(), ref elseCommandIndex, depth + 1);
                    }
                }
                else if (currentCommand.Name.Equals(Constants.Else))
                {
                }
                else if (currentCommand.Name.Equals(Constants.EndIf))
                {
                }
                else if (currentCommand is RepeatCommand)
                {
                    RepeatCommand repeatCommand = currentCommand as RepeatCommand;
                    FInteger      fInteger;
                    do
                    {
                        int repeatCommandIndex = 0;
                        ProcessCommands(repeatCommand.RepeatCommands.ToArray(), ref repeatCommandIndex, depth + 1);
                        fInteger = new FInteger(BitConverter.ToInt32(Stack.Pop().Bytes, 0));
                    } while (fInteger.Value == Constants.False);
                }
                else if (currentCommand.Name.Equals(Constants.Until))
                {
                }
                else if (currentCommand is LoopCommand)
                {
                    LoopCommand loopCommand = currentCommand as LoopCommand;

                    FInteger incrementor  = new FInteger(BitConverter.ToInt32(Stack.Pop().Bytes, 0));
                    FInteger currentValue = new FInteger(BitConverter.ToInt32(Stack.Pop().Bytes, 0));
                    FInteger targetValue  = new FInteger(BitConverter.ToInt32(Stack.Pop().Bytes, 0));

                    while (currentValue.Value != targetValue.Value)
                    {
                        Stack.Push(new Cell(targetValue.GetBytes()));
                        Stack.Push(new Cell(currentValue.GetBytes()));
                        Stack.Push(new Cell(incrementor.GetBytes()));
                        int loopCommandIndex = 0;
                        ProcessCommands(loopCommand.LoopCommands.ToArray(), ref loopCommandIndex, depth + 1);

                        incrementor         = new FInteger(BitConverter.ToInt32(Stack.Pop().Bytes, 0));
                        currentValue        = new FInteger(BitConverter.ToInt32(Stack.Pop().Bytes, 0));
                        targetValue         = new FInteger(BitConverter.ToInt32(Stack.Pop().Bytes, 0));
                        currentValue.Value += incrementor.Value;
                    }
                }
                else if (currentCommand.Name.Equals(Constants.EndLoop))
                {
                }
                else
                {
                    if ((_ioMode == IoModeEnum.Hex) && (IsHexInteger(currentCommand.Name)))
                    {
                        int intValue;

                        if (!int.TryParse(currentCommand.Name, System.Globalization.NumberStyles.HexNumber, null,
                                          out intValue))
                        {
                            throw new Exception(string.Format(Resources.InvalidHexInteger, currentCommand));
                        }

                        FInteger intConstant = new FInteger(intValue);
                        Stack.Push(new Cell(intConstant.GetBytes()));
                    }
                    else if ((_ioMode == IoModeEnum.Decimal) && (IsInteger(currentCommand.Name)))
                    {
                        int intValue;
                        if (!int.TryParse(currentCommand.Name, out intValue))
                        {
                            throw new Exception(string.Format(Resources.InvalidInteger, currentCommand));
                        }

                        FInteger intConstant = new FInteger(intValue);
                        Stack.Push(new Cell(intConstant.GetBytes()));
                    }
                    else
                    {
                        float floatValue;
                        if ((_ioMode == IoModeEnum.Fraction) && (IsFloat(currentCommand.Name)))
                        {
                            if (!float.TryParse(currentCommand.Name, out floatValue))
                            {
                                throw new Exception(string.Format(Resources.InvalidFloat, currentCommand));
                            }

                            FFloat intConstant = new FFloat(floatValue);
                            Stack.Push(new Cell(intConstant.GetBytes()));
                        }
                        else if ((_ioMode == IoModeEnum.Char) && (IsChar(currentCommand.Name)))
                        {
                            string subString = currentCommand.Name.Substring(Constants.StartChar.Length,
                                                                             currentCommand.Name.Length - Constants.EndChar.Length - 1);
                            char ch;
                            if (!char.TryParse(subString, out ch))
                            {
                                throw new Exception(string.Format(Resources.InvalidCharacter, subString));
                            }

                            FInteger intConstant = new FInteger(ch);
                            Stack.Push(new Cell(intConstant.GetBytes()));
                        }
                        else if (IsString(currentCommand.Name))
                        {
                            string subString = currentCommand.Name.Substring(Constants.StartString.Length,
                                                                             currentCommand.Name.Length - Constants.EndString.Length - 2);
                            Console.Write(subString);
                        }
                        else if (IsVariable(currentCommand.Name))
                        {
                            Stack.Push(new Cell(new FInteger(Objects[currentCommand.Name].Item2).GetBytes()));
                        }
                        else if (IsValue(currentCommand.Name))
                        {
                            byte[] bytes = new byte[Constants.CellSize];
                            Array.Copy(Memory, Objects[currentCommand.Name].Item2, bytes, 0, Constants.CellSize);
                            Stack.Push(new Cell(bytes));
                        }
                        else if (IsConstant(currentCommand.Name))
                        {
                            byte[] bytes = new byte[Constants.CellSize];
                            Array.Copy(Memory, Objects[currentCommand.Name].Item2, bytes, 0, Constants.CellSize);
                            Stack.Push(new Cell(bytes));
                        }
                        else if (IsDefinition(currentCommand.Name))
                        {
                            int definitionTokenIndex = 0;
                            ProcessCommands(Definitions[currentCommand.Name].ToArray(), ref definitionTokenIndex, depth + 1);
                        }
                        else if (currentCommand.Name.Equals(Constants.ViewDefinitions))
                        {
                            Console.WriteLine();
                            foreach (string key in Definitions.Keys)
                            {
                                Console.Write(Resources.Executor_ProcessCommands__StartDefinition, Constants.StartDefinition);
                                Console.Write(string.Format(Resources.Executor_ProcessCommands__Key, key).PadRight(18, ' '));
                                foreach (Command command in Definitions[key])
                                {
                                    Console.Write(string.Format("{0} ", command.Name));
                                }

                                Console.WriteLine(string.Format("{0}", Constants.EndDefinition));
                            }
                        }
                        else if (currentCommand.Name.Equals(Constants.ViewObjects))
                        {
                            Console.WriteLine();
                            foreach (string key in Objects.Keys)
                            {
                                Console.Write(string.Format("{0}", key).PadRight(20, ' '));
                                Console.Write(string.Format("{0}\t", Objects[key].Item1));
                                Console.Write(string.Format("{0}\t", Objects[key].Item2));

                                byte[] bytes = FetchFromMemory(new FInteger(Objects[key].Item2));
                                Console.WriteLine(string.Format("{0}", GetOutputValue(bytes)));
                            }
                        }
                        else if (currentCommand.Name.Equals(Constants.Help))
                        {
                            Console.WriteLine();
                            foreach (string command in Constants.ValidCommands)
                            {
                                Console.WriteLine(command);
                            }
                        }
                        else if (currentCommand.Name.Equals(Constants.Variable))
                        {
                            if (currentCommandIndex >= commands.Length - 1)
                            {
                                throw new Exception(Resources.ExpectedAName);
                            }

                            currentCommandIndex++;
                            string variableName = commands[currentCommandIndex].Name;
                            if (IsAlreadyDefined(variableName))
                            {
                                throw new Exception(string.Format(Resources.AlreadyDefined, variableName));
                            }

                            AddObject(variableName, MemoryEntryEnum.Variable);
                        }
                        else if (currentCommand.Name.Equals(Constants.Value))
                        {
                            if (currentCommandIndex >= commands.Length - 1)
                            {
                                throw new Exception(Resources.ExpectedAName);
                            }

                            currentCommandIndex++;
                            string variableName = commands[currentCommandIndex].Name;
                            if (IsAlreadyDefined(variableName))
                            {
                                throw new Exception(string.Format(Resources.AlreadyDefined, variableName));
                            }

                            AddObject(variableName, MemoryEntryEnum.Value, Stack.Pop().Bytes);
                        }
                        else if (currentCommand.Name.Equals(Constants.Constant))
                        {
                            if (currentCommandIndex >= commands.Length - 1)
                            {
                                throw new Exception(Resources.ExpectedAName);
                            }

                            currentCommandIndex++;
                            string variableName = commands[currentCommandIndex].Name;
                            if (IsAlreadyDefined(variableName))
                            {
                                throw new Exception(string.Format(Resources.AlreadyDefined, variableName));
                            }

                            AddObject(variableName, MemoryEntryEnum.Constant, Stack.Pop().Bytes);
                        }
                        else if (currentCommand.Name.Equals(Constants.Store))
                        {
                            FInteger memoryLocation = new FInteger(BitConverter.ToInt32(Stack.Pop().Bytes, 0));
                            FInteger intValue       = new FInteger(BitConverter.ToInt32(Stack.Pop().Bytes, 0));

                            StoreToMemory(intValue, memoryLocation);
                        }
                        else if (currentCommand.Name.Equals(Constants.Fetch))
                        {
                            FInteger memoryLocation = new FInteger(BitConverter.ToInt32(Stack.Pop().Bytes, 0));

                            byte[] bytes = FetchFromMemory(memoryLocation);

                            FInteger intValue = new FInteger(BitConverter.ToInt32(bytes, 0));
                            Stack.Push(new Cell(intValue.GetBytes()));
                        }
                        else if (currentCommand.Name.Equals(Constants.To))
                        {
                            if (currentCommandIndex >= commands.Length - 1)
                            {
                                throw new Exception(Resources.ExpectedAName);
                            }

                            currentCommandIndex++;
                            string valueName = commands[currentCommandIndex].Name;
                            if (!IsValue(valueName))
                            {
                                throw new Exception(string.Format(Resources.NameIsNotAValue, valueName));
                            }

                            SetObject(Objects[valueName].Item2, Stack.Pop().Bytes);
                        }
                        else if (currentCommand.Name.Equals(Constants.Cell))
                        {
                            Stack.Push(new Cell(new FInteger(Constants.CellSize).GetBytes()));
                        }
                        else if (currentCommand.Name.Equals(Constants.Here))
                        {
                            Stack.Push(new Cell(new FInteger(_memoryPointer).GetBytes()));
                        }
                        else if (currentCommand.Name.Equals(Constants.Allot))
                        {
                            FInteger memoryAllocBytes = new FInteger(BitConverter.ToInt32(Stack.Pop().Bytes, 0));
                            if (_memoryPointer + memoryAllocBytes.Value < 0)
                            {
                                throw new Exception(Resources.MemoryUnderflow);
                            }
                            else if (_memoryPointer + memoryAllocBytes.Value > Constants.MemorySize)
                            {
                                throw new Exception(Resources.MemoryOverflow);
                            }

                            _memoryPointer += memoryAllocBytes.Value;
                        }
                        else if (currentCommand.Name.Equals(Constants.Decimal))
                        {
                            _ioMode = IoModeEnum.Decimal;
                        }
                        else if (currentCommand.Name.Equals(Constants.Hex))
                        {
                            _ioMode = IoModeEnum.Hex;
                        }
                        else if (currentCommand.Name.Equals(Constants.Fractional))
                        {
                            _ioMode = IoModeEnum.Fraction;
                        }
                        else if (currentCommand.Name.Equals(Constants.Char))
                        {
                            _ioMode = IoModeEnum.Char;
                        }
                        else if (currentCommand.Name.Equals(Constants.Period))
                        {
                            OutputValue(Stack.Pop().Bytes);
                        }
                        else if (currentCommand.Name.Equals(Constants.Dup))
                        {
                            Stack.Dup();
                        }
                        else if (currentCommand.Name.Equals(Constants.Swap))
                        {
                            Stack.Swap();
                        }
                        else if (currentCommand.Name.Equals(Constants.Drop))
                        {
                            Stack.Drop();
                        }
                        else if (currentCommand.Name.Equals(Constants.Rot))
                        {
                            Stack.Rot();
                        }
                        else if (currentCommand.Name.Equals(Constants.Over))
                        {
                            Stack.Over();
                        }
                        else if (currentCommand.Name.Equals(Constants.Tuck))
                        {
                            Stack.Tuck();
                        }
                        else if (currentCommand.Name.Equals(Constants.Roll))
                        {
                            Stack.Roll();
                        }
                        else if (currentCommand.Name.Equals(Constants.Pick))
                        {
                            Stack.Pick();
                        }
                        else if (currentCommand.Name.Equals(Constants.Cr))
                        {
                            Console.WriteLine();
                        }
                        else if (
                            currentCommand.Name.Equals(Constants.Add) ||
                            currentCommand.Name.Equals(Constants.Subtract) ||
                            currentCommand.Name.Equals(Constants.Multiply) ||
                            currentCommand.Name.Equals(Constants.Modulus) ||
                            currentCommand.Name.Equals(Constants.Divide) ||
                            currentCommand.Name.Equals(Constants.GreaterThan) ||
                            currentCommand.Name.Equals(Constants.LessThan) ||
                            currentCommand.Name.Equals(Constants.GreaterThanOrEqual) ||
                            currentCommand.Name.Equals(Constants.LessThanOrEqual) ||
                            currentCommand.Name.Equals(Constants.Equal) ||
                            currentCommand.Name.Equals(Constants.NotEqual) ||
                            currentCommand.Name.Equals(Constants.And) ||
                            currentCommand.Name.Equals(Constants.Or) ||
                            currentCommand.Name.Equals(Constants.Not)
                            )
                        {
                            if (_ioMode == IoModeEnum.Fraction)
                            {
                                Stack.FloatMaths(currentCommand.Name);
                            }
                            else
                            {
                                Stack.IntMaths(currentCommand.Name);
                            }
                        }
                        else
                        {
                            throw new Exception(string.Format(Resources.UnknownItem, currentCommand.Name));
                        }
                    }
                }

                // Increment to next token
                currentCommandIndex++;
            }
        }
示例#12
0
        /// <summary>
        /// Main Parser function. Takes string of tokens and parses into Command elements.
        /// Most Commands will just be plain strings, but some ('if', 'loop' etc. will be
        /// dedicated commands with properties specifying the sub-commands to be executed)
        /// </summary>
        /// <param name="tokens">Array of tokens to parse</param>
        /// <param name="tokenIndex">Initial token index</param>
        /// <param name="stopTokens">Array of stop-tokens. E.g. 'If' parsing should stop on 'else' or 'endif'</param>
        /// <returns>Array of Command objects</returns>
        public static Command[] Parse(string[] tokens, ref int tokenIndex, string[] stopTokens)
        {
            List <Command> parsedTokens = new List <Command>();

            while (tokenIndex < tokens.Length)
            {
                string token = tokens[tokenIndex];
                if (token.Equals(Constants.If))
                {
                    IfCommand ifCommand = new IfCommand();

                    tokenIndex++;
                    ifCommand.IfCommands.AddRange(Parse(tokens, ref tokenIndex,
                                                        new[] { Constants.Else, Constants.EndIf }));
                    // Only parse the following tokens in our 'if' statement if the next token after the 'then' phase is *not*
                    // 'endif'. This is to handle 'else-less' 'if's where we are only programmed to handle what happens when
                    // the 'if' evaluation is true, and to do nothing when the 'if' evaluation is false.
                    if (tokenIndex >= 1 && !tokens[tokenIndex - 1].Equals(Constants.EndIf))
                    {
                        ifCommand.ElseCommands.AddRange(Parse(tokens, ref tokenIndex, new[] { Constants.EndIf }));
                    }

                    parsedTokens.Add(ifCommand);
                }
                else if (token.Equals(Constants.Loop))
                {
                    LoopCommand loopCommand = new LoopCommand();

                    tokenIndex++;
                    loopCommand.LoopCommands.AddRange(Parse(tokens, ref tokenIndex, new[] { Constants.EndLoop }));

                    parsedTokens.Add(loopCommand);
                }
                else if (token.Equals(Constants.Repeat))
                {
                    RepeatCommand repeatCommand = new RepeatCommand();

                    tokenIndex++;
                    repeatCommand.RepeatCommands.AddRange(Parse(tokens, ref tokenIndex,
                                                                new[] { Constants.Until }));

                    parsedTokens.Add(repeatCommand);
                }
                else
                {
                    // For anything that's not an 'if', or loop, just add the string as a command.
                    // The executor can handle if it's not an actual command
                    parsedTokens.Add(new Command(token));

                    if ((stopTokens != null) && (stopTokens.Contains(token)))
                    {
                        tokenIndex++;
                        return(parsedTokens.ToArray());
                    }

                    tokenIndex++;
                }
            }

            if (stopTokens != null)
            {
                // If we get here then 'stopTokens' was set to something that should terminate a sequence of commands,
                // but wasn't found. E.G. An 'if' without an 'endif'.
                throw new Exception(string.Format(Resources.Expected_, string.Join("/", stopTokens)));
            }

            return(parsedTokens.ToArray());
        }