Reduce size of Position by limiting resolution to 16 bits.
@@ -13,29 +13,29 @@ use crate::stdlib::{
iter::Peekable,
str::{Chars, FromStr},
string::{String, ToString},
- usize,
+ u16,
vec::Vec,
};
type LERR = LexError;
/// A location (line number + character position) in the input script.
+///
+/// In order to keep footprint small, both line number and character position have 16-bit resolution,
+/// meaning they go up to a maximum of 65,535 lines/characters per line.
+/// Advancing beyond the maximum line length or maximum number of lines is not an error but has no effect.
#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)]
pub struct Position {
/// Line number - 0 = none
- line: usize,
+ line: u16,
/// Character position - 0 = BOL
- pos: usize,
+ pos: u16,
}
impl Position {
/// Create a new `Position`.
- pub fn new(line: usize, position: usize) -> Self {
+ pub fn new(line: u16, position: u16) -> Self {
assert!(line != 0, "line cannot be zero");
- assert!(
- line != usize::MAX || position != usize::MAX,
- "invalid position"
- );
Self {
line,
@@ -48,7 +48,7 @@ impl Position {
if self.is_none() {
None
} else {
- Some(self.line)
+ Some(self.line as usize)
}
}
@@ -57,14 +57,19 @@ impl Position {
if self.is_none() || self.pos == 0 {
None
} else {
- Some(self.pos)
+ Some(self.pos as usize)
}
}
/// Advance by one character position.
pub(crate) fn advance(&mut self) {
+ assert!(!self.is_none(), "cannot advance Position::none");
+
+ // Advance up to maximum position
+ if self.pos < u16::MAX {
self.pos += 1;
}
+ }
/// Go backwards by one character position.
///
@@ -73,15 +78,21 @@ impl Position {
/// Panics if already at beginning of a line - cannot rewind to a previous line.
///
pub(crate) fn rewind(&mut self) {
+ assert!(!self.is_none(), "cannot rewind Position::none");
assert!(self.pos > 0, "cannot rewind at position 0");
self.pos -= 1;
}
/// Advance to the next line.
pub(crate) fn new_line(&mut self) {
+ assert!(!self.is_none(), "cannot advance Position::none");
+
+ // Advance up to maximum position
+ if self.line < u16::MAX {
self.line += 1;
self.pos = 0;
}
+ }
/// Create a `Position` representing no position.
pub(crate) fn none() -> Self {
