Skip to content

Commit d5e83c0

Browse files
authored
feature: tokenizer (#4)
* tokenizer * remove unused fields * tell compiler that this branch is not reachable
1 parent ce3e484 commit d5e83c0

File tree

8 files changed

+878
-0
lines changed

8 files changed

+878
-0
lines changed

Cargo.lock

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ license = "MIT"
1010
keywords = ["css", "syntax", "postcss", "parser", "ast"]
1111

1212
[dependencies]
13+
memchr = "2.4"
14+
once_cell = "1.8.0"
1315

1416
[dev-dependencies]
1517
criterion = { version = "0.3", features = ["html_reports"] }

src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1+
pub mod node;
2+
pub mod ref_ring;
3+
pub mod tokenizer;
14
pub mod unit;

src/main.rs

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
pub mod node;
2+
pub mod ref_ring;
3+
pub mod tokenizer;
4+
pub mod unit;
5+
6+
use tokenizer::Tokenizer;
7+
8+
fn main() {
9+
let value = "abc";
10+
let processor = Tokenizer::new(value);
11+
while !processor.end_of_file() {
12+
println!("{:?}", processor.next_token());
13+
}
14+
}

src/node.rs

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
use std::borrow::Cow;
2+
3+
pub struct Word<'a> {
4+
pub source_index: u32,
5+
pub value: Cow<'a, str>,
6+
}
7+
8+
pub struct Space<'a> {
9+
pub source_index: u32,
10+
pub value: Cow<'a, str>,
11+
}
12+
13+
pub struct Comment<'a> {
14+
pub source_index: u32,
15+
pub value: Cow<'a, str>,
16+
}
17+
18+
pub struct UnicodeRange<'a> {
19+
pub source_index: u32,
20+
pub value: Cow<'a, str>,
21+
}
22+
23+
pub struct Div<'a> {
24+
pub source_index: u32,
25+
pub value: Cow<'a, str>,
26+
}
27+
28+
pub struct String<'a> {
29+
pub source_index: u32,
30+
pub value: Cow<'a, str>,
31+
}
32+
33+
pub struct Function<'a> {
34+
pub source_index: u32,
35+
pub value: Cow<'a, str>,
36+
pub nodes: Vec<Node<'a>>,
37+
}
38+
39+
pub enum Node<'a> {
40+
Word(Word<'a>),
41+
Space(Space<'a>),
42+
Comment(Comment<'a>),
43+
UnicodeRange(UnicodeRange<'a>),
44+
Div(Div<'a>),
45+
String(String<'a>),
46+
Function(Function<'a>),
47+
}
48+
49+
pub trait ClosableNode {
50+
/// Whether the parsed CSS value ended before the node was properly closed
51+
fn unclosed(&self) -> bool;
52+
}
53+
54+
pub trait AdjacentAwareNode<'a> {
55+
/// The token at the start of the node
56+
fn before(&self) -> Cow<'a, str>;
57+
/// The token at the end of the node
58+
fn after(&self) -> Cow<'a, str>;
59+
}

src/ref_ring.rs

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
use std::mem;
2+
const BUFFER_SIZE: usize = u8::MAX as usize + 1;
3+
4+
#[derive(Debug)]
5+
pub struct RefRing<'a> {
6+
buffer: [Option<&'a str>; BUFFER_SIZE],
7+
index: u8,
8+
}
9+
10+
impl<'a> Default for RefRing<'a> {
11+
fn default() -> Self {
12+
RefRing {
13+
// SAFETY: SINCE NONE IS ZERO IN MEMORY REPRESENTATION,
14+
// WE COULD JUST ZEROED OUT THE WHOLE BUFFER TO INITIALIZE IT.
15+
buffer: unsafe { mem::zeroed() },
16+
index: 0,
17+
}
18+
}
19+
}
20+
21+
impl<'a> RefRing<'a> {
22+
#[inline]
23+
pub fn push(&mut self, e: &'a str) {
24+
let index = self.index as usize;
25+
// The assert let the compiler optimize out the bounds checks.
26+
assert!(index < BUFFER_SIZE);
27+
self.buffer[index].replace(e);
28+
self.index = self.index.wrapping_add(1);
29+
}
30+
31+
pub fn pop(&mut self) -> Option<&'a str> {
32+
self.index = self.index.wrapping_sub(1);
33+
let index = self.index as usize;
34+
// The assert let the compiler optimize out the bounds checks.
35+
assert!(index < BUFFER_SIZE);
36+
37+
self.buffer[index].take()
38+
}
39+
}

0 commit comments

Comments
 (0)