Пример #1
0
        /// <summary>
        /// Closes a block at the specified index.
        /// </summary>
        /// <param name="index">The index.</param>
        private void Close(int index)
        {
            var block = OpenedBlocks[index];

            // If the pending object is removed, we need to remove it from the parent container
            if (block.Parser != null)
            {
                if (!block.Parser.Close(this, block))
                {
                    block.Parent?.Remove(block);

                    if (block is LeafBlock leaf)
                    {
                        leaf.Lines.Release();
                    }
                }
                else
                {
                    // Invoke the Closed event
                    var blockClosed = block.Parser.GetClosedEvent;
                    blockClosed?.Invoke(this, block);
                }
            }
            OpenedBlocks.RemoveAt(index);
        }
Пример #2
0
        static private string WhileBlockAdd(int command_ptr, ref int NextIndex, ref int line_ptr, string Command, ref int?SkipTo, ref bool DontSkipNextCommand)
        {
            OpenedBlocks.Push(new Block(command_ptr, NextIndex, line_ptr, BlockType.While));
            string expression;
            var    res = GetNextExpression(Command, ref NextIndex, ref line_ptr, out expression, true);

            if (!res)
            {
                return("BAD_EXPRESSION");
            }
            bool while_result;
            var  Result = GetBoolFuncExpressionResult(expression, out while_result);

            if (Result == null)
            {
                DontSkipNextCommand = true;
                if (while_result)
                {
                    return(null);
                }
                else
                {
                    SkipTo = OpenedBlocks.Count - 1;
                    return(null);
                }
            }
            else
            {
                return(Result);
            }
        }
Пример #3
0
        /// <summary>
        /// Processes any new blocks that have been pushed to <see cref="NewBlocks"/>.
        /// </summary>
        /// <param name="result">The last result of matching.</param>
        /// <param name="allowClosing">if set to <c>true</c> the processing of a new block will close existing opened blocks].</param>
        /// <exception cref="InvalidOperationException">The NewBlocks is not empty. This is happening if a LeafBlock is not the last to be pushed</exception>
        private void ProcessNewBlocks(BlockState result, bool allowClosing)
        {
            var newBlocks = NewBlocks;

            while (newBlocks.Count > 0)
            {
                var block = newBlocks.Pop();

                if (block.Parser == null)
                {
                    ThrowHelper.InvalidOperationException($"The new block [{block.GetType()}] must have a valid Parser property");
                }

                block.Line = LineIndex;

                // If we have a leaf block
                var leaf = block as LeafBlock;
                if (leaf != null)
                {
                    if (!result.IsDiscard())
                    {
                        leaf.AppendLine(ref Line, Column, LineIndex, CurrentLineStartPosition);
                    }

                    if (newBlocks.Count > 0)
                    {
                        ThrowHelper.InvalidOperationException(
                            "The NewBlocks is not empty. This is happening if a LeafBlock is not the last to be pushed");
                    }
                }

                if (allowClosing)
                {
                    // Close any previous blocks not opened
                    CloseAll(false);
                }

                // If previous block is a container, add the new block as a children of the previous block
                if (block.Parent == null)
                {
                    UpdateLastBlockAndContainer();
                    CurrentContainer.Add(block);
                }

                block.IsOpen = result.IsContinue();

                // Add a block BlockProcessor to the stack (and leave it opened)
                OpenedBlocks.Add(block);

                if (leaf != null)
                {
                    ContinueProcessingLine = false;
                    return;
                }
            }

            ContinueProcessingLine = !result.IsDiscard();
        }
Пример #4
0
 private void Reset()
 {
     Line               = StringSlice.Empty;
     Column             = 0;
     ColumnBeforeIndent = 0;
     StartBeforeIndent  = 0;
     OpenedBlocks.Clear();
     NewBlocks.Clear();
 }
Пример #5
0
 /// <summary>
 /// Discards the specified block from the stack, remove from its parent.
 /// </summary>
 /// <param name="block">The block.</param>
 public void Discard(Block block)
 {
     for (int i = OpenedBlocks.Count - 1; i >= 1; i--)
     {
         if (OpenedBlocks[i] == block)
         {
             block.Parent.Remove(block);
             OpenedBlocks.RemoveAt(i);
             break;
         }
     }
 }
Пример #6
0
 /// <summary>
 /// Opens the specified block.
 /// </summary>
 /// <param name="block">The block.</param>
 /// <exception cref="ArgumentNullException"></exception>
 /// <exception cref="ArgumentException">The block must be opened</exception>
 public void Open(Block block)
 {
     if (block == null)
     {
         ThrowHelper.ArgumentNullException(nameof(block));
     }
     if (!block.IsOpen)
     {
         ThrowHelper.ArgumentException("The block must be opened", nameof(block));
     }
     OpenedBlocks.Add(block);
 }
Пример #7
0
        static private string Break(ref int?SkipTo, ref bool DontSkipNextCommand)
        {
            var BlockList = OpenedBlocks.ToList();

            for (var i = 0; i < BlockList.Count; i++)
            {
                if (BlockList[i].type == BlockType.While || BlockList[i].type == BlockType.For || BlockList[i].type == BlockType.DoUntil)
                {
                    DontSkipNextCommand = false;
                    SkipTo = BlockList.Count - i - 1;
                    return(null);
                }
            }
            return("BAD_BREAK");
        }
Пример #8
0
 static private string Continue(ref int command_ptr, ref int NextIndex, ref int line_ptr, ref bool DontSkipNextCommand)
 {
     while (OpenedBlocks.Count > 0)
     {
         var NextBlock = OpenedBlocks.Peek();
         if (NextBlock.type == BlockType.While || NextBlock.type == BlockType.For || NextBlock.type == BlockType.DoUntil)
         {
             command_ptr         = NextBlock.command_ptr;
             line_ptr            = NextBlock.line_ptr;
             NextIndex           = NextBlock.NextIndex;
             DontSkipNextCommand = false;
             return(null);
         }
         OpenedBlocks.Pop();
     }
     return("BAD_CONTINUE");
 }
Пример #9
0
        static private string DoUntilBlockProcess(ref int command_ptr, ref int NextIndex, ref int line_ptr, string Command)
        {
            var DoUntilBlock = OpenedBlocks.Peek();

            if (DoUntilBlock.type != BlockType.DoUntil)
            {
                return("BAD_BLOCK");
            }
            string expression;
            var    res = GetNextExpression(Command, ref NextIndex, ref line_ptr, out expression, true);

            if (!res)
            {
                return("BAD_EXPRESSION");
            }
            bool until_result;
            var  Result = GetBoolFuncExpressionResult(expression, out until_result);

            if (Result == null)
            {
                if (until_result)
                {
                    OpenedBlocks.Pop();
                    return(null);
                }
                else
                {
                    command_ptr = DoUntilBlock.command_ptr;
                    NextIndex   = DoUntilBlock.NextIndex;
                    line_ptr    = DoUntilBlock.line_ptr;
                    return(null);
                }
            }
            else
            {
                return(Result);
            }
        }
Пример #10
0
 internal bool IsOpen(Block block)
 {
     return(OpenedBlocks.Contains(block));
 }
Пример #11
0
        static private string ForBlockAdd(int command_ptr, ref int NextIndex, ref int line_ptr, string Command, ref int?SkipTo, ref bool DontSkipNextCommand)
        {
            var ForBlock = new Block(command_ptr, NextIndex, line_ptr, BlockType.For);

            if (!CheckNextSymbol(Command, NextIndex, ','))
            {
                var result = DefineVariable(ref NextIndex, ref line_ptr, Command, GetNextLiteral(Command, ref NextIndex, ref line_ptr), ForBlock, true);
                if (result != null)
                {
                    return(result);
                }
            }
            else
            {
                GetNextSymbol(Command, ref NextIndex, ref line_ptr);
            }
            ForBlock.NextIndex = NextIndex;
            ForBlock.line_ptr  = line_ptr;
            OpenedBlocks.Push(ForBlock);
            string expression;

            if (!CheckNextSymbol(Command, NextIndex, ','))
            {
                var res = GetNextExpression(Command, ref NextIndex, ref line_ptr, out expression, true);
                if (!res)
                {
                    return("BAD_EXPRESSION");
                }
            }
            else
            {
                GetNextSymbol(Command, ref NextIndex, ref line_ptr);
                expression = "true";
            }
            bool for_result;
            var  Result = GetBoolFuncExpressionResult(expression, out for_result);

            if (Result == null)
            {
                DontSkipNextCommand = true;
                var result = GetNextExpression(Command, ref NextIndex, ref line_ptr, out expression, true);
                if (for_result)
                {
                    if (result)
                    {
                        return(null);
                    }
                }
                else
                {
                    SkipTo = OpenedBlocks.Count - 1;
                    if (result)
                    {
                        return(null);
                    }
                }
                return("BAD_EXPRESSION");
            }
            else
            {
                return(Result);
            }
        }
Пример #12
0
 static private void DoUntilBlockAdd(int command_ptr, int NextIndex, int line_ptr)
 {
     OpenedBlocks.Push(new Block(command_ptr, NextIndex, line_ptr, BlockType.DoUntil));
 }