1. Strings


# In Pliant, the standard type to handle character strings is Str.
# String variables must be declared -- if no value is given it's
# value is the empty string ("") if the variable is global.
var Str string

# special characters
string := "[lb]"                   # character '['
string := "[rb]"                   # character ']'
string := "[lf]"                   # line feed
string := "[cr]"                   # carriage return
string := "[tab]"                  # tabulation
string := "[0]"                    # null character
string := "Jon said [dq]hello[dq]" # literal double quotes

# multiline text using inline_text meta and parse_text filters defined 
# in the Appendix

var Str string := inline_text
 This is a multiline here document
 terminated by indentation rule
 (the first indenting space is ignored).
 In the multiline, "special" characters have not to be

# remark each lines of string is ended with a [lf]

var Str string := inline_text leftcut
     This is a multiline here document
       terminated by indentation rule
   with left margin given by the leftest string

var Str string := inline_text ignorefirst
       ! left margin is here
           This is a multiline here document
  gna  with all characters left to the margin ignored,
       as long as properly indented.

Accessing Substrings

var Str s:="some string"

# extraction of at most length characters (less if the required
# length is not available in the string) -> new string

var Str s1 
s1 := s offset length
s1 := s offset s:len      # extracts the end of the string

# same, but the string is really a substring (like in Perl)
# to do this, we add new methods to Str:

method p map s from to
  arg_rw Str p; arg Str s; arg Int from length
  check to < s:len
  p set (s:characters translate Char from) to-from false

s1 map s offset offset+length
s1 map s offset s:len-1

# The equivalent of unpack in Pliant is eparse. However,
# no parsing method is present by default for fixed length
# strings.
# We should create some function FixedStr to create the
# type "string of length xxx" and the from_string method
# on these types. Then, the unpack could be writen as

var FixedStr:5 leading
var FixedStr:3 dummy
var FixedStr:8 s1 s2
var Str trailing data
data eparse leading dummy s1 s2 any:trailing

# A string may be accessed as an array of Char, but if we
# way to transfer a Str into an Array of Char, we need a loop
var Array:Char chars
for (var Int i) 0 s:len
  chars i := s i


s := "This is what you have"

# strings do not support backwards indexing as perl does, but we may
# add this functionality
method s 'new substring' i j -> ss
  arg Str s ss; arg Int i j
  ss:= s (shunt i<0 s:len+i i) j
alias '' '. new substring' 
first  := string 0 1              # "T"
start  := string 5 2              # "is"
rest   := string 13 string:len    # "you have"
last   := string -1 string:len    # "e"
end    := string -4 string:len    # "have"
piece  := string -8 3             # "you"
string := "This is what you have"
console string
#This is what you have

Establishing a Default Value

Exchanging Values Without Using Temporary Variables

Converting Between ASCII Characters and Values

# characters have type Char in Pliant
var Char char:="X"
var Int num := char number        # gets the ASCII code of char
char := character num             # ASCII to character
# Here, we use a string
var Str string:="Hello"
num := string:0:number            # ASCII code of first character
string := character num           # implicit Char->Str cast
var Int ascii_value := "e":number # now 101
var Char char := character 101    # now "e"
var Str hal := "HAL"
var Str ibm := hal
for (var Int i) 0 ibm:len-1
  ibm:i := character hal:i:number+1

Processing a String One Character at a Time

# Since Pliant++ strings can be accessed one character at a time,
# there's no need to do any processing on the string to convert
# it into an array of characters

var Str s

for (var Int i) 0 s:len-1
  # do something with s:i
# we use an Index to sort implicitely the keys
module "/pliant/language/unsafe.pli"         # at the moment Index is still considered unsafe
module "/pliant/language/type/set/each.pli"  # each.pli has to be linked to explicitely
var (Index Char Bool) seen
var Str string := "an apple a day"
for (var Int i) 0 string:len-1
  if not (seen exists string:i)
    seen insert string:i true
console "unique chars are: "
each c seen                       # warning, c is the value associated with the key
  console (seen key c)
console eol
# unique chars are:  adelnpy
var Int sum:=0
for (var Int i) 0 string:len-1
  sum += s:i:number
console sum eol
# prints "1248" if string was "an apple a day"

Reversing a String by Word or Character

Expanding and Compressing Tabs

Expanding Variables in User Input

Controlling Case

Interpolating Functions and Expressions Within Strings

Indenting Here Documents

Reformatting Paragraphs

Escaping Characters

var Str str := "This is a [dq]string[dq] with [lf] special [lb]characters[rb] in it"
var Str quoted := string str
# "This is a [lb]dq[rb]string[lb]dq[rb] with [lb]lf[rb] special [lb]lb[rb]characters[lb]rb[rb] in it"
# back to unquoted string (quoted -> str)
quoted eparse str

Trimming Blanks from the Ends of a String

Parsing Comma-Separated Data

# quoted " ([lb][dq][rb]) are implictely dequoted when arising in a parsed string
var Str string := "XYZZY,[dq][dq],[dq]O'Reilly, Inc[dq],[dq]Wall, Larry[dq],[dq]a [lb]dq[rb]glug[lb]dq[rb] bit[dq], another [dq]glub[dq] bit, 5, [dq]Error, Core Dumped[dq]"
var Str a
var Str b:=string+","
var Array:Str fields
while b<>""
  if not (b parse a "," any:b)  # if not a quoted string
    b parse any:a "," any:b     # it is not quoted and ends with the next ","
  fields += a
for (var Int i) 0 fields:size-1
  console "#" i ":" fields:i eol

#0 : XYZZY
#1 :
#2 : O'Reilly, Inc
#3 : Wall, Larry
#4 : a "glug" bit
#5 : another "glub" bit
#6 : 5
#7 : Error, Core Dumped 

Soundex Matching

Program: fixstyle

Program: psgrep