Table of Contents
Strings, like all other primitive data types in Stratego, are
terms. They are built with the build (
and matched with the match (
?) operator. Additional
operations on and with strings are realized through strategies
provided by the Stratego library. The most basic operations
on strings provided by the library are concatenation, length
computation and splitting. We will discuss operation each in
The library provides two variants of the string concatenation
operation. The first,
takes a list of strings and returns the concatenated result. The
conc-strings takes a two-element tuple of
strings and returns the concatenated result:
stratego><concat-strings> ["foo", "bar", "baz"] "foobarbaz"
stratego><conc-strings ("foo", "bar") "foobar"
Once you have a string, you may want to know its length, i.e. the
number of characters it contains. There are two equivalent strategies
for determining the length of a string. If you come from a C background,
you may favor the
strlen strategy. If not, the
string-length strategy may offer a clearer name.
The final basic operation on strings is splitting. There is a small family of
closely related strategies for this, which all do simple string tokenization.
The simplest of them is
string-tokenize(|sepchars). It takes
a list of characters as its term argument, and must of course be applied
to a string.
stratego><string-tokenize(|[' '])> "foo bar baz" ["foo","bar","baz"]
Another strategy in the tokenizer family is
string-tokenize-keep-all(|sepchars). It works exactly like
string-tokenize(|sepchars), except that it also keeps the
separators that were matched:
stratego><string-tokenize-keep-all(|[' '])> "foo bar baz" ["foo"," ","bar"," ","baz"]
Even if you don't maintain a phone directory, sorting lists of
strings may come in handy in many other enterprises. The strategies
string-sort-desc sort a
list of strings in ascending and descending order, respectively.
stratego>!["worf", "picard", "data", "riker"] ["worf", "picard", "data", "riker"]
If you only have two strings to sort, it may be more intuitive to
use the string comparison strategies instead. Both
string-lt take a two-element
tuple of strings, and return
1 if the first string
is lexicographically bigger (resp. smaller) than the second, otherwise
stratego><string-gt> ("picard","data") 1
stratego><string-lt> ("worf","data") command failed
Not directly a sorting operation,
is a strategy used to compare prefixes of strings. It takes a string
as the term argument
pre and must be applied to a string.
It will succeed if
pre is a prefix of the string it was
stratego><strings-starts-with(|"wes")> "wesley" "wesley"
We already said that strings are terms. As with terms, we can also
deconstruct strings, but we cannot use normal term deconstruction
for this. Taking apart a string with
will decompose a string into a list of characters. We can then
manipulate this character list using normal list operations and
term matching on the elements. Once finished, we can construct
a new string by calling
the following code, which reverses a string:
stratego>!"evil olive" "evil olive"
stratego>implode-string "evilo live"
idiom is useful enough to warrant its own library strategy, namely
string-as-chars(s). The code above may be written
stratego><string-as-chars(reverse)> "evil olive" "evilo live"
Sometimes, in the heat of battle, it is difficult to keep track of your
primitive types. This is where
is-char come in handy. As you might imagine, they will
succeed when applied to a string and a character, respectively. A minor
note about characters is in order. The Stratego runtime does not separate
between characters and integers. The
is-char must therefore
be applied to an integer, and will verify that the value is within the
printable range for ASCII characters, that is between 32 and 126,
Finally, it may be useful to turn arbitrary terms into strings, and
vice versa. This is done by
read-from-string, which may be considered string I/O
stratego><write-to-string> Foo(Bar()) "Foo(Bar)"
Another interplay between primitive types in Stratego is between
numbers and strings. Converting numbers to strings and strings
to numbers is frequently useful when dealing with program
transformation, perhaps particularly partial evaluation and
interpretation. Going from numbers to strings is done by
Both will accept reals and integers, but will treat is input
as indicated by the name.
stratego><int-to-string> 42.9 "42"
stratego><real-to-string> 42.9 "42.899999999999999"
The resulting number will be pretty-printed as best as possible. In the second example above, the imprecision of floating point numbers results in a somewhat non-intuitive result.
Going the other way, from strings to numbers, is a bit
more convoluted, due to the multiple bases available in
the string notation. The simplest strategies,
assume the input string is in decimal.
stratego><string-to-real> "123.123" 1.231230000000000e+02
stratego><string-to-int> "123" 123
For integers, the strategies
bin-string-to-int can be used to parse
strings with numbers in the most popular bases.