Skip to content

Commit 6d3a994

Browse files
committed
Remove smallvec dependency.
Just use an array of `Token` now that tokens are only a single byte (they used to be much larger before a previous refactoring). Additionally, add test coverage for multiple expected tokens errors. Fix a bug where a failed lookahead used the current token position instead of the last position in the source where the next token is EOI.
1 parent 781f086 commit 6d3a994

8 files changed

Lines changed: 40 additions & 28 deletions

File tree

Cargo.lock

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,3 @@ serde_json = "1.0.107"
5252
wat = "1.0.77"
5353
logos = "0.13.0"
5454
thiserror = "1.0.50"
55-
smallvec = "1.11.1"

crates/wac-parser/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ serde = { workspace = true }
2121
wasmparser = { workspace = true }
2222
wit-parser = { workspace = true }
2323
wit-component = { workspace = true }
24-
smallvec = { workspace = true }
2524
wat = { workspace = true, optional = true }
2625
owo-colors = { workspace = true }
2726

crates/wac-parser/src/ast.rs

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use crate::{
55
Spanned,
66
};
77
use serde::Serialize;
8-
use smallvec::SmallVec;
98
use std::{fmt, path::Path};
109

1110
mod export;
@@ -32,26 +31,27 @@ impl fmt::Display for Found {
3231
}
3332

3433
struct Expected<'a> {
35-
expected: &'a [Token],
36-
more: bool,
34+
expected: &'a [Option<Token>],
35+
count: usize,
3736
}
3837

3938
impl fmt::Display for Expected<'_> {
4039
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41-
for (i, t) in self.expected.iter().enumerate() {
40+
let mut expected = self.expected.iter().enumerate();
41+
while let Some((i, Some(token))) = expected.next() {
4242
if i > 0 {
4343
write!(f, ", ")?;
4444
}
4545

46-
if i == self.expected.len() - 1 {
46+
if i == self.expected.len() - 1 && self.count <= self.expected.len() {
4747
write!(f, "or ")?;
4848
}
4949

50-
t.fmt(f)?;
50+
token.fmt(f)?;
5151
}
5252

53-
if self.more {
54-
write!(f, " (and more...) ")?;
53+
if self.count > self.expected.len() {
54+
write!(f, ", or more...")?;
5555
}
5656

5757
Ok(())
@@ -92,12 +92,12 @@ pub enum Error<'a> {
9292
span: Span<'a>,
9393
},
9494
/// An unexpected token was encountered when multiple tokens were expected.
95-
#[error("expected either {expected}, found {found}", expected = Expected { expected, more: *.more }, found = Found(*.found))]
95+
#[error("expected either {expected}, found {found}", expected = Expected { expected, count: *.count }, found = Found(*.found))]
9696
ExpectedMultiple {
9797
/// The tokens that were expected.
98-
expected: SmallVec<[Token; 5]>,
99-
/// Whether or not more tokens were expected.
100-
more: bool,
98+
expected: [Option<Token>; 10],
99+
/// The count of expected tokens.
100+
count: usize,
101101
/// The found token.
102102
found: Option<Token>,
103103
/// The span of the found token.
@@ -182,11 +182,11 @@ where
182182

183183
/// Used to look ahead one token in the lexer.
184184
///
185-
/// The lookahead stores up to 5 attempted tokens.
185+
/// The lookahead stores up to 10 attempted tokens.
186186
pub struct Lookahead<'a> {
187187
next: Option<(LexerResult<'a, Token>, Span<'a>)>,
188-
span: Span<'a>,
189-
attempts: SmallVec<[Token; 5]>,
188+
source: &'a str,
189+
attempts: [Option<Token>; 10],
190190
count: usize,
191191
}
192192

@@ -195,7 +195,7 @@ impl<'a> Lookahead<'a> {
195195
pub fn new(lexer: &Lexer<'a>) -> Self {
196196
Self {
197197
next: lexer.peek(),
198-
span: lexer.span(),
198+
source: lexer.source(),
199199
attempts: Default::default(),
200200
count: 0,
201201
}
@@ -206,9 +206,8 @@ impl<'a> Lookahead<'a> {
206206
match &self.next {
207207
Some((Ok(t), _)) if *t == expected => true,
208208
_ => {
209-
// Push up to the capacity to ensure no allocations
210-
if self.count < self.attempts.capacity() {
211-
self.attempts.push(expected);
209+
if self.count < self.attempts.len() {
210+
self.attempts[self.count] = Some(expected);
212211
}
213212

214213
self.count += 1;
@@ -218,30 +217,34 @@ impl<'a> Lookahead<'a> {
218217
}
219218

220219
/// Returns an error based on the attempted tokens.
220+
///
221+
/// Panics if no peeks were attempted.
221222
pub fn error(self) -> Error<'a> {
222223
let (found, span) = match self.next {
223224
Some((Ok(token), span)) => (Some(token), span),
224225
Some((Err(e), s)) => return (e, s).into(),
225-
None => (None, self.span),
226+
None => (
227+
None,
228+
Span::from_span(self.source, &(self.source.len()..self.source.len())),
229+
),
226230
};
227231

228-
let more = self.count > self.attempts.len();
229232
match self.count {
230233
0 => unreachable!("lookahead had no attempts"),
231234
1 => Error::Expected {
232-
expected: self.attempts[0],
235+
expected: self.attempts[0].unwrap(),
233236
found,
234237
span,
235238
},
236239
2 => Error::ExpectedEither {
237-
first: self.attempts[0],
238-
second: self.attempts[1],
240+
first: self.attempts[0].unwrap(),
241+
second: self.attempts[1].unwrap(),
239242
found,
240243
span,
241244
},
242245
_ => Error::ExpectedMultiple {
243246
expected: self.attempts,
244-
more,
247+
count: self.count,
245248
found,
246249
span,
247250
},
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
type x =
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
expected either `func` keyword, `u8` keyword, `s8` keyword, `u16` keyword, `s16` keyword, `u32` keyword, `s32` keyword, `u64` keyword, `s64` keyword, `float32` keyword, or more..., found end of input
2+
--> tests/parser/fail/expected-multiple.wac:1:10
3+
|
4+
1 | type x =
5+
| ^
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
record foo {
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
expected `}` or identifier, found end of input
2+
--> tests/parser/fail/expected-two.wac:2:1
3+
|
4+
2 |
5+
| ^

0 commit comments

Comments
 (0)