From a1e33af5a04595ed3d6d090f21bc3d40e035e4e2 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Mon, 20 Apr 2020 11:08:54 +0800 Subject: [PATCH] Reduce size of Position by limiting resolution to 16 bits. --- src/token.rs | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/token.rs b/src/token.rs index aa11a3c6..e65e5e3e 100644 --- a/src/token.rs +++ b/src/token.rs @@ -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.