aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_mbe
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2020-03-13 14:18:17 +0000
committerFlorian Diebold <[email protected]>2020-03-16 17:38:19 +0000
commit6305d094ac61ed6e437537b93f4e587b415678c9 (patch)
tree89ec8942a287c8a1f6d2955602fe1a3415262cac /crates/ra_mbe
parentb973158aeb337041d4e1434cf5d8c609a0b02bef (diff)
Attempt to implement ranking of rules when none matches perfectly (wip)
Diffstat (limited to 'crates/ra_mbe')
-rw-r--r--crates/ra_mbe/src/mbe_expander.rs19
-rw-r--r--crates/ra_mbe/src/mbe_expander/matcher.rs4
2 files changed, 13 insertions, 10 deletions
diff --git a/crates/ra_mbe/src/mbe_expander.rs b/crates/ra_mbe/src/mbe_expander.rs
index da3952428..5083d5410 100644
--- a/crates/ra_mbe/src/mbe_expander.rs
+++ b/crates/ra_mbe/src/mbe_expander.rs
@@ -14,24 +14,27 @@ pub(crate) fn expand(
14 rules: &crate::MacroRules, 14 rules: &crate::MacroRules,
15 input: &tt::Subtree, 15 input: &tt::Subtree,
16) -> ExpandResult<tt::Subtree> { 16) -> ExpandResult<tt::Subtree> {
17 let (mut result, mut err) = (tt::Subtree::default(), Some(ExpandError::NoMatchingRule)); 17 let (mut result, mut left_over, mut err) = (tt::Subtree::default(), usize::max_value(), Some(ExpandError::NoMatchingRule));
18 for rule in &rules.rules { 18 for rule in &rules.rules {
19 let (res, e) = expand_rule(rule, input); 19 let ((res, left), e) = expand_rule(rule, input);
20 if e.is_none() { 20 if e.is_none() {
21 // if we find a rule that applies without errors, we're done 21 // if we find a rule that applies without errors, we're done
22 return (res, None); 22 return (res, None);
23 } 23 }
24 // TODO decide which result is better 24 // use the rule if we matched more tokens
25 result = res; 25 if left < left_over {
26 err = e; 26 result = res;
27 err = e;
28 left_over = left;
29 }
27 } 30 }
28 (result, err) 31 (result, err)
29} 32}
30 33
31fn expand_rule(rule: &crate::Rule, input: &tt::Subtree) -> ExpandResult<tt::Subtree> { 34fn expand_rule(rule: &crate::Rule, input: &tt::Subtree) -> ExpandResult<(tt::Subtree, usize)> {
32 let (bindings, bindings_err) = dbg!(matcher::match_(&rule.lhs, input)); 35 let ((bindings, left_over), bindings_err) = dbg!(matcher::match_(&rule.lhs, input));
33 let (res, transcribe_err) = dbg!(transcriber::transcribe(&rule.rhs, &bindings)); 36 let (res, transcribe_err) = dbg!(transcriber::transcribe(&rule.rhs, &bindings));
34 (res, bindings_err.or(transcribe_err)) 37 ((res, left_over), bindings_err.or(transcribe_err))
35} 38}
36 39
37/// The actual algorithm for expansion is not too hard, but is pretty tricky. 40/// The actual algorithm for expansion is not too hard, but is pretty tricky.
diff --git a/crates/ra_mbe/src/mbe_expander/matcher.rs b/crates/ra_mbe/src/mbe_expander/matcher.rs
index f9d4952c6..52f1ac252 100644
--- a/crates/ra_mbe/src/mbe_expander/matcher.rs
+++ b/crates/ra_mbe/src/mbe_expander/matcher.rs
@@ -65,7 +65,7 @@ macro_rules! bail {
65 }; 65 };
66} 66}
67 67
68pub(super) fn match_(pattern: &tt::Subtree, src: &tt::Subtree) -> ExpandResult<Bindings> { 68pub(super) fn match_(pattern: &tt::Subtree, src: &tt::Subtree) -> ExpandResult<(Bindings, usize)> {
69 assert!(pattern.delimiter == None); 69 assert!(pattern.delimiter == None);
70 70
71 let mut res = Bindings::default(); 71 let mut res = Bindings::default();
@@ -77,7 +77,7 @@ pub(super) fn match_(pattern: &tt::Subtree, src: &tt::Subtree) -> ExpandResult<B
77 err = Some(err!("leftover tokens")); 77 err = Some(err!("leftover tokens"));
78 } 78 }
79 79
80 (res, err) 80 ((res, src.len()), err)
81} 81}
82 82
83fn match_subtree( 83fn match_subtree(