Changeset 15017 for branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/DoCountExpressions.cs
- Timestamp:
- 06/01/17 09:28:34 (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/DoCountExpressions.cs
r14952 r15017 1 1 namespace HeuristicLab.Problems.ProgramSynthesis.Push.Expressions { 2 2 using System; 3 using Attributes; 4 using Interpreter; 5 using Persistence.Default.CompositeSerializers.Storable; 6 using Stack; 3 7 4 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; 5 using HeuristicLab.Problems.ProgramSynthesis.Push.Attributes; 6 using HeuristicLab.Problems.ProgramSynthesis.Push.Interpreter; 7 using HeuristicLab.Problems.ProgramSynthesis.Push.Stack; 8 8 /// <summary> 9 /// An iteration instruction that performs a loop (the body of which is taken from the CODE stack) the number of times 10 /// indicated by the INTEGER argument, pushing an index (which runs from zero to one less than the number of iterations) onto the 11 /// INTEGER stack prior to each execution of the loop body. This should be implemented as a macro that expands into a call to 12 /// CODE.DO*RANGE. CODE.DO*COUNT takes a single INTEGER argument (the number of times that the loop will be executed) and a single 13 /// CODE argument (the body of the loop). If the provided INTEGER argument is negative or zero then this becomes a NOOP. Otherwise it 14 /// expands into: ( 0 '1 - IntegerArg>' CODE.QUOTE 'CodeArg' CODE.DO*RANGE ) 15 /// </summary> 9 16 [Serializable] 10 17 [StorableClass] 11 public abstract class DoCountExpression : LoopExpression { 18 [PushExpression(StackTypes.Code, "CODE.DO*COUNT", StackTypes.Integer)] 19 public class CodeDoCountExpression : StatelessExpression { 12 20 13 protected DoCountExpression() { } 14 protected DoCountExpression(LoopState state) : base(state) { } 21 public CodeDoCountExpression() { } 15 22 [StorableConstructor] 16 protected DoCountExpression(bool deserializing) : base(deserializing) { } 17 protected override bool HasInsufficientArguments(IInternalPushInterpreter interpreter, IPushStack<Expression> sourceStack) { 18 return interpreter.IntegerStack.Count < 1 || 19 sourceStack.Count == 0 || 20 interpreter.IntegerStack.Top <= 0; 23 protected CodeDoCountExpression(bool deserializing) : base(deserializing) { } 24 public override void Eval(IInternalPushInterpreter interpreter) { 25 var destinationIndex = interpreter.IntegerStack.Top; 26 interpreter.IntegerStack.Top = 0; 27 interpreter.IntegerStack.Push(destinationIndex); 28 29 interpreter.ExecStack.Push(ExpressionTable.GetStatelessExpression<CodeDoRangeExpression>()); 21 30 } 22 31 23 protected override LoopState InitState(IInternalPushInterpreter interpreter, IPushStack<Expression> sourceStack) { 24 var state = LoopState.Create(interpreter.PoolContainer.LoopStatePool, 25 body: sourceStack.Pop(), 26 currentIndex: 1, 27 destinationIndex: interpreter.IntegerStack.Top, 28 incrementor: 1); 29 30 interpreter.IntegerStack.SetTop(0); 31 32 return state; 32 public override bool IsNoop(IInternalPushInterpreter interpreter) { 33 return interpreter.IntegerStack.IsEmpty || 34 interpreter.IntegerStack.Top < 1 || 35 interpreter.CodeStack.IsEmpty; 33 36 } 34 37 } 35 38 36 39 /// <summary> 37 /// An iteration instruction that performs a loop (the body of which is taken from the CODE stack) the number of times 38 /// indicated by 39 /// the INTEGER argument, pushing an index (which runs from zero to one less than the number of iterations) onto the 40 /// INTEGER stack 41 /// prior to each execution of the loop body. This should be implemented as a macro that expands into a call to 42 /// CODE.DO*RANGE. 43 /// CODE.DO*COUNT takes a single INTEGER argument (the number of times that the loop will be executed) and a single 44 /// CODE argument 45 /// (the body of the loop). If the provided INTEGER argument is negative or zero then this becomes a NOOP. Otherwise it 46 /// expands into: 47 /// ( 0 '1 - IntegerArg>' CODE.QUOTE 'CodeArg' CODE.DO*RANGE ) 40 /// An iteration instruction that performs a loop (the body of which is taken from the EXEC stack) the number of times 41 /// indicated by the INTEGER argument, pushing an index (which runs from zero to one less than the number of iterations) onto the 42 /// INTEGER stack prior to each execution of the loop body. This is similar to CODE.DO*COUNT except that it takes its code 43 /// argument from the EXEC stack. This should be implemented as a macro that expands into a call to EXEC.DO*RANGE. EXEC.DO*COUNT 44 /// takes a single INTEGER argument (the number of times that the loop will be executed) and a single EXEC argument (the body of the 45 /// loop). If the provided INTEGER argument is negative or zero then this becomes a NOOP. Otherwise it expands into: 46 /// ( 0 '1 - IntegerArg' EXEC.DO* RANGE'ExecArg' ) 48 47 /// </summary> 49 48 [Serializable] 50 49 [StorableClass] 51 [PushExpression(StackTypes.Code, "CODE.DO*COUNT", StackTypes.Integer)] 52 public class CodeDoCountExpression : DoCountExpression { 53 54 public CodeDoCountExpression() { } 55 public CodeDoCountExpression(LoopState state) : base(state) { } 56 [StorableConstructor] 57 protected CodeDoCountExpression(bool deserializing) : base(deserializing) { } 58 public override bool IsNoop(IInternalPushInterpreter interpreter) { 59 return State.Body == null && HasInsufficientArguments(interpreter, interpreter.CodeStack); 60 } 61 62 public override void Eval(IInternalPushInterpreter interpreter) { 63 Eval(interpreter, interpreter.CodeStack); 64 } 65 66 protected override LoopExpression Clone(LoopState state, IInternalPushInterpreter interpreter) { 67 var expression = interpreter.PoolContainer.GetStatefulExpression<CodeDoCountExpression>(); 68 expression.State = state; 69 70 return expression; 71 } 72 } 73 74 /// <summary> 75 /// An iteration instruction that performs a loop (the body of which is taken from the EXEC stack) the number of times 76 /// indicated 77 /// by the INTEGER argument, pushing an index (which runs from zero to one less than the number of iterations) onto the 78 /// INTEGER 79 /// stack prior to each execution of the loop body. This is similar to CODE.DO*COUNT except that it takes its code 80 /// argument from 81 /// the EXEC stack. This should be implemented as a macro that expands into a call to EXEC.DO*RANGE. EXEC.DO*COUNT 82 /// takes a single 83 /// INTEGER argument (the number of times that the loop will be executed) and a single EXEC argument (the body of the 84 /// loop). If 85 /// the provided INTEGER argument is negative or zero then this becomes a NOOP. Otherwise it expands into: 86 /// ( 0 '1 - IntegerArg' EXEC.DO* RANGE'ExecArg' ) 87 /// </summary> 88 [Serializable] 89 [StorableClass] 90 [PushExpression(StackTypes.Exec, "EXEC.DO*COUNT", StackTypes.Integer)] 91 public class ExecDoCountExpression : DoCountExpression { 50 [PushExpression(StackTypes.Exec, "EXEC.DO*COUNT", StackTypes.Integer, execIn: 1)] 51 public class ExecDoCountExpression : StatelessExpression { 92 52 public ExecDoCountExpression() { } 93 public ExecDoCountExpression(LoopState state) : base(state) { }94 53 [StorableConstructor] 95 54 protected ExecDoCountExpression(bool deserializing) : base(deserializing) { } 96 55 97 56 public override void Eval(IInternalPushInterpreter interpreter) { 98 Eval(interpreter, interpreter.ExecStack); 57 var destinationIndex = interpreter.IntegerStack.Top; 58 interpreter.IntegerStack.Top = 0; 59 interpreter.IntegerStack.Push(destinationIndex); 60 61 interpreter.ExecStack.Push(ExpressionTable.GetStatelessExpression<ExecDoRangeExpression>()); 99 62 } 100 63 101 64 public override bool IsNoop(IInternalPushInterpreter interpreter) { 102 return State.Body == null && HasInsufficientArguments(interpreter, interpreter.ExecStack); 103 } 104 105 protected override LoopExpression Clone(LoopState state, IInternalPushInterpreter interpreter) { 106 var expression = interpreter.PoolContainer.GetStatefulExpression<ExecDoCountExpression>(); 107 expression.State = state; 108 109 return expression; 65 return interpreter.IntegerStack.IsEmpty || 66 interpreter.IntegerStack.Top < 1 || 67 interpreter.ExecStack.IsEmpty; 110 68 } 111 69 }
Note: See TracChangeset
for help on using the changeset viewer.