rune/macros/
token_stream.rs

1use core::fmt;
2use core::slice;
3
4use crate::compile;
5
6use crate as rune;
7use crate::alloc;
8use crate::alloc::prelude::*;
9use crate::alloc::vec;
10use crate::ast;
11use crate::ast::{OptionSpanned, Span};
12use crate::macros::MacroContext;
13use crate::parse::{Parse, Parser};
14
15/// A token stream.
16#[derive(Debug, TryClone, PartialEq, Eq, Default)]
17pub struct TokenStream {
18    stream: Vec<ast::Token>,
19}
20
21impl TokenStream {
22    /// Construct an empty token stream for testing.
23    pub fn new() -> Self {
24        Self::default()
25    }
26
27    /// Push the current token to the stream.
28    pub fn push(&mut self, token: ast::Token) -> alloc::Result<()> {
29        self.stream.try_push(token)?;
30        Ok(())
31    }
32
33    /// Extend the token stream with another iterator.
34    pub fn extend<I>(&mut self, tokens: I) -> alloc::Result<()>
35    where
36        I: IntoIterator,
37        ast::Token: From<I::Item>,
38    {
39        self.stream
40            .try_extend(tokens.into_iter().map(ast::Token::from))?;
41        Ok(())
42    }
43
44    /// Create an iterator over the token stream.
45    pub(crate) fn iter(&self) -> TokenStreamIter<'_> {
46        TokenStreamIter {
47            iter: self.stream.iter(),
48        }
49    }
50
51    /// Return something that once formatted will produce a stream of kinds.
52    pub fn kinds(&self) -> Kinds<'_> {
53        Kinds {
54            stream: &self.stream,
55        }
56    }
57}
58
59impl From<Vec<ast::Token>> for TokenStream {
60    fn from(stream: Vec<ast::Token>) -> Self {
61        Self { stream }
62    }
63}
64
65impl Parse for TokenStream {
66    fn parse(p: &mut Parser<'_>) -> compile::Result<Self> {
67        Ok(Self { stream: p.parse()? })
68    }
69}
70
71impl OptionSpanned for TokenStream {
72    fn option_span(&self) -> Option<Span> {
73        self.stream.option_span()
74    }
75}
76
77/// A token stream iterator.
78#[derive(Debug, Clone)]
79pub struct TokenStreamIter<'a> {
80    iter: slice::Iter<'a, ast::Token>,
81}
82
83impl OptionSpanned for TokenStreamIter<'_> {
84    fn option_span(&self) -> Option<Span> {
85        self.iter.as_slice().option_span()
86    }
87}
88
89impl Iterator for TokenStreamIter<'_> {
90    type Item = ast::Token;
91
92    fn next(&mut self) -> Option<Self::Item> {
93        self.iter.next().copied()
94    }
95}
96
97impl DoubleEndedIterator for TokenStreamIter<'_> {
98    fn next_back(&mut self) -> Option<Self::Item> {
99        self.iter.next_back().copied()
100    }
101}
102
103impl<'a> IntoIterator for &'a TokenStream {
104    type Item = &'a ast::Token;
105    type IntoIter = slice::Iter<'a, ast::Token>;
106
107    #[inline]
108    fn into_iter(self) -> Self::IntoIter {
109        self.stream.iter()
110    }
111}
112
113impl IntoIterator for TokenStream {
114    type Item = ast::Token;
115    type IntoIter = vec::IntoIter<ast::Token>;
116
117    #[inline]
118    fn into_iter(self) -> Self::IntoIter {
119        self.stream.into_iter()
120    }
121}
122
123/// Trait for things that can be turned into tokens.
124pub trait ToTokens {
125    /// Turn the current item into tokens.
126    fn to_tokens(
127        &self,
128        cx: &mut MacroContext<'_, '_, '_>,
129        stream: &mut TokenStream,
130    ) -> alloc::Result<()>;
131}
132
133impl<T> ToTokens for Box<T>
134where
135    T: ToTokens,
136{
137    fn to_tokens(
138        &self,
139        context: &mut MacroContext<'_, '_, '_>,
140        stream: &mut TokenStream,
141    ) -> alloc::Result<()> {
142        (**self).to_tokens(context, stream)
143    }
144}
145
146impl<T> ToTokens for &T
147where
148    T: ?Sized + ToTokens,
149{
150    fn to_tokens(
151        &self,
152        context: &mut MacroContext<'_, '_, '_>,
153        stream: &mut TokenStream,
154    ) -> alloc::Result<()> {
155        ToTokens::to_tokens(*self, context, stream)
156    }
157}
158
159impl<T> ToTokens for Option<T>
160where
161    T: ToTokens,
162{
163    fn to_tokens(
164        &self,
165        context: &mut MacroContext<'_, '_, '_>,
166        stream: &mut TokenStream,
167    ) -> alloc::Result<()> {
168        if let Some(this) = self {
169            this.to_tokens(context, stream)?;
170        }
171
172        Ok(())
173    }
174}
175
176impl<T> ToTokens for Vec<T>
177where
178    T: ToTokens,
179{
180    fn to_tokens(
181        &self,
182        context: &mut MacroContext<'_, '_, '_>,
183        stream: &mut TokenStream,
184    ) -> alloc::Result<()> {
185        for item in self {
186            item.to_tokens(context, stream)?;
187        }
188
189        Ok(())
190    }
191}
192
193impl<A, B> ToTokens for (A, B)
194where
195    A: ToTokens,
196    B: ToTokens,
197{
198    fn to_tokens(
199        &self,
200        context: &mut MacroContext<'_, '_, '_>,
201        stream: &mut TokenStream,
202    ) -> alloc::Result<()> {
203        self.0.to_tokens(context, stream)?;
204        self.1.to_tokens(context, stream)?;
205        Ok(())
206    }
207}
208
209impl<A, B, C> ToTokens for (A, B, C)
210where
211    A: ToTokens,
212    B: ToTokens,
213    C: ToTokens,
214{
215    fn to_tokens(
216        &self,
217        context: &mut MacroContext<'_, '_, '_>,
218        stream: &mut TokenStream,
219    ) -> alloc::Result<()> {
220        self.0.to_tokens(context, stream)?;
221        self.1.to_tokens(context, stream)?;
222        self.2.to_tokens(context, stream)?;
223        Ok(())
224    }
225}
226
227impl ToTokens for TokenStream {
228    fn to_tokens(
229        &self,
230        context: &mut MacroContext<'_, '_, '_>,
231        stream: &mut TokenStream,
232    ) -> alloc::Result<()> {
233        self.stream.to_tokens(context, stream)
234    }
235}
236
237impl PartialEq<Vec<ast::Token>> for TokenStream {
238    fn eq(&self, other: &Vec<ast::Token>) -> bool {
239        self.stream == *other
240    }
241}
242
243impl PartialEq<TokenStream> for Vec<ast::Token> {
244    fn eq(&self, other: &TokenStream) -> bool {
245        *self == other.stream
246    }
247}
248
249pub struct Kinds<'a> {
250    stream: &'a [ast::Token],
251}
252
253impl Iterator for Kinds<'_> {
254    type Item = ast::Kind;
255
256    fn next(&mut self) -> Option<Self::Item> {
257        let (first, rest) = self.stream.split_first()?;
258        self.stream = rest;
259        Some(first.kind)
260    }
261}
262
263impl fmt::Debug for Kinds<'_> {
264    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
265        let mut it = self.stream.iter();
266        let last = it.next_back();
267
268        for t in it {
269            write!(f, "{} ", t.kind)?;
270        }
271
272        if let Some(t) = last {
273            write!(f, "{}", t.kind)?;
274        }
275
276        Ok(())
277    }
278}