aboutsummaryrefslogtreecommitdiff
path: root/crates/mbe/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/mbe/src/lib.rs')
-rw-r--r--crates/mbe/src/lib.rs72
1 files changed, 67 insertions, 5 deletions
diff --git a/crates/mbe/src/lib.rs b/crates/mbe/src/lib.rs
index 19543d777..35cde5f10 100644
--- a/crates/mbe/src/lib.rs
+++ b/crates/mbe/src/lib.rs
@@ -14,6 +14,7 @@ mod tests;
14 14
15use std::fmt; 15use std::fmt;
16 16
17use test_utils::mark;
17pub use tt::{Delimiter, DelimiterKind, Punct}; 18pub use tt::{Delimiter, DelimiterKind, Punct};
18 19
19use crate::{ 20use crate::{
@@ -76,6 +77,14 @@ pub struct MacroRules {
76 shift: Shift, 77 shift: Shift,
77} 78}
78 79
80/// For Macro 2.0
81#[derive(Clone, Debug, PartialEq, Eq)]
82pub struct MacroDef {
83 rules: Vec<Rule>,
84 /// Highest id of the token we have in TokenMap
85 shift: Shift,
86}
87
79#[derive(Clone, Debug, PartialEq, Eq)] 88#[derive(Clone, Debug, PartialEq, Eq)]
80struct Rule { 89struct Rule {
81 lhs: MetaTemplate, 90 lhs: MetaTemplate,
@@ -179,7 +188,7 @@ impl MacroRules {
179 let mut src = TtIter::new(tt); 188 let mut src = TtIter::new(tt);
180 let mut rules = Vec::new(); 189 let mut rules = Vec::new();
181 while src.len() > 0 { 190 while src.len() > 0 {
182 let rule = Rule::parse(&mut src)?; 191 let rule = Rule::parse(&mut src, true)?;
183 rules.push(rule); 192 rules.push(rule);
184 if let Err(()) = src.expect_char(';') { 193 if let Err(()) = src.expect_char(';') {
185 if src.len() > 0 { 194 if src.len() > 0 {
@@ -200,7 +209,58 @@ impl MacroRules {
200 // apply shift 209 // apply shift
201 let mut tt = tt.clone(); 210 let mut tt = tt.clone();
202 self.shift.shift_all(&mut tt); 211 self.shift.shift_all(&mut tt);
203 mbe_expander::expand(self, &tt) 212 mbe_expander::expand_rules(&self.rules, &tt)
213 }
214
215 pub fn map_id_down(&self, id: tt::TokenId) -> tt::TokenId {
216 self.shift.shift(id)
217 }
218
219 pub fn map_id_up(&self, id: tt::TokenId) -> (tt::TokenId, Origin) {
220 match self.shift.unshift(id) {
221 Some(id) => (id, Origin::Call),
222 None => (id, Origin::Def),
223 }
224 }
225}
226
227impl MacroDef {
228 pub fn parse(tt: &tt::Subtree) -> Result<MacroDef, ParseError> {
229 let mut src = TtIter::new(tt);
230 let mut rules = Vec::new();
231
232 if Some(tt::DelimiterKind::Brace) == tt.delimiter_kind() {
233 mark::hit!(parse_macro_def_rules);
234 while src.len() > 0 {
235 let rule = Rule::parse(&mut src, true)?;
236 rules.push(rule);
237 if let Err(()) = src.expect_char(';') {
238 if src.len() > 0 {
239 return Err(ParseError::Expected("expected `;`".to_string()));
240 }
241 break;
242 }
243 }
244 } else {
245 mark::hit!(parse_macro_def_simple);
246 let rule = Rule::parse(&mut src, false)?;
247 if src.len() != 0 {
248 return Err(ParseError::Expected("remain tokens in macro def".to_string()));
249 }
250 rules.push(rule);
251 }
252 for rule in rules.iter() {
253 validate(&rule.lhs)?;
254 }
255
256 Ok(MacroDef { rules, shift: Shift::new(tt) })
257 }
258
259 pub fn expand(&self, tt: &tt::Subtree) -> ExpandResult<tt::Subtree> {
260 // apply shift
261 let mut tt = tt.clone();
262 self.shift.shift_all(&mut tt);
263 mbe_expander::expand_rules(&self.rules, &tt)
204 } 264 }
205 265
206 pub fn map_id_down(&self, id: tt::TokenId) -> tt::TokenId { 266 pub fn map_id_down(&self, id: tt::TokenId) -> tt::TokenId {
@@ -216,12 +276,14 @@ impl MacroRules {
216} 276}
217 277
218impl Rule { 278impl Rule {
219 fn parse(src: &mut TtIter) -> Result<Rule, ParseError> { 279 fn parse(src: &mut TtIter, expect_arrow: bool) -> Result<Rule, ParseError> {
220 let lhs = src 280 let lhs = src
221 .expect_subtree() 281 .expect_subtree()
222 .map_err(|()| ParseError::Expected("expected subtree".to_string()))?; 282 .map_err(|()| ParseError::Expected("expected subtree".to_string()))?;
223 src.expect_char('=').map_err(|()| ParseError::Expected("expected `=`".to_string()))?; 283 if expect_arrow {
224 src.expect_char('>').map_err(|()| ParseError::Expected("expected `>`".to_string()))?; 284 src.expect_char('=').map_err(|()| ParseError::Expected("expected `=`".to_string()))?;
285 src.expect_char('>').map_err(|()| ParseError::Expected("expected `>`".to_string()))?;
286 }
225 let rhs = src 287 let rhs = src
226 .expect_subtree() 288 .expect_subtree()
227 .map_err(|()| ParseError::Expected("expected subtree".to_string()))?; 289 .map_err(|()| ParseError::Expected("expected subtree".to_string()))?;