///|
fn Machine::escaped_string(self : Machine) -> Array[Byte] raise ForthError {
  let frame = self.source_frame()
  let result = []
  while frame.cursor < frame.data.length() {
    let byte = frame.data[frame.cursor]
    frame.cursor += 1
    if byte == b'"' {
      return result
    }
    if byte != b'\\' {
      result.push(byte)
      continue
    }
    if frame.cursor >= frame.data.length() {
      raise Invalid("unterminated escape")
    }
    let escape = frame.data[frame.cursor]
    frame.cursor += 1
    if escape == b'x' {
      if frame.cursor + 2 > frame.data.length() {
        raise Invalid("short hexadecimal escape")
      }
      let a = digit_value(frame.data[frame.cursor].to_int().to_uint16())
      let b = digit_value(frame.data[frame.cursor + 1].to_int().to_uint16())
      if a < 0 || a > 15 || b < 0 || b > 15 {
        raise Invalid("invalid hexadecimal escape")
      }
      frame.cursor += 2
      result.push((a * 16 + b).to_byte())
    } else if escape == b'm' {
      result.push(13)
      result.push(10)
    } else {
      result.push(
        match escape {
          b'a' => 7
          b'b' => 8
          b'e' => 27
          b'f' => 12
          b'l' | b'n' => 10
          b'q' | b'"' => 34
          b'r' => 13
          b't' => 9
          b'v' => 11
          b'z' => 0
          b'\\' => 92
          _ => raise Invalid("unknown string escape")
        },
      )
    }
  }
  raise Invalid("unterminated escaped string")
}