diff options
| author | Paul Stansifer <paul.stansifer@gmail.com> | 2012-07-27 17:32:15 -0700 |
|---|---|---|
| committer | Paul Stansifer <paul.stansifer@gmail.com> | 2012-07-30 18:04:19 -0700 |
| commit | a28812cfd66115c013b306c4c809dc3dc8c8b6ac (patch) | |
| tree | 0a278f1b82616928ed0d891be4b55189f6d2d995 /src/libsyntax | |
| parent | 19922fcd93bfeac123719e319b7166f50660f847 (diff) | |
| download | rust-a28812cfd66115c013b306c4c809dc3dc8c8b6ac.tar.gz rust-a28812cfd66115c013b306c4c809dc3dc8c8b6ac.zip | |
Improve some documentation.
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ext/tt/macro_rules.rs | 34 |
1 files changed, 20 insertions, 14 deletions
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index cd6ebce4394..a5fc20c461b 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -5,12 +5,10 @@ import ast::{ident, matcher_, matcher, match_tok, import parse::lexer::{new_tt_reader, tt_reader_as_reader, reader}; import parse::token::{FAT_ARROW, SEMI, LBRACE, RBRACE, nt_matchers, nt_tt}; import parse::parser::{parser, SOURCE_FILE}; -import earley_parser::{parse, success, failure, named_match, +import earley_parser::{parse, parse_or_else, success, failure, named_match, matched_seq, matched_nonterminal}; import std::map::hashmap; - - fn add_new_extension(cx: ext_ctxt, sp: span, name: ident, arg: ~[ast::token_tree]) -> base::mac_result { // these spans won't matter, anyways @@ -18,6 +16,9 @@ fn add_new_extension(cx: ext_ctxt, sp: span, name: ident, {node: m, span: {lo: 0u, hi: 0u, expn_info: none}} } + // The grammar for macro_rules! is: + // $( $lhs:mtcs => $rhs:tt );+ + // ...quasiquoting this would be nice. let argument_gram = ~[ ms(match_seq(~[ ms(match_nonterminal(@~"lhs",@~"matchers", 0u)), @@ -25,43 +26,48 @@ fn add_new_extension(cx: ext_ctxt, sp: span, name: ident, ms(match_nonterminal(@~"rhs",@~"tt", 1u)), ], some(SEMI), false, 0u, 2u))]; + + // Parse the macro_rules! invocation (`none` is for no interpolations): let arg_reader = new_tt_reader(cx.parse_sess().span_diagnostic, cx.parse_sess().interner, none, arg); - let arguments = alt parse(cx.parse_sess(), cx.cfg(), - arg_reader as reader, argument_gram) { - success(m) { m } - failure(sp, msg) { cx.span_fatal(sp, msg); } - }; + let argument_map = parse_or_else(cx.parse_sess(), cx.cfg(), + arg_reader as reader, argument_gram); - let lhses = alt arguments.get(@~"lhs") { + // Extract the arguments: + let lhses:~[@named_match] = alt argument_map.get(@~"lhs") { @matched_seq(s, sp) { s } _ { cx.span_bug(sp, ~"wrong-structured lhs") } }; - let rhses = alt arguments.get(@~"rhs") { + let rhses:~[@named_match] = alt argument_map.get(@~"rhs") { @matched_seq(s, sp) { s } _ { cx.span_bug(sp, ~"wrong-structured rhs") } }; + // Given `lhses` and `rhses`, this is the new macro we create fn generic_extension(cx: ext_ctxt, sp: span, arg: ~[ast::token_tree], lhses: ~[@named_match], rhses: ~[@named_match]) -> mac_result { + // Which arm's failure should we report? (the one furthest along) let mut best_fail_spot = {lo: 0u, hi: 0u, expn_info: none}; let mut best_fail_msg = ~"internal error: ran no matchers"; let s_d = cx.parse_sess().span_diagnostic; let itr = cx.parse_sess().interner; - for lhses.eachi() |i, lhs| { + for lhses.eachi() |i, lhs| { // try each arm's matchers alt lhs { @matched_nonterminal(nt_matchers(mtcs)) { + // `none` is because we're not interpolating let arg_rdr = new_tt_reader(s_d, itr, none, arg) as reader; alt parse(cx.parse_sess(), cx.cfg(), arg_rdr, mtcs) { - success(m) { - let rhs = alt rhses[i] { + success(named_matches) { + let rhs = alt rhses[i] { // okay, what's your transcriber? @matched_nonterminal(nt_tt(@tt)) { tt } _ { cx.span_bug(sp, ~"bad thing in rhs") } }; - let trncbr = new_tt_reader(s_d, itr, some(m), ~[rhs]); + // rhs has holes ( `$id` and `$(...)` that need filled) + let trncbr = new_tt_reader(s_d, itr, some(named_matches), + ~[rhs]); let p = parser(cx.parse_sess(), cx.cfg(), trncbr as reader, SOURCE_FILE); ret mr_expr(p.parse_expr()); |
