Exemplo n.º 1
0
        /// <summary>
        /// Create the appropriate element and the appropriate quantifier
        /// </summary>
        /// <param name="Item">The elemen to compile</param>
        /// <param name="Parent">The parent parsed block</param>
        /// <param name="Compiled">The parent compiled block</param>
        private void CompileElement(Parse.Element Item, Parse.Block Parent, Block Compiled)
        {
            //Just create a NOP for a null item
            if (Item == null)
            {
                Compiled.AddItem(new NOP());

                return;
            }

            //Anotate Item's commands
            if (Output != null)
            {
                Item.Annotation.CompiledPosition.Begin = Output.Length;
            }

            _OutIdent++;
            OutComment(Item.GetType().Name + Item.Quantifier);

            //Check for quantifier
            QuantifierBefore qb = null;

            if (!Item.Quantifier.IsDefault())
            {
                if (Item.Quantifier.IsIfAny())
                {
                    //Nothing, just add NOP after
                }
                else if (Item.Quantifier.IsAsMany() && !Item.Quantifier.Additive)
                {
                    //Nothing, just add a ConditionalJump after
                }
                else if (Item.Quantifier.IsNever())
                {
                    //Nothing, add a Fail and a NOP after
                }
                else
                {
                    qb = new QuantifierBefore(Item.Quantifier);
                    Compiled.AddItem(qb);
                }
            }

            int first_runnable_execution_index = Compiled.Count;

            //Find item's type
            if (Item is Parse.Block)
            {
                Parse.Block pabl = (Parse.Block)Item;
                Block       bl;

                //New block if it is unnamed, or get the stub
                if (pabl.Name == null)
                {
                    bl = new Block(this);
                }
                else
                {
                    bl = _BlocksByName[pabl.Name];
                }

                //Compile it
                CompileBlock(pabl, bl);

                //Create a call to the block
                Compiled.AddItem(new CallBlock(bl.ExecuteBlock));

                //Update it's index
                bl.ExecuteIndex = Compiled.Items[first_runnable_execution_index];
            }
            else if (Item is Parse.TextSearch)
            {
                CETextSearch((Parse.TextSearch)Item, Parent, Compiled);
            }
            else if (Item is Parse.Literal)
            {
                CELiterall((Parse.Literal)Item, Compiled);
            }
            else if (Item is Parse.Variable)
            {
                CEVariable((Parse.Variable)Item, Parent, Compiled);
            }
            else if (Item is Parse.ControlFlow)
            {
                CEControlFlow((Parse.ControlFlow)Item, Parent, Compiled);
            }
            else if (Item is Parse.FunctionCall)
            {
                CEFunctionCall((Parse.FunctionCall)Item, Parent, Compiled);
            }
            else if (Item is Parse.BinaryOperator)
            {
                CEBinaryOperator((Parse.BinaryOperator)Item, Parent, Compiled);
            }
            else
            {
                Compiled.AddItem(new NOP());
                ThrowParseError("Unkown type " + Item.GetType().Name, Item.Annotation.SourcePosition);
            }

            int last_runnable_execute_index = Compiled.Count - 1;

            //Check for quantifier
            if (!Item.Quantifier.IsDefault())
            {
                if (Item.Quantifier.IsIfAny())
                {
                    //On failure jump here
                    var nop = new NOP();
                    Compiled.AddItem(nop);

                    //Update Runnables
                    CESetOnJumpFailTo(Compiled, first_runnable_execution_index, last_runnable_execute_index, nop);
                }
                else if (Item.Quantifier.IsAsMany() && !Item.Quantifier.Additive)
                {
                    //On failure jump here
                    var cj = new ConditionalJump(Compiled.Items[first_runnable_execution_index]);
                    Compiled.AddItem(cj);

                    //Update Runnables
                    CESetOnJumpFailTo(Compiled, first_runnable_execution_index, last_runnable_execute_index, cj);
                }
                else if (Item.Quantifier.IsNever())
                {
                    //Fail if the item succeeds
                    Compiled.AddItem(new ReturnBlock(0, false));

                    //On failure jump here
                    var nop = new NOP();
                    Compiled.AddItem(nop);

                    //Update Runnables
                    CESetOnJumpFailTo(Compiled, first_runnable_execution_index, last_runnable_execute_index, nop);
                }
                else
                {
                    //On failure jump here
                    var qa = new QuantifierAfter(qb);
                    Compiled.AddItem(qa);

                    //Update Runnables
                    CESetOnJumpFailTo(Compiled, first_runnable_execution_index, last_runnable_execute_index, qa);
                }
            }

            //Anotate Item's commands
            if (Output != null)
            {
                Item.Annotation.CompiledPosition.End = Output.Length;
            }

            _OutIdent--;

            Item.Annotation.FirstRunnable       = Compiled.Items[first_runnable_execution_index];
            Item.Annotation.RunnablesCount      = Compiled.Count - first_runnable_execution_index;
            Item.Annotation.RunnableParentBlock = Compiled.ExecuteBlock;
            for (int i = first_runnable_execution_index; i < Compiled.Count; i++)
            {
                var rn = Compiled.Items[i];
                if (rn.Annotation.Element == null)
                {
                    rn.Annotation.Element        = Item;
                    rn.Annotation.SourcePosition = Item.Annotation.SourcePosition;
                    rn.Annotation.TreeViewNode   = Item.Annotation.TreeViewNode;
                }
            }
            IDE.CompiledAnnotations.Add(Item.Annotation.CompiledPosition, Item.Annotation);
        }
        /// <summary>
        /// Create the appropriate element and the appropriate quantifier
        /// </summary>
        /// <param name="Item">The elemen to compile</param>
        /// <param name="Parent">The parent parsed block</param>
        /// <param name="Compiled">The parent compiled block</param>
        private void CompileElement(Parse.Element Item, Parse.Block Parent, Block Compiled)
        {
            //Just create a NOP for a null item
            if (Item == null)
            {
                Compiled.AddItem(new NOP());

                return;
            }

            //Anotate Item's commands
            if (Output != null)
                Item.Annotation.CompiledPosition.Begin = Output.Length;

            _OutIdent++;
            OutComment(Item.GetType().Name + Item.Quantifier);

            //Check for quantifier
            QuantifierBefore qb = null;
            if (!Item.Quantifier.IsDefault())
            {
                if (Item.Quantifier.IsIfAny())
                {
                    //Nothing, just add NOP after
                }
                else if (Item.Quantifier.IsAsMany() && !Item.Quantifier.Additive)
                {
                    //Nothing, just add a ConditionalJump after
                }
                else if (Item.Quantifier.IsNever())
                {
                    //Nothing, add a Fail and a NOP after
                }
                else
                {
                    qb = new QuantifierBefore(Item.Quantifier);
                    Compiled.AddItem(qb);
                }
            }

            int first_runnable_execution_index = Compiled.Count;

            //Find item's type
            if (Item is Parse.Block)
            {
                Parse.Block pabl = (Parse.Block)Item;
                Block bl;

                //New block if it is unnamed, or get the stub
                if (pabl.Name == null)
                    bl = new Block(this);
                else
                    bl = _BlocksByName[pabl.Name];

                //Compile it
                CompileBlock(pabl, bl);

                //Create a call to the block
                Compiled.AddItem(new CallBlock(bl.ExecuteBlock));

                //Update it's index
                bl.ExecuteIndex = Compiled.Items[first_runnable_execution_index];
            }
            else if (Item is Parse.TextSearch)
                CETextSearch((Parse.TextSearch) Item, Parent, Compiled);
            else if (Item is Parse.Literal)
                CELiterall((Parse.Literal) Item, Compiled);
            else if (Item is Parse.Variable)
                CEVariable((Parse.Variable) Item, Parent, Compiled);
            else if (Item is Parse.ControlFlow)
                CEControlFlow((Parse.ControlFlow) Item, Parent, Compiled);
            else if (Item is Parse.FunctionCall)
                CEFunctionCall((Parse.FunctionCall) Item, Parent, Compiled);
            else if (Item is Parse.BinaryOperator)
                CEBinaryOperator((Parse.BinaryOperator) Item, Parent, Compiled);
            else
            {
                Compiled.AddItem(new NOP());
                ThrowParseError("Unkown type " + Item.GetType().Name, Item.Annotation.SourcePosition);
            }

            int last_runnable_execute_index = Compiled.Count - 1;

            //Check for quantifier
            if (!Item.Quantifier.IsDefault())
            {
                if (Item.Quantifier.IsIfAny())
                {
                    //On failure jump here
                    var nop = new NOP();
                    Compiled.AddItem(nop);

                    //Update Runnables
                    CESetOnJumpFailTo(Compiled, first_runnable_execution_index, last_runnable_execute_index, nop);
                }
                else if (Item.Quantifier.IsAsMany() && !Item.Quantifier.Additive)
                {
                    //On failure jump here
                    var cj = new ConditionalJump(Compiled.Items[first_runnable_execution_index]);
                    Compiled.AddItem(cj);

                    //Update Runnables
                    CESetOnJumpFailTo(Compiled, first_runnable_execution_index, last_runnable_execute_index, cj);
                }
                else if (Item.Quantifier.IsNever())
                {
                    //Fail if the item succeeds
                    Compiled.AddItem(new ReturnBlock(0, false));

                    //On failure jump here
                    var nop = new NOP();
                    Compiled.AddItem(nop);

                    //Update Runnables
                    CESetOnJumpFailTo(Compiled, first_runnable_execution_index, last_runnable_execute_index, nop);
                }
                else
                {
                    //On failure jump here
                    var qa = new QuantifierAfter(qb);
                    Compiled.AddItem(qa);

                    //Update Runnables
                    CESetOnJumpFailTo(Compiled, first_runnable_execution_index, last_runnable_execute_index, qa);
                }
            }

            //Anotate Item's commands
            if (Output != null)
                Item.Annotation.CompiledPosition.End = Output.Length;

            _OutIdent--;

            Item.Annotation.FirstRunnable = Compiled.Items[first_runnable_execution_index];
            Item.Annotation.RunnablesCount = Compiled.Count - first_runnable_execution_index;
            Item.Annotation.RunnableParentBlock = Compiled.ExecuteBlock;
            for (int i = first_runnable_execution_index ; i < Compiled.Count ; i++)
            {
                var rn = Compiled.Items[i];
                if (rn.Annotation.Element == null)
                {
                    rn.Annotation.Element = Item;
                    rn.Annotation.SourcePosition = Item.Annotation.SourcePosition;
                    rn.Annotation.TreeViewNode = Item.Annotation.TreeViewNode;
                }
            }
            IDE.CompiledAnnotations.Add(Item.Annotation.CompiledPosition, Item.Annotation);
        }