/// <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); }