コード例 #1
0
        public override object Clone()
        {
            StepAndRepeatCmdLine stepAndRepeatCmdLine = MemberwiseClone() as StepAndRepeatCmdLine;

            stepAndRepeatCmdLine.Origin        = Origin.Clone() as PointD;
            stepAndRepeatCmdLine.HorizontalEnd = HorizontalEnd.Clone() as PointD;
            stepAndRepeatCmdLine.VerticalEnd   = VerticalEnd.Clone() as PointD;
            stepAndRepeatCmdLine.DoCmdLineList = new List <DoCmdLine>();
            foreach (DoCmdLine doCmdLine in DoCmdLineList)
            {
                stepAndRepeatCmdLine.DoCmdLineList.Add(doCmdLine.Clone() as DoCmdLine);
            }
            return(stepAndRepeatCmdLine);
        }
コード例 #2
0
        /// <summary>
        /// 解析指令
        /// 注意: 传递的实际原点坐标值,是引用当前模块的指令(DO, DO MULTIPASS)里面的坐标值;如果当前模块是FluidProgram,则原点值为(0, 0)
        /// </summary>
        /// <param name="origin">当前模块实际原点坐标</param>
        /// <param name="parent">包含当前模块的外层模块, 一个模块解析后对应的是RunnableModule类型,所以parent类型是RunnableModule</param>
        /// <param name="level">当前模块所处的层级,Program为0,Workpiece为1,以此类推</param>
        /// <returns>解析结果. 如果解析成功,携带对应的RunnableModule;如果解析失败,携带出错行CmdLine、出错描述信息</returns>
        private Result parse(CommandsModule commandsModule, PointD origin, RunnableModule parent, int level, int boardNo)
        {
            Pattern        currPattern    = commandsModule as Pattern;
            RunnableModule runnableModule = new RunnableModule(commandsModule, origin);

            runnableModule.BoardNo = boardNo;
            // workpiece下面所有拼版根据因引用的Do指令或DoMultiPass指令的Valve设定拼版
            if (level == 2)
            {
                runnableModule.Valve = (commandsModule as Pattern).Valve;
                if (runnableModule.Valve == Drive.ValveSystem.ValveType.Valve1)
                {
                    runnableModule.Mode     = ModuleMode.AssignMode1;
                    runnableModule.SaveMode = ModuleMode.AssignMode1;
                }
                else if (runnableModule.Valve == Drive.ValveSystem.ValveType.Valve2)
                {
                    runnableModule.Mode     = ModuleMode.AssignMode2;
                    runnableModule.SaveMode = ModuleMode.AssignMode2;
                }
                else if (runnableModule.Valve == Drive.ValveSystem.ValveType.Both)
                {
                    runnableModule.Mode     = ModuleMode.DualFallow;
                    runnableModule.SaveMode = ModuleMode.DualFallow;
                }
            }
            if (level > 2)
            {
                runnableModule.Valve    = parent.Valve;
                runnableModule.Mode     = parent.Mode;
                runnableModule.SaveMode = parent.SaveMode;
            }
            program.ModuleStructure.AddModule(runnableModule, parent, level);
            // 是否已经遇到END:
            bool ended = false;
            // 记录当前处在什么类型的子句中,例如:loop block, pass block
            BlockState blockState = new BlockState();
            // 开始解析:
            List <CmdLine> cmdLineList;

            cmdLineList = new List <CmdLine>(commandsModule.CmdLineList);
            CmdLine          cmdLine             = null;
            bool             hasPassBlock        = false;
            int              lastPassblockIndex  = -1;
            MeasureHeightCmd curMeasureHeightCmd = null;

            //增加螺杆阀的速度、重量键值对
            Dictionary <int, double> svValvespeedDic = new Dictionary <int, double>();

            //TODO 将5换为阀参数设置的默认值,10换为默认值
            svValvespeedDic.Add(5, 10);

            for (int i = 0; i < cmdLineList.Count; i++)
            {
                cmdLine = cmdLineList[i];

                // 忽略被禁用的命令
                if (!cmdLine.Enabled)
                {
                    continue;
                }

                // END: 后面不允许添加任何命令
                if (ended)
                {
                    return(new Result(false, cmdLine, "No commands is allowed to be added after END"));
                }

                if (cmdLine is SetHeightSenseModeCmdLine)
                {
                    runnableModule.AddCommand(new SetHeightSenseModeCmd(runnableModule, cmdLine as SetHeightSenseModeCmdLine));
                }
                else if (cmdLine is MarkCmdLine)
                {
                    // Mark点命令必须处在最前面
                    if (i > 0)
                    {
                        // 寻找Mark点前面的Enable==true且不是注释的命令
                        CmdLine lastestCmdLine = getLastestEnabledCmdLine(cmdLineList, i - 1);
                        if (lastestCmdLine != null && !(lastestCmdLine is MarkCmdLine))
                        {
                            return(new Result(false, cmdLine, "MARK must be added before the other command types."));
                        }
                    }
                    if (findMarkCmdLineIndex(cmdLineList, cmdLine as MarkCmdLine) > 1)
                    {
                        return(new Result(false, cmdLine, "MARK number can not be more than 2."));
                    }
                    MarkCmd markCmd = new MarkCmd(runnableModule, cmdLine as MarkCmdLine);
                    runnableModule.AddCommand(markCmd);
                    program.ModuleStructure.RecordMarkPoint(runnableModule, markCmd);
                }
                else if (cmdLine is BadMarkCmdLine)
                {
                    //// 屏蔽原因 : BadMark模式由每个拼版只有一个 改为 测高指令那种模式
                    //// BadMark点命令必须处在非Mark命令的前面
                    //if (i > 0)
                    //{
                    //    // 寻找Bad Mark点前面的Enable==true且不是注释的命令
                    //    CmdLine lastestCmdLine = getLastestEnabledCmdLine(cmdLineList, i - 1);
                    //    if (lastestCmdLine != null && !(lastestCmdLine is MarkCmdLine))
                    //    {
                    //        // 当前指令前面有非Mark指令,判断是否是BadMark,每个pattern只能添加一个BadMark
                    //        if (lastestCmdLine is BadMarkCmdLine)
                    //        {
                    //            return new Result(false, cmdLine, "Only one BADMARK command can be added per pattern");
                    //        }
                    //        else
                    //        {
                    //            return new Result(false, cmdLine, "BADMARK must be added before the non-mark command types.");
                    //        }
                    //    }
                    //}
                    BadMarkCmd badMarkCmd = new BadMarkCmd(runnableModule, cmdLine as BadMarkCmdLine);
                    runnableModule.AddCommand(badMarkCmd);
                    program.ModuleStructure.RecordBadMarkPoint(runnableModule, badMarkCmd);
                }
                else if (cmdLine is MeasureCmdLine)
                {
                    MeasureCmd measureCmd = new MeasureCmd(runnableModule, cmdLine as MeasureCmdLine);
                    runnableModule.AddCommand(measureCmd);
                    //记录检测指令里的测高
                    program.ModuleStructure.RecordMeasureGlueHTCmds(runnableModule, measureCmd);
                }
                else if (cmdLine is BlobsCmdLine)
                {
                    BlobsCmd blobsCmd = new BlobsCmd(runnableModule, cmdLine as BlobsCmdLine);
                    runnableModule.AddCommand(blobsCmd);
                    program.ModuleStructure.RecordBlobsCmds(runnableModule, blobsCmd);
                }
                else if (cmdLine is BarcodeCmdLine)
                {
                    BarcodeCmd barcodeCmd = new BarcodeCmd(runnableModule, cmdLine as BarcodeCmdLine);
                    runnableModule.AddCommand(barcodeCmd);
                    program.ModuleStructure.RecordBarcodeCmds(runnableModule, barcodeCmd);
                }
                else if (cmdLine is ConveyorBarcodeCmdLine)
                {
                    ConveyorBarcodeCmd conveyorBarcodeCmd = new ConveyorBarcodeCmd(runnableModule, cmdLine as ConveyorBarcodeCmdLine);
                    runnableModule.AddCommand(conveyorBarcodeCmd);
                }
                else if (cmdLine is MeasureHeightCmdLine)
                {
                    MeasureHeightCmdLine measureHeightCmdLine = cmdLine as MeasureHeightCmdLine;
                    curMeasureHeightCmd = new MeasureHeightCmd(runnableModule, measureHeightCmdLine);
                    runnableModule.AddCommand(curMeasureHeightCmd);
                    program.ModuleStructure.RecordMeasureHeightPoint(runnableModule, curMeasureHeightCmd);
                }
                else if (cmdLine is NozzleCheckCmdLine)
                {
                    if (level > 1)
                    {
                        cmdLine.Valve = runnableModule.Valve;
                    }
                    runnableModule.AddCommand(new NozzleCheckCmd(runnableModule, cmdLine as NozzleCheckCmdLine, curMeasureHeightCmd));
                }
                else if (cmdLine is SymbolLinesCmdLine)
                {
                    if (level > 1)
                    {
                        cmdLine.Valve = runnableModule.Valve;
                    }
                    SymbolLinesCmdLine symbolLinesCmdLine = cmdLine as SymbolLinesCmdLine;
                    SymbolLinesCmd     symbolLinesCmd     = new SymbolLinesCmd(runnableModule, symbolLinesCmdLine);
                    runnableModule.AddCommand(symbolLinesCmd);
                    foreach (MeasureHeightCmd item in symbolLinesCmd.GetAllMeasureCmdLineList())
                    {
                        if (item == null)
                        {
                            continue;
                        }
                        program.ModuleStructure.RecordMeasureHeightPoint(runnableModule, item);
                    }
                    program.ModuleStructure.RecordSymbolLinesCmd(runnableModule, symbolLinesCmd);
                }
                else if (cmdLine is MultiTracesCmdLine)
                {
                    if (level > 1)
                    {
                        cmdLine.Valve = runnableModule.Valve;
                    }
                    runnableModule.AddCommand(new MultiTracesCmd(runnableModule, cmdLine as MultiTracesCmdLine, curMeasureHeightCmd));
                }
                else if (cmdLine is DotCmdLine)
                {
                    if (level > 1)
                    {
                        cmdLine.Valve = runnableModule.Valve;
                    }
                    runnableModule.AddCommand(new DotCmd(runnableModule, cmdLine as DotCmdLine, curMeasureHeightCmd));
                }
                else if (cmdLine is FinishShotCmdLine)
                {
                    if (level > 1)
                    {
                        cmdLine.Valve = runnableModule.Valve;
                    }
                    runnableModule.AddCommand(new FinishShotCmd(runnableModule, cmdLine as FinishShotCmdLine, curMeasureHeightCmd));
                }
                else if (cmdLine is LineCmdLine) // 包含了 cmdLine is SnakeLineCmdLine
                {
                    if (level > 1)
                    {
                        cmdLine.Valve = runnableModule.Valve;
                    }
                    runnableModule.AddCommand(new LineCmd(runnableModule, cmdLine as LineCmdLine, curMeasureHeightCmd));
                }
                else if (cmdLine is ArcCmdLine) // 包含了 CircleCmdLine
                {
                    if (level > 1)
                    {
                        cmdLine.Valve = runnableModule.Valve;
                    }
                    runnableModule.AddCommand(new ArcCmd(runnableModule, cmdLine as ArcCmdLine, curMeasureHeightCmd));
                }
                else if (cmdLine is CircleCmdLine)
                {
                    if (level > 1)
                    {
                        cmdLine.Valve = runnableModule.Valve;
                    }
                    runnableModule.AddCommand(new ArcCmd(runnableModule, cmdLine as CircleCmdLine, curMeasureHeightCmd));
                }
                else if (cmdLine is MoveXyCmdLine)
                {
                    runnableModule.AddCommand(new MoveXyCmd(runnableModule, cmdLine as MoveXyCmdLine));
                }
                else if (cmdLine is MoveAbsXyCmdLine)
                {
                    runnableModule.AddCommand(new MoveAbsXyCmd(runnableModule, cmdLine as MoveAbsXyCmdLine));
                }
                else if (cmdLine is MoveAbsZCmdLine)
                {
                    runnableModule.AddCommand(new MoveAbsZCmd(runnableModule, cmdLine as MoveAbsZCmdLine));
                }
                else if (cmdLine is MoveToLocationCmdLine)
                {
                    MoveToLocationCmdLine moveToLocationCmdLine = cmdLine as MoveToLocationCmdLine;
                    // 检测系统预定义坐标名称是否存在
                    if (runnableModule.CommandsModule.program.UserPositions.Find(x => x.Name == moveToLocationCmdLine.PositionName) == null)
                    {
                        return(new Result(false, cmdLine, "\'" + moveToLocationCmdLine.PositionName + "\' is not defined in system."));
                    }
                    runnableModule.AddCommand(new MoveToLocationCmd(runnableModule, moveToLocationCmdLine));
                }
                else if (cmdLine is NormalTimerCmdLine)
                {
                    // TIMER不能放在pass block里面
                    if (blockState.Type == BlockType.PASS_BLOCK)
                    {
                        return(new Result(false, cmdLine, "TIMER must not be added in pass block"));
                    }
                    runnableModule.AddCommand(new NormalTimerCmd(runnableModule, cmdLine as NormalTimerCmdLine));
                }
                else if (cmdLine is TimerCmdLine)
                {
                    // TIMER必须在pass block里面
                    if (blockState.Type != BlockType.PASS_BLOCK)
                    {
                        return(new Result(false, cmdLine, "TIMER must be added in pass block"));
                    }
                    // TIMER必须是END PASS的前一个命令行,也就是说TIMER必须是分组内的最后一个命令行
                    if (i >= cmdLineList.Count - 1 || !(cmdLineList[i + 1] is EndPassCmdLine))
                    {
                        return(new Result(false, cmdLine, "TIMER must be added before END PASS."));
                    }
                    //// TIMER不能放在最后一个分组中,无意义
                    //if (i + 2 <= cmdLineList.Count - 1 && !(cmdLineList[i + 2] is StartPassCmdLine))
                    //{
                    //    return new Result(false, cmdLine, "TIMER is no need to be added in the last pass block.");
                    //}
                    runnableModule.AddCommand(new TimerCmd(runnableModule, cmdLine as TimerCmdLine));
                }
                else if (cmdLine is StepAndRepeatCmdLine)
                {
                    StepAndRepeatCmdLine stepAndRepeatCmdLine = cmdLine as StepAndRepeatCmdLine;
                    Pattern pattern = program.GetPatternByName(stepAndRepeatCmdLine.PatternName);
                    if (pattern == null)
                    {
                        return(new Result(false, cmdLine, "Pattern '" + stepAndRepeatCmdLine.PatternName + "' is not found."));
                    }
                    if (pattern.HasPassBlocks)
                    {
                        return(new Result(false, cmdLine, "Pattern '" + pattern.Name + "' can not contain pass blocks."));
                    }
                    if (pattern.IsContainItself)
                    {
                        return(new Result(false, cmdLine, "Pattern '" + pattern.Name + "' can not contain itself."));
                    }
                    cmdLineList.InsertRange(i + 1, (cmdLine as StepAndRepeatCmdLine).DoCmdLineList);
                }
                else if (cmdLine is DoCmdLine)
                {
                    DoCmdLine doCmdLine = cmdLine as DoCmdLine;
                    Pattern   pattern   = program.GetPatternByName(doCmdLine.PatternName);
                    if (pattern == null)
                    {
                        return(new Result(false, cmdLine, "Pattern '" + doCmdLine.PatternName + "' is not found."));
                    }
                    //设置父级Pattern,建立Pattern的引用关系
                    pattern.ParentPattern = currPattern;
                    currPattern?.AddChild(pattern);
                    Logger.DEFAULT.Debug(this.GetType().Name, string.Format("{0}'s parent pattern is {1}", pattern.Name, currPattern?.Name));

                    if (pattern.HasPassBlocks)
                    {
                        return(new Result(false, cmdLine, "Pattern '" + pattern.Name + "' can not contain pass blocks."));
                    }
                    if (pattern.Name == commandsModule.Name)
                    {
                        return(new Result(false, cmdLine, "Pattern '" + pattern.Name + "' can not contain itself."));
                    }
                    if (checkExitInAncestorNode(pattern, runnableModule))
                    {
                        return(new Result(false, cmdLine, "Pattern '" + pattern.Name + "' can not contain itself."));
                    }
                    pattern.Valve = doCmdLine.Valve;
                    //倒序
                    if (doCmdLine.Reverse)
                    {
                        pattern = pattern.ReversePattern();
                    }
                    if (level > 0)
                    {
                        if (runnableModule.BoardNo != 0)
                        {
                            doCmdLine.BoardNo = runnableModule.BoardNo;
                        }
                        program.ModuleStructure.AddBoardNo(doCmdLine.BoardNo);
                    }
                    Result result = parse(pattern, doCmdLine.Origin, runnableModule, level + 1, doCmdLine.BoardNo);
                    if (!result.IsOk)
                    {
                        return(result);
                    }
                    // 拼版穴位号逻辑
                    (result.Param as RunnableModule).BoardNo = doCmdLine.BoardNo;
                    runnableModule.AddCommand(new DoCmd(runnableModule, result.Param as RunnableModule, curMeasureHeightCmd));
                }
                else if (cmdLine is DoMultiPassCmdLine)
                {
                    if (blockState.Type != BlockType.LOOP_BLOCK)
                    {
                        return(new Result(false, cmdLine, "DO MULTIPASS must be added in loop block."));
                    }
                    DoMultiPassCmdLine doMultiPassCmdLine = cmdLine as DoMultiPassCmdLine;
                    Pattern            pattern            = program.GetPatternByName(doMultiPassCmdLine.PatternName);
                    //设置父级Pattern,建立Pattern的引用关系
                    pattern.ParentPattern = currPattern;
                    if (pattern == null)
                    {
                        return(new Result(false, cmdLine, "Pattern '" + doMultiPassCmdLine.PatternName + "' is not found."));
                    }
                    currPattern?.AddChild(pattern);
                    Logger.DEFAULT.Debug(this.GetType().Name, string.Format("{0}'s parent pattern is {1}", pattern.Name, currPattern?.Name));

                    if (pattern.IsContainItself)
                    {
                        return(new Result(false, cmdLine, "Pattern '" + pattern.Name + "' can not contain itself."));
                    }
                    pattern.Valve = doMultiPassCmdLine.Valve;
                    if (level > 0)
                    {
                        if (runnableModule.BoardNo != 0)
                        {
                            doMultiPassCmdLine.BoardNo = runnableModule.BoardNo;
                        }
                        program.ModuleStructure.AddBoardNo(doMultiPassCmdLine.BoardNo);
                    }
                    Result result = parse(pattern, doMultiPassCmdLine.Origin, runnableModule, level + 1, doMultiPassCmdLine.BoardNo);
                    if (!result.IsOk)
                    {
                        return(result);
                    }
                    if (!pattern.HasPassBlocks)
                    {
                        return(new Result(false, cmdLine, "Pattern '" + doMultiPassCmdLine.PatternName + "' has no pass blocks."));
                    }
                    // 拼版穴位号逻辑
                    (result.Param as RunnableModule).BoardNo = doMultiPassCmdLine.BoardNo;
                    // 此处先暂时添加在cmdList中,在结尾处,对处于子句中的语句,集中处理。
                    runnableModule.AddCommand(new DoMultipassCmd(runnableModule, result.Param as RunnableModule, curMeasureHeightCmd));
                }
                else if (cmdLine is LoopPassCmdLine)
                {
                    if (blockState.Type != BlockType.NONE)
                    {
                        return(new Result(false, cmdLine, blockState.NoEndDescription));
                    }
                    blockState.Type        = BlockType.LOOP_BLOCK;
                    blockState.BlockCmdObj = new LoopBlockCmd(runnableModule, cmdLine as LoopPassCmdLine);
                }
                else if (cmdLine is NextLoopCmdLine)
                {
                    if (blockState.Type != BlockType.LOOP_BLOCK)
                    {
                        return(new Result(false, cmdLine, "LOOP PASS is not found for the loop block."));
                    }
                    //不同拼版的同一个分组只需要一个计时器,不需要每个拼版都记一次时间
                    LoopBlockCmd loopBlockCmd = blockState.BlockCmdObj as LoopBlockCmd;
                    for (int doMultiPassCmdIndex = 1; doMultiPassCmdIndex < loopBlockCmd.DoMultipassCmdList.Count; doMultiPassCmdIndex++)
                    {
                        RunnableModule tempModule = loopBlockCmd.DoMultipassCmdList[doMultiPassCmdIndex].AssociatedRunnableModule;
                        foreach (Command item in tempModule.CmdList)
                        {
                            if (item is PassBlockCmd)
                            {
                                (item as PassBlockCmd).CmdList.RemoveAll(data => data is TimerCmd);
                            }
                        }
                    }
                    runnableModule.AddCommand(blockState.BlockCmdObj as LoopBlockCmd);
                    blockState.Reset();
                }
                else if (cmdLine is StartPassCmdLine)
                {
                    if (blockState.Type != BlockType.NONE)
                    {
                        return(new Result(false, cmdLine, blockState.NoEndDescription));
                    }
                    // 当前pass block序号必须比上一个pass block序号大
                    if ((cmdLine as StartPassCmdLine).Index <= lastPassblockIndex)
                    {
                        return(new Result(false, cmdLine, "Current pass block index must be bigger than the previous."));
                    }
                    // 相邻pass block之间不允许添加指令
                    if (hasPassBlock && !(cmdLineList[i - 1] is EndPassCmdLine))
                    {
                        return(new Result(false, cmdLine, "No commands is allowed to be added between pass blocks."));
                    }
                    blockState.Type        = BlockType.PASS_BLOCK;
                    blockState.BlockCmdObj = new PassBlockCmd(runnableModule, cmdLine as StartPassCmdLine);
                }
                else if (cmdLine is EndPassCmdLine)
                {
                    if (blockState.Type != BlockType.PASS_BLOCK)
                    {
                        return(new Result(false, cmdLine, "START PASS is not found for the pass block"));
                    }
                    PassBlockCmd passBlockCmd = blockState.BlockCmdObj as PassBlockCmd;
                    runnableModule.AddCommand(passBlockCmd);
                    hasPassBlock       = true;
                    lastPassblockIndex = passBlockCmd.Index;
                    blockState.Reset();
                }
                else if (cmdLine is EndCmdLine)
                {
                    ended = true;
                }
                else if (cmdLine is PurgeCmdLine)
                {
                    if (commandsModule is Pattern)
                    {
                        cmdLine.Valve = (commandsModule as Pattern).Valve;
                    }
                    runnableModule.AddCommand(new PurgeCmd(runnableModule, cmdLine as PurgeCmdLine));
                }
                else if (cmdLine is ChangeSpeedCmdLine)
                {
                    ChangeSpeedCmdLine changeSpeedCmdLine = cmdLine as ChangeSpeedCmdLine;

                    if (svValvespeedDic.ContainsKey(changeSpeedCmdLine.Speed))
                    {
                    }
                    else if (this.program.RuntimeSettings.VavelSpeedDic.ContainsKey(changeSpeedCmdLine.Speed))
                    {
                        double value;
                        this.program.RuntimeSettings.VavelSpeedDic.TryGetValue(changeSpeedCmdLine.Speed, out value);
                        svValvespeedDic.Add(changeSpeedCmdLine.Speed, value);
                    }
                    else
                    {
                        //TODO 将10替换为默认参数
                        svValvespeedDic.Add(changeSpeedCmdLine.Speed, 10);
                    }

                    runnableModule.AddCommand(new ChangeSpeedCmd(runnableModule, changeSpeedCmdLine));

                    //传递程序中的速度重量键值对
                    SvOrGearValveSpeedWeightValve.VavelSpeedWeightDic = FluidProgram.CurrentOrDefault().RuntimeSettings.VavelSpeedDic;
                }

                // 处理包含在子句中的语句:
                if (blockState.Type != BlockType.NONE && runnableModule.CmdList.Count > 0)
                {
                    switch (blockState.Type)
                    {
                    case BlockType.LOOP_BLOCK:
                        if (!(cmdLine is LoopPassCmdLine))
                        {
                            if (!(cmdLine is DoMultiPassCmdLine))
                            {
                                return(new Result(false, cmdLine, "Only DO MULTIPASS can be added in loop block."));
                            }
                            (blockState.BlockCmdObj as LoopBlockCmd).DoMultipassCmdList.Add(runnableModule.GetCommandAtTail() as DoMultipassCmd);
                            runnableModule.RemoveCommandAtTail();
                        }
                        break;

                    case BlockType.PASS_BLOCK:
                        if (!(cmdLine is StartPassCmdLine))
                        {
                            (blockState.BlockCmdObj as PassBlockCmd).CmdList.Add(runnableModule.GetCommandAtTail());
                            runnableModule.RemoveCommandAtTail();
                        }
                        break;
                    }
                }
            }

            //替换Program中的SvValveDic
            this.program.RuntimeSettings.VavelSpeedDic = svValvespeedDic;

            var lastCmdLine = getLastestEnabledCmdLine(cmdLineList, cmdLineList.Count - 1);

            // 检查子句命令是否完成
            if (blockState.Type != BlockType.NONE)
            {
                return(new Result(false, lastCmdLine, blockState.NoEndDescription));
            }
            // 必须以END命令结尾
            if (!ended)
            {
                return(new Result(false, lastCmdLine, "END is not found."));
            }

            return(new Result(true, runnableModule));
        }