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