kproc_parser/
kproc_macros.rs1use std::fmt::Debug;
4
5use crate::proc_macro::{TokenStream, TokenTree};
6
7#[derive(Debug)]
13pub struct KTokenStream {
14 pos: usize,
15 kstream: Vec<TokenTree>,
16 size: usize,
17}
18
19impl From<TokenStream> for KTokenStream {
20 fn from(value: TokenStream) -> Self {
21 KTokenStream::new(&value)
22 }
23}
24
25impl From<&TokenStream> for KTokenStream {
26 fn from(value: &TokenStream) -> Self {
27 KTokenStream::new(value)
28 }
29}
30
31impl KTokenStream {
32 pub fn new(tokens: &TokenStream) -> Self {
34 KTokenStream::new_with_pos(tokens, 0)
35 }
36
37 pub fn new_with_pos(tokens: &TokenStream, pos: usize) -> Self {
40 let mut kstream = Vec::new();
41 tokens
42 .to_owned()
43 .into_iter()
44 .for_each(|token| kstream.push(token));
45 KTokenStream {
46 pos,
47 kstream: kstream.to_vec(),
48 size: kstream.len(),
49 }
50 }
51
52 pub fn advance(&mut self) -> TokenTree {
55 self.next();
56 if self.is_end() {
57 return self.kstream.last().unwrap().to_owned();
58 }
59 self.prev().to_owned()
60 }
61
62 pub fn lookup(&self, step: usize) -> &TokenTree {
65 assert!(self.size > self.pos + step);
66 &self.kstream[self.pos + step]
67 }
68
69 pub fn has(&self, step: usize) -> bool {
72 self.size > self.pos + step
73 }
74
75 pub fn next(&mut self) {
77 self.pos += 1;
78 }
79
80 pub fn prev(&self) -> &TokenTree {
83 assert!(self.pos < self.size, "prev: out of bound");
84 &self.kstream[self.pos - 1]
85 }
86
87 pub fn peek(&self) -> &TokenTree {
89 assert!(
90 self.pos < self.size,
91 "peek: out of bound requested {} vs tot size {}",
92 self.pos,
93 self.size
94 );
95 &self.kstream[self.pos]
96 }
97
98 pub fn last(&self) -> &TokenTree {
100 self.kstream.last().unwrap()
101 }
102
103 pub fn match_tok(&self, tok: &str) -> bool {
105 self.peek().match_tok(tok)
106 }
107
108 pub fn is_end(&self) -> bool {
110 self.pos >= self.size
111 }
112
113 pub fn to_ktoken_stream(&self) -> KTokenStream {
117 match self.peek() {
118 TokenTree::Group(stream) => KTokenStream::new(&stream.stream()),
119 _ => panic!("no stream on token {:?}", self.peek()),
120 }
121 }
122
123 pub fn opt_ktoken_stream(&self) -> Option<KTokenStream> {
127 match self.peek() {
128 TokenTree::Group(stream) => Some(KTokenStream::new(&stream.stream())),
129 _ => None,
130 }
131 }
132
133 pub fn unwrap_group(&self) -> TokenTree {
134 match self.peek() {
135 TokenTree::Group(_) => self.peek().clone(),
136 _ => panic!("the token {:?} is not a `TokenTree::Group`", self.peek()),
137 }
138 }
139
140 pub fn unwrap_group_as_stream(&self) -> TokenStream {
141 match self.peek() {
142 TokenTree::Group(stream) => stream.stream(),
143 _ => panic!("the token {:?} is not a `TokenTree::Group`", self.peek()),
144 }
145 }
146
147 pub fn is_group(&self) -> bool {
149 match self.peek() {
150 TokenTree::Group(_) => true,
151 _ => false,
152 }
153 }
154
155 pub fn consume_brace(&mut self) {
157 let tok = self.peek();
158 match tok.to_string().as_str() {
159 "{" | "}" => {
160 self.advance();
161 }
162 _ => {}
163 }
164 }
165}
166
167pub trait MatchTok
168where
169 Self: ToString + Debug,
170{
171 fn match_tok(&self, tok: &str) -> bool {
172 self.to_string().as_str() == tok
173 }
174
175 fn to_token_stream(&self) -> KTokenStream;
176}
177
178impl MatchTok for TokenTree {
179 fn to_token_stream(&self) -> KTokenStream {
180 match self {
181 TokenTree::Group(stream) => KTokenStream::new(&stream.stream()),
182 _ => panic!("no stream on token {:?}", self),
183 }
184 }
185}
186
187#[derive(Clone, Debug)]
188pub struct OrderedTokenTree {
189 idx: u64,
190 token: TokenTree,
191}
192
193impl OrderedTokenTree {
194 pub fn new(idx: u64, token: TokenTree) -> Self {
195 OrderedTokenTree { idx, token }
196 }
197
198 pub fn token(&self) -> TokenTree {
199 self.token.clone()
200 }
201
202 pub fn idx(&mut self, idx: u64) {
203 self.idx = idx;
204 }
205}
206
207impl From<TokenTree> for OrderedTokenTree {
208 fn from(value: TokenTree) -> Self {
209 OrderedTokenTree::new(0, value)
210 }
211}
212
213impl PartialOrd for OrderedTokenTree {
214 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
215 self.idx.partial_cmp(&other.idx)
216 }
217}
218
219impl Ord for OrderedTokenTree {
220 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
221 self.idx.cmp(&other.idx)
222 }
223}
224
225impl PartialEq for OrderedTokenTree {
226 fn eq(&self, other: &Self) -> bool {
227 self.idx.eq(&other.idx)
228 }
229}
230
231impl Eq for OrderedTokenTree {}