namespace HeuristicLab.Problems.ProgramSynthesis.Push.Expressions {
using System;
using Attributes;
using Interpreter;
using Persistence.Default.CompositeSerializers.Storable;
using Stack;
///
/// An iteration instruction that performs a loop (the body of which is taken from the CODE stack) the number of times
/// indicated by the INTEGER argument, pushing an index (which runs from zero to one less than the number of iterations) onto the
/// INTEGER stack prior to each execution of the loop body. This should be implemented as a macro that expands into a call to
/// CODE.DO*RANGE. CODE.DO*COUNT takes a single INTEGER argument (the number of times that the loop will be executed) and a single
/// CODE argument (the body of the loop). If the provided INTEGER argument is negative or zero then this becomes a NOOP. Otherwise it
/// expands into: ( 0 '1 - IntegerArg>' CODE.QUOTE 'CodeArg' CODE.DO*RANGE )
///
[Serializable]
[StorableClass]
[PushExpression(
StackTypes.Code,
"CODE.DO*COUNT",
"An iteration instruction that performs a loop (the body of which is taken from the CODE stack) the number of times indicated by the INTEGER argument, pushing an index (which runs from zero to one less than the number of iterations) onto the INTEGER stack prior to each execution of the loop body.",
StackTypes.Integer)]
public class CodeDoCountExpression : StatelessExpression {
public CodeDoCountExpression() { }
[StorableConstructor]
protected CodeDoCountExpression(bool deserializing) : base(deserializing) { }
public override void Eval(IInternalPushInterpreter interpreter) {
var destinationIndex = interpreter.IntegerStack.Top;
interpreter.IntegerStack.Top = 0;
interpreter.IntegerStack.Push(destinationIndex);
interpreter.ExecStack.Push(ExpressionTable.GetStatelessExpression());
}
public override bool IsNoop(IInternalPushInterpreter interpreter) {
return interpreter.IntegerStack.IsEmpty ||
interpreter.IntegerStack.Top < 1 ||
interpreter.CodeStack.IsEmpty;
}
}
///
/// An iteration instruction that performs a loop (the body of which is taken from the EXEC stack) the number of times
/// indicated by the INTEGER argument, pushing an index (which runs from zero to one less than the number of iterations) onto the
/// INTEGER stack prior to each execution of the loop body. This is similar to CODE.DO*COUNT except that it takes its code
/// argument from the EXEC stack. This should be implemented as a macro that expands into a call to EXEC.DO*RANGE. EXEC.DO*COUNT
/// takes a single INTEGER argument (the number of times that the loop will be executed) and a single EXEC argument (the body of the
/// loop). If the provided INTEGER argument is negative or zero then this becomes a NOOP. Otherwise it expands into:
/// ( 0 '1 - IntegerArg' EXEC.DO* RANGE'ExecArg' )
///
[Serializable]
[StorableClass]
[PushExpression(
StackTypes.Exec,
"EXEC.DO*COUNT",
"An iteration instruction that performs a loop (the body of which is taken from the EXEC stack) the number of times indicated by the INTEGER argument, pushing an index (which runs from zero to one less than the number of iterations) onto the INTEGER stack prior to each execution of the loop body.",
StackTypes.Integer,
requiredBlockCount: 1)]
public class ExecDoCountExpression : StatelessExpression {
public ExecDoCountExpression() { }
[StorableConstructor]
protected ExecDoCountExpression(bool deserializing) : base(deserializing) { }
public override void Eval(IInternalPushInterpreter interpreter) {
var destinationIndex = interpreter.IntegerStack.Top;
interpreter.IntegerStack.Top = 0;
interpreter.IntegerStack.Push(destinationIndex);
interpreter.ExecStack.Push(ExpressionTable.GetStatelessExpression());
}
public override bool IsNoop(IInternalPushInterpreter interpreter) {
return interpreter.IntegerStack.IsEmpty ||
interpreter.IntegerStack.Top < 1 ||
interpreter.ExecStack.IsEmpty;
}
}
}