jrsonnet_rowan_parser/
token_set.rs1use std::fmt;
2
3use crate::SyntaxKind;
4
5#[derive(Clone, Copy, Default)]
6pub struct SyntaxKindSet(u128);
7
8impl SyntaxKindSet {
9 #[allow(dead_code)]
10 pub const EMPTY: Self = Self(0);
11 pub const ALL: Self = Self(u128::MAX);
12
13 pub const fn new(kinds: &[SyntaxKind]) -> Self {
14 let mut res = 0u128;
15 let mut i = 0;
16 while i < kinds.len() {
17 res |= mask(kinds[i]);
18 i += 1;
19 }
20 Self(res)
21 }
22
23 #[must_use]
24 pub const fn union(self, other: Self) -> Self {
25 Self(self.0 | other.0)
26 }
27 #[must_use]
28 pub const fn with(self, kind: SyntaxKind) -> Self {
29 Self(self.0 | mask(kind))
30 }
31
32 pub fn contains(&self, kind: SyntaxKind) -> bool {
33 if !is_token(kind) {
34 return false;
35 }
36 self.0 & mask(kind) != 0
37 }
38}
39impl fmt::Display for SyntaxKindSet {
40 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41 let mut v = self.0;
42 let mut variants = <Vec<SyntaxKind>>::new();
43 for i in 0..128 {
44 if v & 1 == 1 {
45 variants.push(SyntaxKind::from_raw(i));
46 }
47 v >>= 1;
48 if v == 0 {
49 break;
50 }
51 }
52 for (i, v) in variants.iter().enumerate() {
53 if i == 0 {
54 } else if i == variants.len() - 1 {
55 write!(f, " or ")?;
56 } else {
57 write!(f, ", ")?;
58 }
59 write!(f, "{v:?}")?;
60 }
61 Ok(())
62 }
63}
64impl fmt::Debug for SyntaxKindSet {
65 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66 let mut v = self.0;
67 let mut variants = <Vec<SyntaxKind>>::new();
68 for i in 0..128 {
69 if v & 1 == 1 {
70 variants.push(SyntaxKind::from_raw(i));
71 }
72 v >>= 1;
73 if v == 0 {
74 break;
75 }
76 }
77 f.debug_tuple("SyntaxKindSet").field(&variants).finish()
78 }
79}
80
81const fn mask(kind: SyntaxKind) -> u128 {
82 assert!(kind as u32 <= 128, "mask for not a token kind");
83 1u128 << (kind as u128)
84}
85
86#[macro_export]
87macro_rules! TS {
88 ($($tt:tt)*) => {
89 $crate::SyntaxKindSet::new(&[
90 $(
91 $crate::T![$tt]
92 ),*
93 ])
94 };
95}
96
97#[test]
98fn sanity() {
99 assert!(
100 (SyntaxKind::LEXING_ERROR as u32) < 127,
101 "can't keep KindSet as bitset"
102 );
103}
104fn is_token(kind: SyntaxKind) -> bool {
105 (kind as u32) < 127
106}