aboutsummaryrefslogtreecommitdiffstats
path: root/src/tokenizer.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/tokenizer.rs39
1 files changed, 23 insertions, 16 deletions
diff --git a/src/tokenizer.rs b/src/tokenizer.rs
index ba9bcbb..909a1d1 100644
--- a/src/tokenizer.rs
+++ b/src/tokenizer.rs
@@ -222,12 +222,14 @@ impl Tokenizer {
self.current = code;
}
+ /// To do.
pub fn define_skip(&mut self, point: &Point, index: usize) {
self.column_start.insert(point.line, point.column);
self.account_for_potential_skip();
log::debug!("position: define skip: `{:?}` ({:?})", point, index);
}
+ /// To do.
fn account_for_potential_skip(&mut self) {
match self.column_start.get(&self.point.line) {
None => {}
@@ -462,6 +464,7 @@ impl Tokenizer {
}
// To do: lifetimes, boxes, lmao.
+ /// To do.
pub fn attempt_2(
&mut self,
a: impl FnOnce(&mut Tokenizer, Code) -> StateFnResult + 'static,
@@ -481,6 +484,7 @@ impl Tokenizer {
)
}
+ /// To do.
#[allow(clippy::too_many_arguments, clippy::many_single_char_names)]
pub fn attempt_5(
&mut self,
@@ -504,6 +508,7 @@ impl Tokenizer {
)
}
+ /// To do.
#[allow(clippy::too_many_arguments, clippy::many_single_char_names)]
pub fn attempt_7(
&mut self,
@@ -529,6 +534,7 @@ impl Tokenizer {
)
}
+ /// To do.
#[allow(clippy::too_many_arguments, clippy::many_single_char_names)]
pub fn call_multiple(
&mut self,
@@ -606,7 +612,7 @@ impl Tokenizer {
// Yield to a higher loop if we shouldn’t feed EOFs.
if !drain {
- return (state, Some(codes[index..].to_vec()));
+ return check_statefn_result((state, Some(codes[index..].to_vec())));
}
loop {
@@ -618,14 +624,7 @@ impl Tokenizer {
log::debug!("main: passing eof");
self.expect(code);
let (next, remainder) = check_statefn_result(func(self, code));
-
- if let Some(ref x) = remainder {
- if !x.is_empty() {
- // To do: handle?
- unreachable!("drain:remainder {:?}", x);
- }
- }
-
+ assert!(remainder.is_none(), "expected no remainder");
state = next;
}
}
@@ -661,8 +660,13 @@ fn attempt_impl(
}
}
- // To do: `remainder` must never be bigger than codes I guess?
- // To do: `remainder` probably has to be taken *from* `codes`, in a similar vain to the `Ok` handling below.
+ if let Some(ref list) = remainder {
+ assert!(
+ list.len() <= codes.len(),
+ "`remainder` must be less than or equal to `codes`"
+ );
+ }
+
match next {
State::Ok => {
let remaining = if let Some(x) = remainder { x } else { vec![] };
@@ -670,6 +674,7 @@ fn attempt_impl(
}
State::Nok => check_statefn_result(done((codes, vec![]), false, tokenizer)),
State::Fn(func) => {
+ assert!(remainder.is_none(), "expected no remainder");
check_statefn_result((State::Fn(attempt_impl(func, codes, done)), None))
}
}
@@ -712,20 +717,18 @@ pub fn as_codes(value: &str) -> Vec<Code> {
}
// Send a tab and virtual spaces.
'\t' => {
- // To do: is this correct?
let remainder = column % TAB_SIZE;
- let virtual_spaces = if remainder == 0 {
+ let mut virtual_spaces = if remainder == 0 {
0
} else {
TAB_SIZE - remainder
};
codes.push(Code::Char(char));
column += 1;
- let mut index = 0;
- while index < virtual_spaces {
+ while virtual_spaces > 0 {
codes.push(Code::VirtualSpace);
column += 1;
- index += 1;
+ virtual_spaces -= 1;
}
}
// Send an LF.
@@ -770,6 +773,10 @@ fn check_statefn_result(result: StateFnResult) -> StateFnResult {
if Some(&Code::None) == list.last() {
list.pop();
}
+
+ if list.is_empty() {
+ return (state, None);
+ }
}
(state, remainder)