source: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/StringExpressions.cs @ 14834

Last change on this file since 14834 was 14834, checked in by pkimmesw, 2 years ago

#2665 LexicaseSelector, Performance improvements, UI Fixes, Debugger only shows used stacks, fixed Debugger stepping, Added vector expressions, ERCOptions,

File size: 16.6 KB
Line 
1namespace HeuristicLab.Problems.ProgramSynthesis.Push.Expressions {
2  using System;
3  using System.Linq;
4
5  using Attributes;
6  using Interpreter;
7  using Stack;
8
9  [PushExpression(StackTypes.String, "STRING.FROMINTEGER", StackTypes.Integer)]
10  public class StringFromIntegerExpression : StatelessExpression {
11    public override bool Eval(IInternalPushInterpreter interpreter) {
12      if (interpreter.IntegerStack.IsEmpty)
13        return false;
14
15      var value = interpreter.IntegerStack.Pop();
16      interpreter.StringStack.Push(value.ToString());
17      return true;
18    }
19  }
20
21  [PushExpression(StackTypes.String, "STRING.FROMFLOAT", StackTypes.Float)]
22  public class StringFromFloatExpression : StatelessExpression {
23    public override bool Eval(IInternalPushInterpreter interpreter) {
24      if (interpreter.FloatStack.IsEmpty)
25        return false;
26
27      var value = interpreter.FloatStack.Pop();
28      interpreter.StringStack.Push(value.ToString());
29      return true;
30    }
31  }
32
33  [PushExpression(StackTypes.String, "STRING.FROMBOOLEAN", StackTypes.Boolean)]
34  public class StringFromBooleanExpression : StatelessExpression {
35    public override bool Eval(IInternalPushInterpreter interpreter) {
36      if (interpreter.BooleanStack.IsEmpty)
37        return false;
38
39      var value = interpreter.BooleanStack.Pop();
40      interpreter.StringStack.Push(value.ToString());
41      return true;
42    }
43  }
44
45  [PushExpression(StackTypes.String, "STRING.FROMCHAR", StackTypes.Char)]
46  public class StringFromCharExpression : StatelessExpression {
47    public override bool Eval(IInternalPushInterpreter interpreter) {
48      if (interpreter.CharStack.IsEmpty)
49        return false;
50
51      var value = interpreter.CharStack.Pop();
52      interpreter.StringStack.Push(value.ToString());
53      return true;
54    }
55  }
56
57  [PushExpression(StackTypes.String, "STRING.CONCAT")]
58  public class StringConcatExpression : StatelessExpression {
59    public override bool Eval(IInternalPushInterpreter interpreter) {
60      if (interpreter.StringStack.Count < 2 ||
61        interpreter.StringStack.Top.Length + interpreter.StringStack.ReverseElementAt(1).Length >= interpreter.Configuration.MaxStringLength)
62        return false;
63
64      var str = interpreter.StringStack.Pop();
65      interpreter.StringStack.SetTop(str + interpreter.StringStack.Top);
66      return true;
67    }
68  }
69
70  /// <summary>
71  /// Conj char onto string
72  /// </summary>
73  [PushExpression(StackTypes.String, "STRING.CONJCHAR", StackTypes.Char)]
74  public class StringConjCharExpression : StatelessExpression {
75    public override bool Eval(IInternalPushInterpreter interpreter) {
76      if (interpreter.StringStack.IsEmpty ||
77          interpreter.CharStack.IsEmpty ||
78          interpreter.StringStack.Top.Length + 1 >= interpreter.Configuration.MaxStringLength)
79        return false;
80
81      var c = interpreter.CharStack.Pop();
82      interpreter.StringStack.SetTop(interpreter.StringStack.Top + c);
83      return true;
84    }
85  }
86
87  [PushExpression(StackTypes.String, "STRING.TAKE", StackTypes.Integer)]
88  public class StringTakeExpression : StatelessExpression {
89    public override bool Eval(IInternalPushInterpreter interpreter) {
90      if (interpreter.StringStack.IsEmpty ||
91          interpreter.IntegerStack.IsEmpty)
92        return false;
93
94      var value = interpreter.IntegerStack.Pop();
95
96      if (value < 0) {
97        return true;
98      }
99
100      var str = interpreter.StringStack.Top;
101
102      if (str.Length > 0) {
103        value = Math.Min(str.Length - 1, value);
104        interpreter.StringStack.SetTop(str.Substring(0, (int)value));
105      }
106
107      return true;
108    }
109  }
110
111  [PushExpression(StackTypes.String, "STRING.SUBSTRING", StackTypes.Integer)]
112  public class StringSubstringExpression : StatelessExpression {
113    public override bool Eval(IInternalPushInterpreter interpreter) {
114      if (interpreter.StringStack.IsEmpty ||
115          interpreter.IntegerStack.Count < 2)
116        return false;
117
118      var str = interpreter.StringStack.Top;
119      var values = interpreter.IntegerStack.Pop(2);
120      var first = Math.Min(str.Length - 1, Math.Max(values[0], 0));
121      var second = Math.Min(str.Length - 1, Math.Max(values[1], first));
122      var length = second - first;
123
124      if (length > 0)
125        interpreter.StringStack.SetTop(str.Substring((int)first, (int)length));
126
127      return true;
128    }
129  }
130
131  [PushExpression(StackTypes.String, "STRING.FIRST")]
132  public class StringFirstExpression : StatelessExpression {
133    public override bool Eval(IInternalPushInterpreter interpreter) {
134      if (interpreter.StringStack.IsEmpty ||
135          interpreter.StringStack.Top.Length == 0)
136        return false;
137
138      interpreter.StringStack.SetTop(interpreter.StringStack.Top[0].ToString());
139      return true;
140    }
141  }
142
143
144  [PushExpression(StackTypes.String, "STRING.LAST")]
145  public class StringLastExpression : StatelessExpression {
146    public override bool Eval(IInternalPushInterpreter interpreter) {
147      if (interpreter.StringStack.IsEmpty ||
148          interpreter.StringStack.Top.Length == 0)
149        return false;
150
151      var str = interpreter.StringStack.Top;
152      var c = str[str.Length - 1].ToString();
153      interpreter.StringStack.SetTop(c);
154      return true;
155    }
156  }
157
158  [PushExpression(StackTypes.String, "STRING.NTH", StackTypes.Integer)]
159  public class StringNthExpression : StatelessExpression {
160    public override bool Eval(IInternalPushInterpreter interpreter) {
161      if (interpreter.StringStack.IsEmpty ||
162          interpreter.IntegerStack.IsEmpty ||
163          interpreter.StringStack.Top.Length == 0)
164        return false;
165
166      var str = interpreter.StringStack.Top;
167      var index = str.Length == 1 ? 0 : (int)Math.Abs(interpreter.IntegerStack.Pop() % (str.Length - 1));
168      var c = str[index].ToString();
169      interpreter.StringStack.SetTop(c);
170      return true;
171    }
172  }
173
174  [PushExpression(StackTypes.String, "STRING.REST")]
175  public class StringRestExpression : StatelessExpression {
176    public override bool Eval(IInternalPushInterpreter interpreter) {
177      if (interpreter.StringStack.IsEmpty ||
178          interpreter.StringStack.Top.Length == 0)
179        return false;
180
181      var str = interpreter.StringStack.Top;
182      interpreter.StringStack.SetTop(str.Length == 1 ? string.Empty : str.Substring(1, str.Length - 1));
183      return true;
184    }
185  }
186
187  [PushExpression(StackTypes.String, "STRING.BUTLAST")]
188  public class StringButLastExpression : StatelessExpression {
189    public override bool Eval(IInternalPushInterpreter interpreter) {
190      if (interpreter.StringStack.IsEmpty ||
191          interpreter.StringStack.Top.Length == 0)
192        return false;
193
194      var str = interpreter.StringStack.Top;
195      interpreter.StringStack.SetTop(str.Length == 1 ? string.Empty : str.Substring(0, str.Length - 1));
196      return true;
197    }
198  }
199
200  [PushExpression(StackTypes.String, "STRING.LENGTH", StackTypes.Integer)]
201  public class StringLengthExpression : StatelessExpression {
202    public override bool Eval(IInternalPushInterpreter interpreter) {
203      if (interpreter.StringStack.IsEmpty)
204        return false;
205
206      var str = interpreter.StringStack.Pop();
207      interpreter.IntegerStack.Push(str.Length);
208      return true;
209    }
210  }
211
212  [PushExpression(StackTypes.String, "STRING.REVERSE")]
213  public class StringReverseExpression : StatelessExpression {
214    public override bool Eval(IInternalPushInterpreter interpreter) {
215      if (interpreter.StringStack.IsEmpty)
216        return false;
217
218      interpreter.StringStack.SetTop(interpreter.StringStack.Top.Reverse().ToString());
219      return true;
220    }
221  }
222
223  [PushExpression(StackTypes.String, "STRING.PARSETOCHARS")]
224  public class StringParseToCharsExpression : StatelessExpression {
225    public override bool Eval(IInternalPushInterpreter interpreter) {
226      if (interpreter.StringStack.IsEmpty)
227        return false;
228
229      if (interpreter.StringStack.Top.Length == 0) {
230        interpreter.StringStack.Pop();
231        return true;
232      }
233
234      var str = interpreter.StringStack.Top;
235      interpreter.StringStack.SetTop(str[0].ToString());
236
237      if (str.Length > 1) {
238        var chars = new string[str.Length - 1];
239        for (var i = 0; i < str.Length - 1; i++) {
240          chars[i] = str[i + 1].ToString();
241        }
242
243        interpreter.StringStack.Push(chars);
244      }
245
246      return true;
247    }
248  }
249
250  [PushExpression(StackTypes.String, "STRING.SPLIT")]
251  public class StringSplitExpression : StatelessExpression {
252    public override bool Eval(IInternalPushInterpreter interpreter) {
253      if (interpreter.StringStack.IsEmpty)
254        return false;
255
256      var words = interpreter.StringStack.Top.Trim().Split();
257
258      if (words.Length == 0)
259        return false;
260
261      interpreter.StringStack.SetTop(words[0]);
262
263      if (words.Length > 1)
264        interpreter.StringStack.Push(words, 1);
265
266      return true;
267    }
268  }
269
270  /// <summary>
271  /// True if top string is empty
272  /// </summary>
273
274  [PushExpression(StackTypes.String, "STRING.EMPTYSTRING", StackTypes.Boolean)]
275  public class StringEmptyStringExpression : StatelessExpression {
276    public override bool Eval(IInternalPushInterpreter interpreter) {
277      if (interpreter.StringStack.IsEmpty)
278        return false;
279
280      var str = interpreter.StringStack.Pop();
281      interpreter.BooleanStack.Push(str.Length == 0);
282      return true;
283    }
284  }
285
286  /// <summary>
287  /// True if top string is a substring of second string; false otherwise
288  /// </summary>
289  [PushExpression(StackTypes.String, "STRING.CONTAINS", StackTypes.Boolean)]
290  public class StringContainsExpression : StatelessExpression {
291    public override bool Eval(IInternalPushInterpreter interpreter) {
292      if (interpreter.StringStack.Count < 2)
293        return false;
294
295      var strings = interpreter.StringStack.Pop(2);
296      interpreter.BooleanStack.Push(strings[0].IndexOf(strings[1], StringComparison.Ordinal) >= 0);
297      return true;
298    }
299  }
300
301  /// <summary>
302  /// True if the top char is in the top string
303  /// </summary>
304  [PushExpression(StackTypes.String, "STRING.CONTAINSCHAR", StackTypes.Boolean | StackTypes.Char)]
305  public class StringContainsCharExpression : StatelessExpression {
306    public override bool Eval(IInternalPushInterpreter interpreter) {
307      if (interpreter.StringStack.IsEmpty ||
308          interpreter.CharStack.IsEmpty)
309        return false;
310
311      var str = interpreter.StringStack.Pop();
312      var c = interpreter.CharStack.Pop();
313
314      interpreter.BooleanStack.Push(str.IndexOf(c) >= 0);
315      return true;
316    }
317  }
318
319  /// <summary>
320  /// Puts on the integer stack the index of the top char in the top string
321  /// </summary>
322  [PushExpression(StackTypes.String, "STRING.INDEXOFCHAR", StackTypes.Integer | StackTypes.Char)]
323  public class StringIndexOfCharExpression : StatelessExpression {
324    public override bool Eval(IInternalPushInterpreter interpreter) {
325      if (interpreter.StringStack.IsEmpty ||
326          interpreter.CharStack.IsEmpty)
327        return false;
328
329      var str = interpreter.StringStack.Pop();
330      var c = interpreter.CharStack.Pop();
331
332      interpreter.IntegerStack.Push(str.IndexOf(c));
333      return true;
334    }
335  }
336
337  /// <summary>
338  /// The number of times the top char is in the top string
339  /// </summary>
340  [PushExpression(StackTypes.String, "STRING.OCCURENCESOFCHAR", StackTypes.Integer | StackTypes.Char)]
341  public class StringOccurrencesOfCharExpression : StatelessExpression {
342    public override bool Eval(IInternalPushInterpreter interpreter) {
343      if (interpreter.StringStack.IsEmpty ||
344          interpreter.CharStack.IsEmpty)
345        return false;
346
347      var str = interpreter.StringStack.Pop();
348      var c = interpreter.CharStack.Pop();
349
350      var count = 0;
351      for (var i = 0; i < str.Length; i++)
352        if (str[i] == c) count++;
353
354      interpreter.IntegerStack.Push(count);
355      return true;
356    }
357  }
358
359  /// <summary>
360  /// In third string on stack, replaces second string with first string
361  /// </summary>
362  [PushExpression(StackTypes.String, "STRING.REPLACE")]
363  public class StringReplaceExpression : StatelessExpression {
364    public override bool Eval(IInternalPushInterpreter interpreter) {
365      if (interpreter.StringStack.Count < 3)
366        return false;
367
368      var strings = interpreter.StringStack.Pop(2);
369
370      if (strings[0].Length == 0 || strings[1].Length == 0)
371        interpreter.StringStack.SetTop(strings[0]);
372      else {
373        var result = strings[0].Replace(strings[1], interpreter.StringStack.Top);
374        interpreter.StringStack.SetTop(result);
375      }
376
377      return true;
378    }
379  }
380
381  /// <summary>
382  /// In third string on stack, replaces first occurence of second string with first string
383  /// </summary>
384  [PushExpression(StackTypes.String, "STRING.REPLACEFIRST")]
385  public class StringReplaceLastExpression : StatelessExpression {
386    public override bool Eval(IInternalPushInterpreter interpreter) {
387      if (interpreter.StringStack.Count < 3)
388        return false;
389
390      var strings = interpreter.StringStack.Pop(2);
391
392      var pos = strings[0].IndexOf(strings[1], StringComparison.Ordinal);
393
394      if (pos < 0)
395        return true;
396
397      var result = strings[0].Substring(0, pos) +
398                   interpreter.StringStack.Top +
399                   strings[0].Substring(pos + strings[1].Length);
400
401      interpreter.StringStack.SetTop(result);
402      return true;
403    }
404  }
405
406  /// <summary>
407  /// In top string on stack, replaces all occurences of second char with first char
408  /// </summary>
409  [PushExpression(StackTypes.String, "STRING.REPLACECHAR", StackTypes.Char)]
410  public class StringReplaceCharExpression : StatelessExpression {
411    public override bool Eval(IInternalPushInterpreter interpreter) {
412      if (interpreter.StringStack.IsEmpty ||
413          interpreter.CharStack.Count < 2)
414        return false;
415
416      var chars = interpreter.CharStack.Pop(2);
417      var result = interpreter.StringStack.Top.Replace(chars[0], chars[1]);
418      interpreter.StringStack.SetTop(result);
419      return true;
420    }
421  }
422
423  /// <summary>
424  /// In top string on stack, replaces first occurence of second char with first char
425  /// </summary>
426  [PushExpression(StackTypes.String, "STRING.REPLACEFIRSTCHAR", StackTypes.Char)]
427  public class StringReplaceLastCharExpression : StatelessExpression {
428    public override bool Eval(IInternalPushInterpreter interpreter) {
429      if (interpreter.StringStack.IsEmpty ||
430          interpreter.CharStack.Count < 2)
431        return false;
432
433      var str = interpreter.StringStack.Top;
434      var chars = interpreter.CharStack.Pop(2);
435      var pos = interpreter.StringStack.Top.IndexOf(chars[0]);
436
437      if (pos < 0)
438        return true;
439
440      var result = str.Substring(0, pos) +
441                   chars[1] +
442                   str.Substring(Math.Min(pos + 2, str.Length - 1));
443      interpreter.StringStack.SetTop(result);
444      return true;
445    }
446  }
447
448  /// <summary>
449  /// In top string on stack, remove all occurences of char
450  /// </summary>
451  [PushExpression(StackTypes.String, "STRING.REMOVECHAR", StackTypes.Char)]
452  public class StringRemoveCharExpression : StatelessExpression {
453    public override bool Eval(IInternalPushInterpreter interpreter) {
454      if (interpreter.StringStack.IsEmpty ||
455          interpreter.CharStack.IsEmpty)
456        return false;
457
458      var c = interpreter.CharStack.Pop();
459      var result = interpreter.StringStack.Top.Trim(c);
460      interpreter.StringStack.SetTop(result);
461      return true;
462    }
463  }
464
465  /// <summary>
466  /// Returns a function that sets char at index in string
467  /// </summary>
468  [PushExpression(StackTypes.String, "STRING.SETCHAR", StackTypes.Char | StackTypes.Integer)]
469  public class StringSetCharExpression : StatelessExpression {
470    public override bool Eval(IInternalPushInterpreter interpreter) {
471      if (interpreter.StringStack.IsEmpty ||
472          interpreter.CharStack.IsEmpty ||
473          interpreter.IntegerStack.IsEmpty)
474        return false;
475
476      var str = interpreter.StringStack.Top;
477      var i = (int)interpreter.IntegerStack.Pop();
478      var c = interpreter.CharStack.Pop();
479
480      if (str.Length == 0) {
481        interpreter.StringStack.Pop();
482        return true;
483      }
484
485      var pos = str.Length == 1 ? 0 : Math.Abs(i) % (str.Length - 1);
486      var result = str.Substring(0, pos) + c + str.Substring(Math.Min(pos + 2, str.Length - 1));
487
488      interpreter.StringStack.SetTop(result);
489      return true;
490    }
491  }
492}
Note: See TracBrowser for help on using the repository browser.