///|
// Decode the escape sequences of a data-string token into bytes.
//
// The lexer keeps string escapes raw (see lexer/lexer.mbt), so every consumer
// that needs the actual bytes has to decode them. The assembly emitters get
// this for free by passing the raw text to gas, but the interpreter stores
// bytes directly and used to copy the raw characters:
//   data $x = { b "0x42" }   (spelled with a backslash escape in real input)
// produced the characters backslash, 'x', '4', '2' instead of 0x42.
pub fn decode_data_string(raw : String) -> Array[Int32] {
  let a = raw.to_array()
  let n = a.length()
  let out : Array[Int32] = []
  let mut i = 0
  while i < n {
    let ch = a[i]
    if ch.to_int() == 92 && i + 1 < n {
      i = i + 1
      let e = a[i]
      let ev = e.to_int()
      if ev == 110 {
        out.push(10)
      } else if ev == 116 {
        out.push(9)
      } else if ev == 114 {
        out.push(13)
      } else if ev == 92 {
        out.push(92)
      } else if ev == 34 {
        out.push(34)
      } else if ev == 39 {
        out.push(39)
      } else if ev == 120 {
        // hex escape, one or two digits
        let mut v = 0
        let mut k = 0
        while i + 1 < n && k < 2 {
          let d = hex_val(a[i + 1])
          if d < 0 {
            break
          }
          v = v * 16 + d
          i = i + 1
          k = k + 1
        }
        out.push(v & 0xFF)
      } else if ev >= 48 && ev <= 55 {
        // octal escape, up to three digits
        let mut v = 0
        let mut k = 0
        while i < n && k < 3 && a[i].to_int() >= 48 && a[i].to_int() <= 55 {
          v = v * 8 + (a[i].to_int() - 48)
          i = i + 1
          k = k + 1
        }
        i = i - 1
        out.push(v & 0xFF)
      } else {
        out.push(ev)
      }
    } else {
      out.push(ch.to_int())
    }
    i = i + 1
  }
  out
}

///|
fn hex_val(c : Char) -> Int32 {
  let v = c.to_int()
  if v >= 48 && v <= 57 {
    v - 48
  } else if v >= 97 && v <= 102 {
    v - 87
  } else if v >= 65 && v <= 70 {
    v - 55
  } else {
    -1
  }
}