using System.Collections.Generic; namespace HeuristicLab.Problems.ProgramSynthesis.Push.Expressions { using System; using System.Linq; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.Problems.ProgramSynthesis.Push.Attributes; using HeuristicLab.Problems.ProgramSynthesis.Push.Interpreter; using HeuristicLab.Problems.ProgramSynthesis.Push.Stack; /// /// Iterates in reverse order (due to performance reasons) over the type vector using the code on the exec stack.If the vector isn't empty, expands to: /// ((first vector) (top-item :exec state) (rest vector) exec_do*vector_type (top-item :exec state) rest_of_program) /// /// [StorableClass] public abstract class VectorIterateExpression : StatelessExpression { protected VectorIterateExpression() { } [StorableConstructor] protected VectorIterateExpression(bool deserializing) : base(deserializing) { } protected bool IsNoop(IInternalPushInterpreter interpter, IPushStack> vectorStack) { return vectorStack.IsEmpty || interpter.ExecStack.IsEmpty; } protected void Eval(IInternalPushInterpreter interpter, IPushStack> vectorStack, IPushStack literalStack) { var vector = vectorStack.Top; if (vector.Count == 0) { interpter.ExecStack.Pop(); vectorStack.Pop(); } else if (vector.Count == 1) { literalStack.Push(vector[0]); vectorStack.Pop(); } else { interpter.ExecStack.Push(this, interpter.ExecStack.Top); var last = vector.Count - 1; literalStack.Push(vector[last]); var list = vector as List; if (list != null) { var newTop = new T[last]; list.CopyTo(0, newTop, 0, last); vectorStack.Top = newTop; return; } var array = vector as T[]; if (array != null) { var newTop = new T[last]; Array.Copy(array, 0, newTop, 0, last); vectorStack.Top = newTop; return; } vectorStack.Top = vector.Take(last).ToList(); } } } [StorableClass] [PushExpression( StackTypes.IntegerVector, "INTEGER[].ITERATE", "Iterates in reverse order (due to performance reasons) over the top INTEGER[] using the top item of the EXEC stack.", StackTypes.Integer | StackTypes.Exec, requiredBlockCount: 1)] public class IntegerVectorIterateExpression : VectorIterateExpression { public IntegerVectorIterateExpression() { } [StorableConstructor] protected IntegerVectorIterateExpression(bool deserializing) : base(deserializing) { } public override bool IsNoop(IInternalPushInterpreter interpreter) { return IsNoop(interpreter, interpreter.IntegerVectorStack); } public override void Eval(IInternalPushInterpreter interpreter) { Eval(interpreter, interpreter.IntegerVectorStack, interpreter.IntegerStack); } } [StorableClass] [PushExpression( StackTypes.FloatVector, "FLOAT[].ITERATE", "Iterates in reverse order (due to performance reasons) over the top FLOAT[] using the top item of the EXEC stack.", StackTypes.Float | StackTypes.Exec, requiredBlockCount: 1)] public class FloatVectorIterateExpression : VectorIterateExpression { public FloatVectorIterateExpression() { } [StorableConstructor] protected FloatVectorIterateExpression(bool deserializing) : base(deserializing) { } public override bool IsNoop(IInternalPushInterpreter interpreter) { return IsNoop(interpreter, interpreter.FloatVectorStack); } public override void Eval(IInternalPushInterpreter interpreter) { Eval(interpreter, interpreter.FloatVectorStack, interpreter.FloatStack); } } [StorableClass] [PushExpression( StackTypes.BooleanVector, "BOOLEAN[].ITERATE", "Iterates in reverse order (due to performance reasons) over the top BOOLEAN[] using the top item of the EXEC stack.", StackTypes.Boolean | StackTypes.Exec, requiredBlockCount: 1)] public class BooleanVectorIterateExpression : VectorIterateExpression { public BooleanVectorIterateExpression() { } [StorableConstructor] protected BooleanVectorIterateExpression(bool deserializing) : base(deserializing) { } public override bool IsNoop(IInternalPushInterpreter interpreter) { return IsNoop(interpreter, interpreter.BooleanVectorStack); } public override void Eval(IInternalPushInterpreter interpreter) { Eval(interpreter, interpreter.BooleanVectorStack, interpreter.BooleanStack); } } [StorableClass] [PushExpression( StackTypes.StringVector, "STRING[].ITERATE", "Iterates in reverse order (due to performance reasons) over the top STRING[] using the top item of the EXEC stack.", StackTypes.String | StackTypes.Exec, requiredBlockCount: 1)] public class StringVectorIterateExpression : VectorIterateExpression { public StringVectorIterateExpression() { } [StorableConstructor] protected StringVectorIterateExpression(bool deserializing) : base(deserializing) { } public override bool IsNoop(IInternalPushInterpreter interpreter) { return IsNoop(interpreter, interpreter.StringVectorStack); } public override void Eval(IInternalPushInterpreter interpreter) { Eval(interpreter, interpreter.StringVectorStack, interpreter.StringStack); } } }