1 //! Input for the parser -- a sequence of tokens.
3 //! As of now, parser doesn't have access to the *text* of the tokens, and makes
4 //! decisions based solely on their classification.
8 #[allow(non_camel_case_types)]
11 /// Main input to the parser.
13 /// A sequence of tokens represented internally as a struct of arrays.
16 kind: Vec<SyntaxKind>,
18 contextual_kind: Vec<SyntaxKind>,
21 /// `pub` impl used by callers to create `Tokens`.
24 pub fn push(&mut self, kind: SyntaxKind) {
25 self.push_impl(kind, SyntaxKind::EOF)
28 pub fn push_ident(&mut self, contextual_kind: SyntaxKind) {
29 self.push_impl(SyntaxKind::IDENT, contextual_kind)
31 /// Sets jointness for the last token we've pushed.
33 /// This is a separate API rather than an argument to the `push` to make it
34 /// convenient both for textual and mbe tokens. With text, you know whether
35 /// the *previous* token was joint, with mbe, you know whether the *current*
36 /// one is joint. This API allows for styles of usage:
40 /// tokens.was_joint(prev_joint);
41 /// tokens.push(curr);
45 /// tokens.push(curr_joint)
48 pub fn was_joint(&mut self) {
49 let n = self.len() - 1;
50 let (idx, b_idx) = self.bit_index(n);
51 self.joint[idx] |= 1 << b_idx;
54 fn push_impl(&mut self, kind: SyntaxKind, contextual_kind: SyntaxKind) {
56 if idx % (bits::BITS as usize) == 0 {
60 self.contextual_kind.push(contextual_kind);
64 /// pub(crate) impl used by the parser to consume `Tokens`.
66 pub(crate) fn kind(&self, idx: usize) -> SyntaxKind {
67 self.kind.get(idx).copied().unwrap_or(SyntaxKind::EOF)
69 pub(crate) fn contextual_kind(&self, idx: usize) -> SyntaxKind {
70 self.contextual_kind.get(idx).copied().unwrap_or(SyntaxKind::EOF)
72 pub(crate) fn is_joint(&self, n: usize) -> bool {
73 let (idx, b_idx) = self.bit_index(n);
74 self.joint[idx] & 1 << b_idx != 0
79 fn bit_index(&self, n: usize) -> (usize, usize) {
80 let idx = n / (bits::BITS as usize);
81 let b_idx = n % (bits::BITS as usize);
84 fn len(&self) -> usize {