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); } } }