1use crate::SyntaxKind;
30
31#[derive(Default)]
41pub struct Output {
42 event: Vec<u32>,
48 error: Vec<String>,
49}
50
51#[derive(Debug)]
52pub(crate) enum Step<'a> {
53 Token {
54 kind: SyntaxKind,
55 n_input_tokens: u8,
56 },
57 FloatSplit {
58 ends_in_dot: bool,
59 },
60 Enter {
61 kind: SyntaxKind,
62 },
63 Exit,
64 Error {
65 msg: &'a str,
66 },
67}
68
69impl Output {
70 const EVENT_MASK: u32 = 0b1;
71 const TAG_MASK: u32 = 0x0000_00F0;
72 const N_INPUT_TOKEN_MASK: u32 = 0x0000_FF00;
73 const KIND_MASK: u32 = 0xFFFF_0000;
74
75 const ERROR_SHIFT: u32 = Self::EVENT_MASK.trailing_ones();
76 const TAG_SHIFT: u32 = Self::TAG_MASK.trailing_zeros();
77 const N_INPUT_TOKEN_SHIFT: u32 = Self::N_INPUT_TOKEN_MASK.trailing_zeros();
78 const KIND_SHIFT: u32 = Self::KIND_MASK.trailing_zeros();
79
80 const TOKEN_EVENT: u8 = 0;
81 const ENTER_EVENT: u8 = 1;
82 const EXIT_EVENT: u8 = 2;
83 const SPLIT_EVENT: u8 = 3;
84
85 pub(crate) fn iter(&self) -> impl Iterator<Item = Step<'_>> {
86 self.event.iter().map(|&event| {
87 if event & Self::EVENT_MASK == 0 {
88 return Step::Error {
89 msg: self.error[(event as usize) >> Self::ERROR_SHIFT].as_str(),
90 };
91 }
92 let tag = ((event & Self::TAG_MASK) >> Self::TAG_SHIFT) as u8;
93 match tag {
94 Self::TOKEN_EVENT => {
95 let kind: SyntaxKind =
96 (((event & Self::KIND_MASK) >> Self::KIND_SHIFT) as u16).into();
97 let n_input_tokens =
98 ((event & Self::N_INPUT_TOKEN_MASK) >> Self::N_INPUT_TOKEN_SHIFT) as u8;
99 Step::Token {
100 kind,
101 n_input_tokens,
102 }
103 }
104 Self::ENTER_EVENT => {
105 let kind: SyntaxKind =
106 (((event & Self::KIND_MASK) >> Self::KIND_SHIFT) as u16).into();
107 Step::Enter { kind }
108 }
109 Self::EXIT_EVENT => Step::Exit,
110 Self::SPLIT_EVENT => Step::FloatSplit {
111 ends_in_dot: event & Self::N_INPUT_TOKEN_MASK != 0,
112 },
113 _ => unreachable!(),
114 }
115 })
116 }
117
118 pub(crate) fn token(&mut self, kind: SyntaxKind, n_tokens: u8) {
119 let e = ((kind as u16 as u32) << Self::KIND_SHIFT)
120 | ((n_tokens as u32) << Self::N_INPUT_TOKEN_SHIFT)
121 | Self::EVENT_MASK;
122 self.event.push(e)
123 }
124
125 pub(crate) fn float_split_hack(&mut self, ends_in_dot: bool) {
126 let e = (Self::SPLIT_EVENT as u32) << Self::TAG_SHIFT
127 | ((ends_in_dot as u32) << Self::N_INPUT_TOKEN_SHIFT)
128 | Self::EVENT_MASK;
129 self.event.push(e);
130 }
131
132 pub(crate) fn enter_node(&mut self, kind: SyntaxKind) {
133 let e = ((kind as u16 as u32) << Self::KIND_SHIFT)
134 | ((Self::ENTER_EVENT as u32) << Self::TAG_SHIFT)
135 | Self::EVENT_MASK;
136 self.event.push(e)
137 }
138
139 pub(crate) fn leave_node(&mut self) {
140 let e = (Self::EXIT_EVENT as u32) << Self::TAG_SHIFT | Self::EVENT_MASK;
141 self.event.push(e)
142 }
143
144 pub(crate) fn error(&mut self, error: String) {
145 let idx = self.error.len();
146 self.error.push(error);
147 let e = (idx as u32) << Self::ERROR_SHIFT;
148 self.event.push(e);
149 }
150}