///|
/// Parse a quoted string (basic or literal)
fn Parser::parse_string(self : Parser) -> String raise ParseError {
  match self.next() {
    Some('"') => self.parse_basic_string()
    Some('\'') => self.parse_literal_string()
    Some(ch) => raise ParseError::UnexpectedChar(self.pos - 1, ch)
    None => raise ParseError::UnexpectedEof
  }
}

///|
/// Parse a basic string (with escape sequences)
fn Parser::parse_basic_string(self : Parser) -> String raise ParseError {
  let buf = @buffer.new()
  while not(self.is_eof()) {
    match self.next() {
      Some('"') => return buf.to_string()
      Some('\\') =>
        match self.next() {
          Some('t') => buf.write_char('\t')
          Some('n') => buf.write_char('\n')
          Some('r') => buf.write_char('\r')
          Some('\\') => buf.write_char('\\')
          Some('"') => buf.write_char('"')
          Some(ch) => raise ParseError::InvalidEscape(self.pos - 1, ch)
          None => raise ParseError::UnexpectedEof
        }
      Some(ch) => buf.write_char(ch)
      None => raise ParseError::UnexpectedEof
    }
  }
  raise ParseError::UnexpectedEof
}

///|
/// Parse a literal string (no escape sequences except '' for a single quote)
fn Parser::parse_literal_string(self : Parser) -> String raise ParseError {
  let buf = @buffer.new()
  while not(self.is_eof()) {
    match self.next() {
      Some('\'') =>
        // Check for escaped single quote (two single quotes in a row)
        if self.peek() == Some('\'') {
          buf.write_char('\'')
          self.pos += 1 // Skip the second quote
        } else {
          return buf.to_string()
        }
      Some(ch) => buf.write_char(ch)
      None => raise ParseError::UnexpectedEof
    }
  }
  raise ParseError::UnexpectedEof
}

///|
/// Parse a bare key (unquoted identifier)
fn Parser::parse_bare_key(self : Parser) -> String raise ParseError {
  let buf = @buffer.new()
  while not(self.is_eof()) {
    match self.peek() {
      Some(ch) if is_bare_key_char(ch) => {
        buf.write_char(ch)
        self.pos += 1
      }
      _ => break
    }
  }
  let key = buf.to_string()
  if key.is_empty() {
    raise ParseError::InvalidKey(self.pos, "empty key")
  }
  key
}

///|
/// Check if character is valid in a bare key
fn is_bare_key_char(ch : Char) -> Bool {
  match ch {
    'a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '-' => true
    _ => false
  }
}

///|
/// Parse a key (bare, basic string, or literal string)
fn Parser::parse_key(self : Parser) -> String raise ParseError {
  self.skip_whitespace()
  match self.peek() {
    Some('"') => {
      self.pos += 1
      self.parse_basic_string()
    }
    Some('\'') => {
      self.pos += 1
      self.parse_literal_string()
    }
    Some(ch) if is_bare_key_char(ch) => self.parse_bare_key()
    Some(ch) => raise ParseError::UnexpectedChar(self.pos, ch)
    None => raise ParseError::UnexpectedEof
  }
}

///|
/// Parse a number (integer or float)
fn Parser::parse_number(self : Parser) -> TomlValue raise ParseError {
  let buf = @buffer.new()
  let start_pos = self.pos
  let mut is_float = false

  // Handle sign
  match self.peek() {
    Some('+' | '-') => buf.write_char(self.next().unwrap())
    _ => ()
  }

  // Parse digits
  while not(self.is_eof()) {
    match self.peek() {
      Some('0'..='9') => buf.write_char(self.next().unwrap())
      Some('_') => self.pos += 1 // Skip underscores
      Some('.') => {
        is_float = true
        buf.write_char(self.next().unwrap())
      }
      Some('e' | 'E') => {
        is_float = true
        buf.write_char(self.next().unwrap())
        match self.peek() {
          Some('+' | '-') => buf.write_char(self.next().unwrap())
          _ => ()
        }
      }
      _ => break
    }
  }
  let num_str = buf.to_string()
  if is_float {
    let result = @strconv.parse_double(num_str) catch {
      _ => raise ParseError::InvalidNumber(start_pos, num_str)
    }
    TomlValue::Float(result)
  } else {
    let result = @strconv.parse_int64(num_str) catch {
      _ => raise ParseError::InvalidNumber(start_pos, num_str)
    }
    TomlValue::Integer(result)
  }
}

///|
/// Parse a boolean value
fn Parser::parse_boolean(self : Parser) -> Bool raise ParseError {
  let start_pos = self.pos
  if self.try_consume("true") {
    true
  } else if self.try_consume("false") {
    false
  } else {
    raise ParseError::InvalidKey(start_pos, "expected boolean")
  }
}

///|
/// Try to consume a specific string
fn Parser::try_consume(self : Parser, s : String) -> Bool {
  let start_pos = self.pos
  for i = 0; i < s.length(); i = i + 1 {
    match (self.peek(), s.get_char(i)) {
      (Some(ch1), Some(ch2)) if ch1 == ch2 => self.pos += 1
      _ => {
        self.pos = start_pos
        return false
      }
    }
  }
  true
}