Reduce size of Position by limiting resolution to 16 bits.

This commit is contained in:
Stephen Chung 2020-04-20 11:08:54 +08:00
parent 642533aef6
commit a1e33af5a0

View File

@ -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,13 +57,18 @@ 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) {
self.pos += 1;
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,14 +78,20 @@ 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) {
self.line += 1;
self.pos = 0;
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.