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, iter::Peekable,
str::{Chars, FromStr}, str::{Chars, FromStr},
string::{String, ToString}, string::{String, ToString},
usize, u16,
vec::Vec, vec::Vec,
}; };
type LERR = LexError; type LERR = LexError;
/// A location (line number + character position) in the input script. /// 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)] #[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)]
pub struct Position { pub struct Position {
/// Line number - 0 = none /// Line number - 0 = none
line: usize, line: u16,
/// Character position - 0 = BOL /// Character position - 0 = BOL
pos: usize, pos: u16,
} }
impl Position { impl Position {
/// Create a new `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 != 0, "line cannot be zero");
assert!(
line != usize::MAX || position != usize::MAX,
"invalid position"
);
Self { Self {
line, line,
@ -48,7 +48,7 @@ impl Position {
if self.is_none() { if self.is_none() {
None None
} else { } else {
Some(self.line) Some(self.line as usize)
} }
} }
@ -57,13 +57,18 @@ impl Position {
if self.is_none() || self.pos == 0 { if self.is_none() || self.pos == 0 {
None None
} else { } else {
Some(self.pos) Some(self.pos as usize)
} }
} }
/// Advance by one character position. /// Advance by one character position.
pub(crate) fn advance(&mut self) { 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. /// 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. /// Panics if already at beginning of a line - cannot rewind to a previous line.
/// ///
pub(crate) fn rewind(&mut self) { pub(crate) fn rewind(&mut self) {
assert!(!self.is_none(), "cannot rewind Position::none");
assert!(self.pos > 0, "cannot rewind at position 0"); assert!(self.pos > 0, "cannot rewind at position 0");
self.pos -= 1; self.pos -= 1;
} }
/// Advance to the next line. /// Advance to the next line.
pub(crate) fn new_line(&mut self) { pub(crate) fn new_line(&mut self) {
self.line += 1; assert!(!self.is_none(), "cannot advance Position::none");
self.pos = 0;
// Advance up to maximum position
if self.line < u16::MAX {
self.line += 1;
self.pos = 0;
}
} }
/// Create a `Position` representing no position. /// Create a `Position` representing no position.