namespace HeuristicLab.Problems.ProgramSynthesis.Push.Expressions {
using HeuristicLab.Problems.ProgramSynthesis.Push.Attributes;
using HeuristicLab.Problems.ProgramSynthesis.Push.Interpreter;
using HeuristicLab.Problems.ProgramSynthesis.Push.Stack;
///
/// Pushes a copy of an indexed item "deep" in the stack onto the top of the stack, without removing the deep item.
/// The index is taken from the INTEGER stack, and the indexing is done after the index is removed.
///
/// Stacktype
public abstract class YankDuplicateExpression : StatelessExpression {
public void Eval(IStack stack, IStack integerStack) {
T item;
if (this.TryGetItem(stack, integerStack, out item)) stack.Push(item);
}
public void Eval(IStack stack, IStack integerStack) {
Expression item;
if (this.TryGetItem(stack, integerStack, out item)) stack.Push(item);
}
public void Eval(IStack integerStack) {
if ((integerStack.Count < 2) || (integerStack.Top > integerStack.Count - 2) ||
(integerStack.Top < 0)) return;
var index = (int)integerStack.Pop();
var item = integerStack.ReverseElementAt(index);
integerStack.Push(item);
}
private bool TryGetItem(IStack stack, IStack integerStack, out E item) {
if ((integerStack.Count == 0) ||
(integerStack.Top >= stack.Count) ||
(integerStack.Top < 0) ||
(stack.Count < 2)) {
item = default(E);
return false;
}
var index = (int)integerStack.Pop();
item = stack.ReverseElementAt(index);
return true;
}
}
[PushExpression(StackType.Integer, "INTEGER.YANKDUP")]
public class IntegerYankDuplicateExpression : YankDuplicateExpression {
public override void Eval(IPushGpInterpreter interpreter) {
this.Eval(interpreter.IntegerStack);
}
}
[PushExpression(StackType.Float, "FLOAT.YANKDUP")]
public class FloatYankDuplicateExpression : YankDuplicateExpression {
public override void Eval(IPushGpInterpreter interpreter) {
this.Eval(interpreter.FloatStack, interpreter.IntegerStack);
}
}
[PushExpression(StackType.Boolean, "BOOLEAN.YANKDUP")]
public class BooleanYankDuplicateExpression : YankDuplicateExpression {
public override void Eval(IPushGpInterpreter interpreter) {
this.Eval(interpreter.BooleanStack, interpreter.IntegerStack);
}
}
[PushExpression(StackType.Name, "NAME.YANKDUP")]
public class NameYankDuplicateExpression : YankDuplicateExpression {
public override void Eval(IPushGpInterpreter interpreter) {
this.Eval(interpreter.NameStack, interpreter.IntegerStack);
}
}
[PushExpression(StackType.Exec, "EXEC.YANKDUP")]
public class ExecYankDuplicateExpression : YankDuplicateExpression {
public override void Eval(IPushGpInterpreter interpreter) {
this.Eval(interpreter.ExecStack, interpreter.IntegerStack);
}
}
[PushExpression(StackType.Code, "CODE.YANKDUP")]
public class CodeYankDuplicateExpression : YankDuplicateExpression {
public override void Eval(IPushGpInterpreter interpreter) {
this.Eval(interpreter.CodeStack, interpreter.IntegerStack);
}
}
}