Free cookie consent management tool by TermsFeed Policy Generator

source: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/DoRangeExpressions.cs @ 14744

Last change on this file since 14744 was 14744, checked in by pkimmesw, 7 years ago

#2665 Renamings due to typos, ManagedPool tests, Skip Noops in Debugger

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