namespace HeuristicLab.Problems.ProgramSynthesis.Push.Expressions {
using System;
using System.Linq;
using Attributes;
using Interpreter;
using Stack;
[PushExpression(StackTypes.String, "STRING.FROMINTEGER", StackTypes.Integer)]
public class StringFromIntegerExpression : StatelessExpression {
public override bool Eval(IInternalPushInterpreter interpreter) {
if (interpreter.IntegerStack.IsEmpty)
return false;
var value = interpreter.IntegerStack.Pop();
interpreter.StringStack.Push(value.ToString());
return true;
}
}
[PushExpression(StackTypes.String, "STRING.FROMFLOAT", StackTypes.Float)]
public class StringFromFloatExpression : StatelessExpression {
public override bool Eval(IInternalPushInterpreter interpreter) {
if (interpreter.FloatStack.IsEmpty)
return false;
var value = interpreter.FloatStack.Pop();
interpreter.StringStack.Push(value.ToString());
return true;
}
}
[PushExpression(StackTypes.String, "STRING.FROMBOOLEAN", StackTypes.Boolean)]
public class StringFromBooleanExpression : StatelessExpression {
public override bool Eval(IInternalPushInterpreter interpreter) {
if (interpreter.BooleanStack.IsEmpty)
return false;
var value = interpreter.BooleanStack.Pop();
interpreter.StringStack.Push(value.ToString());
return true;
}
}
[PushExpression(StackTypes.String, "STRING.FROMCHAR", StackTypes.Char)]
public class StringFromCharExpression : StatelessExpression {
public override bool Eval(IInternalPushInterpreter interpreter) {
if (interpreter.CharStack.IsEmpty)
return false;
var value = interpreter.CharStack.Pop();
interpreter.StringStack.Push(value.ToString());
return true;
}
}
[PushExpression(StackTypes.String, "STRING.CONCAT")]
public class StringConcatExpression : StatelessExpression {
public override bool Eval(IInternalPushInterpreter interpreter) {
if (interpreter.StringStack.Count < 2 ||
interpreter.StringStack.Top.Length + interpreter.StringStack.ReverseElementAt(1).Length >= interpreter.Configuration.MaxStringLength)
return false;
var str = interpreter.StringStack.Pop();
interpreter.StringStack.SetTop(str + interpreter.StringStack.Top);
return true;
}
}
///
/// Conj char onto string
///
[PushExpression(StackTypes.String, "STRING.CONJCHAR", StackTypes.Char)]
public class StringConjCharExpression : StatelessExpression {
public override bool Eval(IInternalPushInterpreter interpreter) {
if (interpreter.StringStack.IsEmpty ||
interpreter.CharStack.IsEmpty ||
interpreter.StringStack.Top.Length + 1 >= interpreter.Configuration.MaxStringLength)
return false;
var c = interpreter.CharStack.Pop();
interpreter.StringStack.SetTop(interpreter.StringStack.Top + c);
return true;
}
}
[PushExpression(StackTypes.String, "STRING.TAKE", StackTypes.Integer)]
public class StringTakeExpression : StatelessExpression {
public override bool Eval(IInternalPushInterpreter interpreter) {
if (interpreter.StringStack.IsEmpty ||
interpreter.IntegerStack.IsEmpty)
return false;
var value = interpreter.IntegerStack.Pop();
if (value < 0) {
return true;
}
var str = interpreter.StringStack.Top;
if (str.Length > 0) {
value = Math.Min(str.Length - 1, value);
interpreter.StringStack.SetTop(str.Substring(0, (int)value));
}
return true;
}
}
[PushExpression(StackTypes.String, "STRING.SUBSTRING", StackTypes.Integer)]
public class StringSubstringExpression : StatelessExpression {
public override bool Eval(IInternalPushInterpreter interpreter) {
if (interpreter.StringStack.IsEmpty ||
interpreter.IntegerStack.Count < 2)
return false;
var str = interpreter.StringStack.Top;
var values = interpreter.IntegerStack.Pop(2);
var first = Math.Min(str.Length - 1, Math.Max(values[0], 0));
var second = Math.Min(str.Length - 1, Math.Max(values[1], first));
var length = second - first;
if (length > 0)
interpreter.StringStack.SetTop(str.Substring((int)first, (int)length));
return true;
}
}
[PushExpression(StackTypes.String, "STRING.FIRST")]
public class StringFirstExpression : StatelessExpression {
public override bool Eval(IInternalPushInterpreter interpreter) {
if (interpreter.StringStack.IsEmpty ||
interpreter.StringStack.Top.Length == 0)
return false;
interpreter.StringStack.SetTop(interpreter.StringStack.Top[0].ToString());
return true;
}
}
[PushExpression(StackTypes.String, "STRING.LAST")]
public class StringLastExpression : StatelessExpression {
public override bool Eval(IInternalPushInterpreter interpreter) {
if (interpreter.StringStack.IsEmpty ||
interpreter.StringStack.Top.Length == 0)
return false;
var str = interpreter.StringStack.Top;
var c = str[str.Length - 1].ToString();
interpreter.StringStack.SetTop(c);
return true;
}
}
[PushExpression(StackTypes.String, "STRING.NTH", StackTypes.Integer)]
public class StringNthExpression : StatelessExpression {
public override bool Eval(IInternalPushInterpreter interpreter) {
if (interpreter.StringStack.IsEmpty ||
interpreter.IntegerStack.IsEmpty ||
interpreter.StringStack.Top.Length == 0)
return false;
var str = interpreter.StringStack.Top;
var index = str.Length == 1 ? 0 : (int)Math.Abs(interpreter.IntegerStack.Pop() % (str.Length - 1));
var c = str[index].ToString();
interpreter.StringStack.SetTop(c);
return true;
}
}
[PushExpression(StackTypes.String, "STRING.REST")]
public class StringRestExpression : StatelessExpression {
public override bool Eval(IInternalPushInterpreter interpreter) {
if (interpreter.StringStack.IsEmpty ||
interpreter.StringStack.Top.Length == 0)
return false;
var str = interpreter.StringStack.Top;
interpreter.StringStack.SetTop(str.Length == 1 ? string.Empty : str.Substring(1, str.Length - 1));
return true;
}
}
[PushExpression(StackTypes.String, "STRING.BUTLAST")]
public class StringButLastExpression : StatelessExpression {
public override bool Eval(IInternalPushInterpreter interpreter) {
if (interpreter.StringStack.IsEmpty ||
interpreter.StringStack.Top.Length == 0)
return false;
var str = interpreter.StringStack.Top;
interpreter.StringStack.SetTop(str.Length == 1 ? string.Empty : str.Substring(0, str.Length - 1));
return true;
}
}
[PushExpression(StackTypes.String, "STRING.LENGTH", StackTypes.Integer)]
public class StringLengthExpression : StatelessExpression {
public override bool Eval(IInternalPushInterpreter interpreter) {
if (interpreter.StringStack.IsEmpty)
return false;
var str = interpreter.StringStack.Pop();
interpreter.IntegerStack.Push(str.Length);
return true;
}
}
[PushExpression(StackTypes.String, "STRING.REVERSE")]
public class StringReverseExpression : StatelessExpression {
public override bool Eval(IInternalPushInterpreter interpreter) {
if (interpreter.StringStack.IsEmpty)
return false;
interpreter.StringStack.SetTop(interpreter.StringStack.Top.Reverse().ToString());
return true;
}
}
[PushExpression(StackTypes.String, "STRING.PARSETOCHARS")]
public class StringParseToCharsExpression : StatelessExpression {
public override bool Eval(IInternalPushInterpreter interpreter) {
if (interpreter.StringStack.IsEmpty)
return false;
if (interpreter.StringStack.Top.Length == 0) {
interpreter.StringStack.Pop();
return true;
}
var str = interpreter.StringStack.Top;
interpreter.StringStack.SetTop(str[0].ToString());
if (str.Length > 1) {
var chars = new string[str.Length - 1];
for (var i = 0; i < str.Length - 1; i++) {
chars[i] = str[i + 1].ToString();
}
interpreter.StringStack.Push(chars);
}
return true;
}
}
[PushExpression(StackTypes.String, "STRING.SPLIT")]
public class StringSplitExpression : StatelessExpression {
public override bool Eval(IInternalPushInterpreter interpreter) {
if (interpreter.StringStack.IsEmpty)
return false;
var words = interpreter.StringStack.Top.Trim().Split();
if (words.Length == 0)
return false;
interpreter.StringStack.SetTop(words[0]);
if (words.Length > 1)
interpreter.StringStack.Push(words, 1);
return true;
}
}
///
/// True if top string is empty
///
[PushExpression(StackTypes.String, "STRING.EMPTYSTRING", StackTypes.Boolean)]
public class StringEmptyStringExpression : StatelessExpression {
public override bool Eval(IInternalPushInterpreter interpreter) {
if (interpreter.StringStack.IsEmpty)
return false;
var str = interpreter.StringStack.Pop();
interpreter.BooleanStack.Push(str.Length == 0);
return true;
}
}
///
/// True if top string is a substring of second string; false otherwise
///
[PushExpression(StackTypes.String, "STRING.CONTAINS", StackTypes.Boolean)]
public class StringContainsExpression : StatelessExpression {
public override bool Eval(IInternalPushInterpreter interpreter) {
if (interpreter.StringStack.Count < 2)
return false;
var strings = interpreter.StringStack.Pop(2);
interpreter.BooleanStack.Push(strings[0].IndexOf(strings[1], StringComparison.Ordinal) >= 0);
return true;
}
}
///
/// True if the top char is in the top string
///
[PushExpression(StackTypes.String, "STRING.CONTAINSCHAR", StackTypes.Boolean | StackTypes.Char)]
public class StringContainsCharExpression : StatelessExpression {
public override bool Eval(IInternalPushInterpreter interpreter) {
if (interpreter.StringStack.IsEmpty ||
interpreter.CharStack.IsEmpty)
return false;
var str = interpreter.StringStack.Pop();
var c = interpreter.CharStack.Pop();
interpreter.BooleanStack.Push(str.IndexOf(c) >= 0);
return true;
}
}
///
/// Puts on the integer stack the index of the top char in the top string
///
[PushExpression(StackTypes.String, "STRING.INDEXOFCHAR", StackTypes.Integer | StackTypes.Char)]
public class StringIndexOfCharExpression : StatelessExpression {
public override bool Eval(IInternalPushInterpreter interpreter) {
if (interpreter.StringStack.IsEmpty ||
interpreter.CharStack.IsEmpty)
return false;
var str = interpreter.StringStack.Pop();
var c = interpreter.CharStack.Pop();
interpreter.IntegerStack.Push(str.IndexOf(c));
return true;
}
}
///
/// The number of times the top char is in the top string
///
[PushExpression(StackTypes.String, "STRING.OCCURENCESOFCHAR", StackTypes.Integer | StackTypes.Char)]
public class StringOccurrencesOfCharExpression : StatelessExpression {
public override bool Eval(IInternalPushInterpreter interpreter) {
if (interpreter.StringStack.IsEmpty ||
interpreter.CharStack.IsEmpty)
return false;
var str = interpreter.StringStack.Pop();
var c = interpreter.CharStack.Pop();
var count = 0;
for (var i = 0; i < str.Length; i++)
if (str[i] == c) count++;
interpreter.IntegerStack.Push(count);
return true;
}
}
///
/// In third string on stack, replaces second string with first string
///
[PushExpression(StackTypes.String, "STRING.REPLACE")]
public class StringReplaceExpression : StatelessExpression {
public override bool Eval(IInternalPushInterpreter interpreter) {
if (interpreter.StringStack.Count < 3)
return false;
var strings = interpreter.StringStack.Pop(2);
if (strings[0].Length == 0 || strings[1].Length == 0)
interpreter.StringStack.SetTop(strings[0]);
else {
var result = strings[0].Replace(strings[1], interpreter.StringStack.Top);
interpreter.StringStack.SetTop(result);
}
return true;
}
}
///
/// In third string on stack, replaces first occurence of second string with first string
///
[PushExpression(StackTypes.String, "STRING.REPLACEFIRST")]
public class StringReplaceLastExpression : StatelessExpression {
public override bool Eval(IInternalPushInterpreter interpreter) {
if (interpreter.StringStack.Count < 3)
return false;
var strings = interpreter.StringStack.Pop(2);
var pos = strings[0].IndexOf(strings[1], StringComparison.Ordinal);
if (pos < 0)
return true;
var result = strings[0].Substring(0, pos) +
interpreter.StringStack.Top +
strings[0].Substring(pos + strings[1].Length);
interpreter.StringStack.SetTop(result);
return true;
}
}
///
/// In top string on stack, replaces all occurences of second char with first char
///
[PushExpression(StackTypes.String, "STRING.REPLACECHAR", StackTypes.Char)]
public class StringReplaceCharExpression : StatelessExpression {
public override bool Eval(IInternalPushInterpreter interpreter) {
if (interpreter.StringStack.IsEmpty ||
interpreter.CharStack.Count < 2)
return false;
var chars = interpreter.CharStack.Pop(2);
var result = interpreter.StringStack.Top.Replace(chars[0], chars[1]);
interpreter.StringStack.SetTop(result);
return true;
}
}
///
/// In top string on stack, replaces first occurence of second char with first char
///
[PushExpression(StackTypes.String, "STRING.REPLACEFIRSTCHAR", StackTypes.Char)]
public class StringReplaceLastCharExpression : StatelessExpression {
public override bool Eval(IInternalPushInterpreter interpreter) {
if (interpreter.StringStack.IsEmpty ||
interpreter.CharStack.Count < 2)
return false;
var str = interpreter.StringStack.Top;
var chars = interpreter.CharStack.Pop(2);
var pos = interpreter.StringStack.Top.IndexOf(chars[0]);
if (pos < 0)
return true;
var result = str.Substring(0, pos) +
chars[1] +
str.Substring(Math.Min(pos + 2, str.Length - 1));
interpreter.StringStack.SetTop(result);
return true;
}
}
///
/// In top string on stack, remove all occurences of char
///
[PushExpression(StackTypes.String, "STRING.REMOVECHAR", StackTypes.Char)]
public class StringRemoveCharExpression : StatelessExpression {
public override bool Eval(IInternalPushInterpreter interpreter) {
if (interpreter.StringStack.IsEmpty ||
interpreter.CharStack.IsEmpty)
return false;
var c = interpreter.CharStack.Pop();
var result = interpreter.StringStack.Top.Trim(c);
interpreter.StringStack.SetTop(result);
return true;
}
}
///
/// Returns a function that sets char at index in string
///
[PushExpression(StackTypes.String, "STRING.SETCHAR", StackTypes.Char | StackTypes.Integer)]
public class StringSetCharExpression : StatelessExpression {
public override bool Eval(IInternalPushInterpreter interpreter) {
if (interpreter.StringStack.IsEmpty ||
interpreter.CharStack.IsEmpty ||
interpreter.IntegerStack.IsEmpty)
return false;
var str = interpreter.StringStack.Top;
var i = (int)interpreter.IntegerStack.Pop();
var c = interpreter.CharStack.Pop();
if (str.Length == 0) {
interpreter.StringStack.Pop();
return true;
}
var pos = str.Length == 1 ? 0 : Math.Abs(i) % (str.Length - 1);
var result = str.Substring(0, pos) + c + str.Substring(Math.Min(pos + 2, str.Length - 1));
interpreter.StringStack.SetTop(result);
return true;
}
}
}