module Strings { 
 
  // STRING AND CHARACTER BASICS 
 
  // Strings are modeled as an array of characters, but are stored in 
  // UTF-8 format in memory. 
  // 
  // Strings are immutable. 
  //  
  // Characters in a string are of type char, which is a numeric  
  // type corresponding to a UNICODE "scalar", with values in the 
  // range 0..0x10FFFF, except surrogates 0xD800 to 0xDFFF 
  // 
  // Strings are written between double quotes ("), and characters 
  // are written between single quotes '. 
   
  fn test1() { 
    let s : string = "hello"; 
    let c : char = 'h'; 
  } 
 
  // STRING AND CHARACTER ESCAPES 
 
  // Strings and character literals support "escaped" characters that are  
  // preceeded by backslash (\).   
  // 
  // The escape \u{n} allows a UNICODE character value n using 1-6 hex digits. 
  //   
  // The following additional escapes are supported for string and char: 
  // 
  //  shortcut   equivalent 
  //   \0        \u{0} 
  //   \n        \u{a} 
  //   \r        \u{d} 
  //   \t        \u{9} 
  //   \f        \u{c} 
  //   \v        \u{b} 
  //   \\        \u{5c} (backslash) 
  //   \xNN      \u{NN} (NN represents 2 hex digits) 
  // 
  // The following escapes are specific to string: 
  //  
  //  shortcut   equivalent 
  //   \"        \u{22} (double quote) 
  // 
  // The following escapes are specific to char: 
  //  
  //  shortcut   equivalent 
  //   \'        \u{27} (single quote) 
  //   \$        \u{24} (dollar sign) 
 
  fn test2() { 
    let snowman = '\u{2603}';   // snowman character 
    let newlines = "abc\ndef";  // string with newline (\n) 
  } 
 
  // CHARACTER MATH 
 
  // Characters are numeric type, so they support addition, subtraction, etc. 
  // An exception will be thrown if the resulting of a math operation is not within 
  // the value defined for a UNICODE "scalar". 
 
  fn test3() { 
    let c1 = '9' - '0';         // 9 
    let c2 = 'a' + 1;           // 'b' 
    let c3 = '\u{D7FF}' + 1;    // exception: character out of range 
  } 
 
  // ACCESSING CHARACTERS IN STRINGS 
 
  // A string s can be accessed by character index i using s[i] 
 
  fn test4() { 
    let s = "abc"; 
    let c = s[1];     // b 
  } 
 
  // STRING LENGTH 
 
  // The length of a string s is accessed using s#.  The result is the count 
  // of characters in the string.  Strings are not \0 terminated. 
 
  fn test5() { 
    let s = "abc\n"; 
    let l = s#;      // 4 
  } 
 
  // STRING INTERPOLATION 
 
  // To insert values in a string, use ${x}, where x is an expression.  If  
  // x is not of type string, then the format method must be defined for  
  // the type of x, which will turn the value into a string. 
 
  fn test6() { 
    let s1 = "def"; 
    let i1 = 123; 
    let s2 = "abc${s1}${i1}";   // "abcdef123" 
  } 
 
  // STRING SEQUENCE 
 
  // A given string constant must be on a single line, but multiple string 
  // constants listed after each other will form a single string. 
 
  fn test7() { 
    let one_string = 
      "abc" "def" 
      "ghi";    // "abcdefghi" 
  } 
 
  // STRING PARTS 
 
  // By default, a string constant produces a value of type string.  By prefixing 
  // the string with $, the string constant will produce an array of string 
  // parts.  A "string part" is defined as follows: 
  // 
  // union StrPart{T} { 
  //   StrLit{lit : string}   // a constant string 
  //   StrVal{val : T}        // a value x inserted with ${x} 
  //   StrBrk{};              // a \ that appears between strings 
  // } 
  // 
  // This provides a way for custom handling of the values inserted in the 
  // string, for example for escaping or other custom processing (HTML, SQL, etc.) 
 
  fn test8() { 
    let s1 = "def"; 
    let i1 = 123; 
 
    // since the string is preceeded by $, the value produced is an array 
    // of StrPart, where each element corresponds to either a string constant 
    // or a value inserted. 
    let s2 = $"abc${s1}${i1}";   // [StrLit("abc"), StrVal("def"), StrVal(123)] 
  } 
 
  // STRING BREAKS 
 
  // When using string parts, a "break" can be inserted between strings 
  // by using \.  This will produce a StrBrk part.  The meaning of 
  // can be interpreted by custom processing, but it could be replaced 
  // by a newline, for example. 
 
  fn test9() { 
    let s1 = $ 
      "abc" \ "def" \ 
      "ghi" "jkl";    // [StrLit("abc"), StrBrk, StrLit("def"), StrBrk, StrLit("ghijkl")] 
  } 
 
 
}