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