Changeset 14513 for branches/PushGP/HeuristicLab.Algorithms.PushGP/HeuristicLab.Algorithms.PushGP/Expressions/DoRangeExpressions.cs
- Timestamp:
- 12/20/16 22:57:11 (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/PushGP/HeuristicLab.Algorithms.PushGP/HeuristicLab.Algorithms.PushGP/Expressions/DoRangeExpressions.cs
r14398 r14513 1 using HeuristicLab.Algorithms.PushGP.Interpreter;2 using HeuristicLab.Algorithms.PushGP.Stack;3 using HeuristicLab.Common;1 namespace HeuristicLab.Algorithms.PushGP.Expressions { 2 using HeuristicLab.Algorithms.PushGP.Interpreter; 3 using HeuristicLab.Algorithms.PushGP.Stack; 4 4 5 namespace HeuristicLab.Algorithms.PushGP.Expressions 6 { 7 public abstract class DoRangeExpression : LoopExpression 8 { 9 public DoRangeExpression() 10 { } 11 12 public DoRangeExpression(LoopExpression origin, Cloner cloner) : base(origin, cloner) 13 { } 14 15 protected override bool HasInsufficientArguments(IInterpreter interpreter, IStack<Expression> sourceStack) 16 { 17 return interpreter.IntegerStack.Count < 2 || 18 sourceStack.Count == 0 || 19 interpreter.IntegerStack.Top == interpreter.IntegerStack.ReverseElementAt(1); 20 } 21 22 protected override void InitState(IInterpreter interpreter, IStack<Expression> sourceStack) 23 { 24 body = sourceStack.Pop(); 25 destinationIndex = interpreter.IntegerStack.Pop(); 26 currentIndex = interpreter.IntegerStack.Top; 27 incrementor = destinationIndex < currentIndex ? -1 : 1; 28 currentIndex += incrementor; 29 } 5 public abstract class DoRangeExpression : LoopExpression { 6 protected override bool HasInsufficientArguments(IPushGpInterpreter interpreter, IStack<Expression> sourceStack) { 7 return (interpreter.IntegerStack.Count < 2) || (sourceStack.Count == 0) 8 || (interpreter.IntegerStack.Top == interpreter.IntegerStack.ReverseElementAt(1)); 30 9 } 31 10 32 /// <summary> 33 /// An iteration instruction that executes the top item on the CODE stack a number of times that depends on the 34 /// top two integers, while also pushing the loop counter onto the INTEGER stack for possible access during the execution of 35 /// the body of the loop. The top integer is the "destination index" and the second integer is the "current index." First the code 36 /// and the integer arguments are saved locally and popped. Then the integers are compared. If the integers are equal then the current 37 /// index is pushed onto the INTEGER stack and the code (which is the "body" of the loop) is pushed onto the EXEC stack for subsequent 38 /// execution. If the integers are not equal then the current index will still be pushed onto the INTEGER stack but two items will be 39 /// pushed onto the EXEC stack -- first a recursive call to CODE.DO*RANGE (with the same code and destination index, but with a current 40 /// index that has been either incremented or decremented by 1 to be closer to the destination index) and then the body code. Note that 41 /// the range is inclusive of both endpoints; a call with integer arguments 3 and 5 will cause its body to be executed 3 times, with the 42 /// loop counter having the values 3, 4, and 5. Note also that one can specify a loop that "counts down" by providing a destination index 43 /// that is less than the specified current index. 44 /// </summary> 45 public class CodeDoRangeExpression : DoRangeExpression 46 { 47 public CodeDoRangeExpression() 48 { } 11 protected override void InitState(IPushGpInterpreter interpreter, IStack<Expression> sourceStack) { 12 this.State.Body = sourceStack.Pop(); 13 this.State.DestinationIndex = interpreter.IntegerStack.Pop(); 14 this.State.CurrentIndex = interpreter.IntegerStack.Top; 15 this.State.Incrementor = this.State.DestinationIndex < this.State.CurrentIndex ? -1 : 1; 16 this.State.CurrentIndex += this.State.Incrementor; 17 } 18 } 49 19 50 protected CodeDoRangeExpression(CodeDoRangeExpression origin, Cloner cloner) : base(origin, cloner) 51 { } 52 53 public override IDeepCloneable Clone(Cloner cloner) 54 { 55 return new CodeDoRangeExpression(this, cloner); 56 } 57 58 protected override string InitStringRepresentation() 59 { 60 return "CODE.DO*RANGE"; 61 } 62 63 public override void Eval(IInterpreter interpreter) 64 { 65 Eval(interpreter, interpreter.CodeStack); 66 } 20 /// <summary> 21 /// An iteration instruction that executes the top item on the CODE stack a number of times that depends on the 22 /// top two integers, while also pushing the loop counter onto the INTEGER stack for possible access during the 23 /// execution of 24 /// the body of the loop. The top integer is the "destination index" and the second integer is the "current index." 25 /// First the code 26 /// and the integer arguments are saved locally and popped. Then the integers are compared. If the integers are equal 27 /// then the current 28 /// index is pushed onto the INTEGER stack and the code (which is the "body" of the loop) is pushed onto the EXEC stack 29 /// for subsequent 30 /// execution. If the integers are not equal then the current index will still be pushed onto the INTEGER stack but two 31 /// items will be 32 /// pushed onto the EXEC stack -- first a recursive call to CODE.DO*RANGE (with the same code and destination index, 33 /// but with a current 34 /// index that has been either incremented or decremented by 1 to be closer to the destination index) and then the body 35 /// code. Note that 36 /// the range is inclusive of both endpoints; a call with integer arguments 3 and 5 will cause its body to be executed 37 /// 3 times, with the 38 /// loop counter having the values 3, 4, and 5. Note also that one can specify a loop that "counts down" by providing a 39 /// destination index 40 /// that is less than the specified current index. 41 /// </summary> 42 public class CodeDoRangeExpression : DoRangeExpression { 43 protected override string InitStringRepresentation() { 44 return "CODE.DO*RANGE"; 67 45 } 68 46 69 /// <summary> 70 /// An iteration instruction that executes the top item on the EXEC stack a number of times that depends on the top two integers, 71 /// while also pushing the loop counter onto the INTEGER stack for possible access during the execution of the body of the loop. 72 /// This is similar to CODE.DO*COUNT except that it takes its code argument from the EXEC stack. The top integer is the 73 /// "destination index" and the second integer is the "current index." First the code and the integer arguments are saved locally 74 /// and popped. Then the integers are compared. If the integers are equal then the current index is pushed onto the INTEGER stack 75 /// and the code (which is the "body" of the loop) is pushed onto the EXEC stack for subsequent execution. If the integers are not 76 /// equal then the current index will still be pushed onto the INTEGER stack but two items will be pushed onto the EXEC stack 77 /// -- first a recursive call to EXEC.DO*RANGE (with the same code and destination index, but with a current index that has been 78 /// either incremented or decremented by 1 to be closer to the destination index) and then the body code. Note that the range is 79 /// inclusive of both endpoints; a call with integer arguments 3 and 5 will cause its body to be executed 3 times, with the loop 80 /// counter having the values 3, 4, and 5. Note also that one can specify a loop that "counts down" by providing a destination 81 /// index that is less than the specified current index. 82 /// </summary> 83 public class ExecDoRangeExpression : DoRangeExpression 84 { 85 public ExecDoRangeExpression() 86 { } 47 public override void Eval(IPushGpInterpreter interpreter) { 48 this.Eval(interpreter, interpreter.CodeStack); 49 } 50 } 87 51 88 protected ExecDoRangeExpression(ExecDoRangeExpression origin, Cloner cloner) : base(origin, cloner) 89 { } 52 /// <summary> 53 /// An iteration instruction that executes the top item on the EXEC stack a number of times that depends on the top two 54 /// integers, 55 /// while also pushing the loop counter onto the INTEGER stack for possible access during the execution of the body of 56 /// the loop. 57 /// This is similar to CODE.DO*COUNT except that it takes its code argument from the EXEC stack. The top integer is the 58 /// "destination index" and the second integer is the "current index." First the code and the integer arguments are 59 /// saved locally 60 /// and popped. Then the integers are compared. If the integers are equal then the current index is pushed onto the 61 /// INTEGER stack 62 /// and the code (which is the "body" of the loop) is pushed onto the EXEC stack for subsequent execution. If the 63 /// integers are not 64 /// equal then the current index will still be pushed onto the INTEGER stack but two items will be pushed onto the EXEC 65 /// stack 66 /// -- first a recursive call to EXEC.DO*RANGE (with the same code and destination index, but with a current index that 67 /// has been 68 /// either incremented or decremented by 1 to be closer to the destination index) and then the body code. Note that the 69 /// range is 70 /// inclusive of both endpoints; a call with integer arguments 3 and 5 will cause its body to be executed 3 times, with 71 /// the loop 72 /// counter having the values 3, 4, and 5. Note also that one can specify a loop that "counts down" by providing a 73 /// destination 74 /// index that is less than the specified current index. 75 /// </summary> 76 public class ExecDoRangeExpression : DoRangeExpression { 77 protected override string InitStringRepresentation() { 78 return "EXEC.DO*RANGE"; 79 } 90 80 91 public override IDeepCloneable Clone(Cloner cloner) 92 { 93 return new ExecDoRangeExpression(this, cloner); 94 } 95 96 protected override string InitStringRepresentation() 97 { 98 return "EXEC.DO*RANGE"; 99 } 100 101 public override void Eval(IInterpreter interpreter) 102 { 103 Eval(interpreter, interpreter.ExecStack); 104 } 81 public override void Eval(IPushGpInterpreter interpreter) { 82 this.Eval(interpreter, interpreter.ExecStack); 105 83 } 84 } 106 85 }
Note: See TracChangeset
for help on using the changeset viewer.