diff --git a/src/lex/cursor.rs b/src/lex/cursor.rs new file mode 100644 index 0000000..02bad56 --- /dev/null +++ b/src/lex/cursor.rs @@ -0,0 +1,90 @@ +// See the end of this file for copyright and license terms. + +use std::str::Chars; + +pub(crate) struct Cursor<'a> { + stream: Chars<'a>, + line: usize, + col: usize, +} + +impl<'a> Cursor<'a> { + pub const fn new(stream: Chars<'a>) -> Cursor<'a> { + Cursor { + stream: stream, + line: 1, + col: 1, + } + } + + pub fn next(&mut self) -> Option { + let c = self.stream.next(); + + self.col += 1; + if c == Some('\n') { + self.line += 1; + self.col = 0; + } + + c + } + + pub fn advance_by(&mut self, n: usize) -> Result<(), usize> { + for i in 0..n { + if self.next() == None { + return Err(i) + } + } + + Ok(()) + } + + pub fn next_until(&mut self, test: fn (c: char) -> bool) -> String { + let mut s = String::new(); + + for _ in 0.. { + match self.peek() { + Some(c) => if test(c) { + break; + } else { + s.push(c); + self.next(); + }, + None => break, + } + } + + s + } + + pub fn peek(&self) -> Option { + self.nth(1) + } + + pub fn nth(&self, n: usize) -> Option { + self.chars().nth(n) + } + + pub fn line(&self) -> usize { + self.line + } + + pub fn col(&self) -> usize { + self.col + } + + pub fn chars(&self) -> Chars<'a> { + self.stream.clone() + } +} + +// Copyright (C) 2021 Fefie +// This file is part of gayconf. +// +// gayconf is ethical software: you can use, redistribute, +// and/or modify it under the terms of the CNPLv5+ as found +// in the LICENSE file in the source code root directory or +// at . +// +// gayconf comes with ABSOLUTELY NO WARRANTY, to the extent +// permitted by applicable law. See the CNPL for details.