diff options
author | Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com> | 2023-02-20 12:46:23 +0100 |
---|---|---|
committer | Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com> | 2023-03-30 13:52:30 +0200 |
commit | f84d6127fe60a968bf331ebb9cec58b16df86852 (patch) | |
tree | d21f7197fb4ec5d144a3333ac0c9f2c30ba20511 | |
parent | e4cd0d726ed65e34cfcb8cd6a265095d89983520 (diff) | |
download | gcc-f84d6127fe60a968bf331ebb9cec58b16df86852.zip gcc-f84d6127fe60a968bf331ebb9cec58b16df86852.tar.gz gcc-f84d6127fe60a968bf331ebb9cec58b16df86852.tar.bz2 |
libproc_macro: Implement FromIterator
Implement FromIterator for TokenStream, from either a TokenTree iterator
or a TokenStream iterator.
ChangeLog:
* librust/proc_macro/rust/bridge/token_stream.rs: Add internal
implementation.
* librust/proc_macro/rust/lib.rs: Add FromIterator
implementation.
Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
-rw-r--r-- | librust/proc_macro/rust/bridge/token_stream.rs | 52 | ||||
-rw-r--r-- | librust/proc_macro/rust/lib.rs | 8 |
2 files changed, 56 insertions, 4 deletions
diff --git a/librust/proc_macro/rust/bridge/token_stream.rs b/librust/proc_macro/rust/bridge/token_stream.rs index 307ff6b..7135a0f 100644 --- a/librust/proc_macro/rust/bridge/token_stream.rs +++ b/librust/proc_macro/rust/bridge/token_stream.rs @@ -1,4 +1,8 @@ use bridge::{group::Group, ident::Ident, literal::Literal, punct::Punct}; +use std::convert::TryInto; + +type ExternalTokenTree = crate::TokenTree; +type ExternalTokenStream = crate::TokenStream; // TODO: There surely is a better way to achieve this. I don't like this // "duplication" of the TokenTree enumeration. But I cannot use the public @@ -13,8 +17,21 @@ pub enum TokenTree { Literal(Literal), } +impl From<ExternalTokenTree> for TokenTree { + fn from(value: ExternalTokenTree) -> Self { + match value { + ExternalTokenTree::Group(g) => TokenTree::Group(g.0), + ExternalTokenTree::Ident(i) => TokenTree::Ident(i.0), + ExternalTokenTree::Punct(p) => TokenTree::Punct(p.0), + ExternalTokenTree::Literal(l) => TokenTree::Literal(l.0), + } + } +} + extern "C" { fn TokenStream__new() -> TokenStream; + fn TokenStream__with_capacity(capacity: u64) -> TokenStream; + fn TokenStream__push(stream: *mut TokenStream, tree: TokenTree); } #[repr(C)] @@ -22,6 +39,7 @@ extern "C" { pub struct TokenStream { pub(crate) data: *const TokenTree, pub(crate) size: u64, + capacity: u64, } impl TokenStream { @@ -29,7 +47,41 @@ impl TokenStream { unsafe { TokenStream__new() } } + fn with_capacity(capacity: u64) -> Self { + unsafe { TokenStream__with_capacity(capacity) } + } + + fn push(&mut self, tree: TokenTree) { + unsafe { TokenStream__push(self as *mut TokenStream, tree) } + } + pub fn is_empty(&self) -> bool { 0 == self.size } + + pub fn from_iterator<I>(it: I) -> Self + where + I: IntoIterator<Item = ExternalTokenStream>, + { + let it = it.into_iter(); + let mut result = TokenStream::with_capacity(it.size_hint().0.try_into().unwrap()); + for stream in it { + for item in stream.into_iter() { + result.push(item.into()); + } + } + result + } + + pub fn from_tree_iterator<I>(it: I) -> Self + where + I: IntoIterator<Item = ExternalTokenTree>, + { + let it = it.into_iter(); + let mut result = TokenStream::with_capacity(it.size_hint().0.try_into().unwrap()); + for item in it { + result.push(item.into()); + } + result + } } diff --git a/librust/proc_macro/rust/lib.rs b/librust/proc_macro/rust/lib.rs index 31aa6ea..4888edb 100644 --- a/librust/proc_macro/rust/lib.rs +++ b/librust/proc_macro/rust/lib.rs @@ -174,14 +174,14 @@ impl FromStr for TokenStream { } impl iter::FromIterator<TokenTree> for TokenStream { - fn from_iter<I: IntoIterator<Item = TokenTree>>(_trees: I) -> Self { - todo!("Implement this function") + fn from_iter<I: IntoIterator<Item = TokenTree>>(trees: I) -> Self { + TokenStream(bridge::token_stream::TokenStream::from_tree_iterator(trees)) } } impl iter::FromIterator<TokenStream> for TokenStream { - fn from_iter<I: IntoIterator<Item = TokenStream>>(_streams: I) -> Self { - todo!("Implement this function") + fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self { + TokenStream(bridge::token_stream::TokenStream::from_iterator(streams)) } } |