1 | namespace HeuristicLab.Algorithms.PushGP.Expressions {
|
---|
2 | using HeuristicLab.Algorithms.PushGP.Interpreter;
|
---|
3 | using HeuristicLab.Algorithms.PushGP.Stack;
|
---|
4 |
|
---|
5 | public abstract class DoCountExpression : LoopExpression {
|
---|
6 | protected override bool HasInsufficientArguments(IPushGpInterpreter interpreter, IStack<Expression> sourceStack) {
|
---|
7 | return (interpreter.IntegerStack.Count < 1) || (sourceStack.Count == 0) || (interpreter.IntegerStack.Top <= 0);
|
---|
8 | }
|
---|
9 |
|
---|
10 | protected override void InitState(IPushGpInterpreter interpreter, IStack<Expression> sourceStack) {
|
---|
11 | this.State.Body = sourceStack.Pop();
|
---|
12 | this.State.DestinationIndex = interpreter.IntegerStack.Top;
|
---|
13 | this.State.CurrentIndex = 1;
|
---|
14 | this.State.Incrementor = 1;
|
---|
15 |
|
---|
16 | interpreter.IntegerStack.SetTop(0);
|
---|
17 | }
|
---|
18 | }
|
---|
19 |
|
---|
20 | /// <summary>
|
---|
21 | /// An iteration instruction that performs a loop (the body of which is taken from the CODE stack) the number of times
|
---|
22 | /// indicated by
|
---|
23 | /// the INTEGER argument, pushing an index (which runs from zero to one less than the number of iterations) onto the
|
---|
24 | /// INTEGER stack
|
---|
25 | /// prior to each execution of the loop body. This should be implemented as a macro that expands into a call to
|
---|
26 | /// CODE.DO*RANGE.
|
---|
27 | /// CODE.DO*COUNT takes a single INTEGER argument (the number of times that the loop will be executed) and a single
|
---|
28 | /// CODE argument
|
---|
29 | /// (the body of the loop). If the provided INTEGER argument is negative or zero then this becomes a NOOP. Otherwise it
|
---|
30 | /// expands into:
|
---|
31 | /// ( 0 '1 - IntegerArg>' CODE.QUOTE 'CodeArg' CODE.DO*RANGE )
|
---|
32 | /// </summary>
|
---|
33 | public class CodeDoCountExpression : DoCountExpression {
|
---|
34 | protected override string InitStringRepresentation() {
|
---|
35 | return "CODE.DO*COUNT";
|
---|
36 | }
|
---|
37 |
|
---|
38 | public override void Eval(IPushGpInterpreter interpreter) {
|
---|
39 | this.Eval(interpreter, interpreter.CodeStack);
|
---|
40 | }
|
---|
41 | }
|
---|
42 |
|
---|
43 | /// <summary>
|
---|
44 | /// An iteration instruction that performs a loop (the body of which is taken from the EXEC stack) the number of times
|
---|
45 | /// indicated
|
---|
46 | /// by the INTEGER argument, pushing an index (which runs from zero to one less than the number of iterations) onto the
|
---|
47 | /// INTEGER
|
---|
48 | /// stack prior to each execution of the loop body. This is similar to CODE.DO*COUNT except that it takes its code
|
---|
49 | /// argument from
|
---|
50 | /// the EXEC stack. This should be implemented as a macro that expands into a call to EXEC.DO*RANGE. EXEC.DO*COUNT
|
---|
51 | /// takes a single
|
---|
52 | /// INTEGER argument (the number of times that the loop will be executed) and a single EXEC argument (the body of the
|
---|
53 | /// loop). If
|
---|
54 | /// the provided INTEGER argument is negative or zero then this becomes a NOOP. Otherwise it expands into:
|
---|
55 | /// ( 0 '1 - IntegerArg' EXEC.DO* RANGE'ExecArg' )
|
---|
56 | /// </summary>
|
---|
57 | public class ExecDoCountExpression : DoCountExpression {
|
---|
58 | protected override string InitStringRepresentation() {
|
---|
59 | return "EXEC.DO*COUNT";
|
---|
60 | }
|
---|
61 |
|
---|
62 | public override void Eval(IPushGpInterpreter interpreter) {
|
---|
63 | this.Eval(interpreter, interpreter.ExecStack);
|
---|
64 | }
|
---|
65 | }
|
---|
66 | } |
---|