Skip to content

Commit 1d9f01c

Browse files
committed
Comments in the new macro system, reflecting conversation with pauls.
1 parent f7382c4 commit 1d9f01c

File tree

4 files changed

+125
-6
lines changed

4 files changed

+125
-6
lines changed

src/libsyntax/ast.rs

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,47 @@ enum token_tree {
376376
type matcher = spanned<matcher_>;
377377

378378
#[auto_serialize]
379+
//
380+
// Matchers are nodes defined-by and recognized-by the main rust parser and
381+
// language, but they're only ever found inside syntax-extension invocations.
382+
// They represent a small sub-language for pattern-matching token-trees, and
383+
// are thus primarily used by the macro-defining extension itself.
384+
//
385+
// mtc_tok ===> A matcher that matches a single token,
386+
// denoted by the token itself. So long as
387+
// there's no $ involved.
388+
//
389+
//
390+
// mtc_rep ===> A matcher that matches a sequence of
391+
// sub-matchers, denoted various ways:
392+
//
393+
// $(M)* zero or more Ms
394+
// $(M)+ one or more Ms
395+
// $(M),+ one or more comma-separated Ms
396+
// $(A B C);* zero or more semi-separated 'A B C' seqs
397+
//
398+
//
399+
// mtc_bb ===> A matcher that matches one of a few interesting named rust
400+
// nonterminals, such as types, expressions, items, or raw
401+
// token-trees. A black-box matcher on expr, for example, binds an
402+
// expr to a given ident, and that ident can re-occur as an
403+
// interpolation in the RHS of a macro-by-example rule. For
404+
// example:
405+
//
406+
// $foo:expr => 1 + $foo // interpolate an expr
407+
// $foo:tt => $foo // interpolate a token-tree
408+
// $foo:tt => bar! $foo // only other valid interpolation
409+
// // is in arg position for another macro
410+
//
411+
// As a final, horrifying aside, note that macro-by-example's input is
412+
// also matched by one of these matchers. Holy self-referential! It is matched
413+
// by an mtc_rep, specifically this one:
414+
//
415+
// $( $lhs:mtcs => $rhs:tt );+
416+
//
417+
// If you understand that, you have closed to loop and understand the whole
418+
// macro system. Congratulations.
419+
//
379420
enum matcher_ {
380421
/* match one token */
381422
mtc_tok(token::token),
@@ -401,10 +442,11 @@ type mac_body = option<mac_body_>;
401442
#[auto_serialize]
402443
enum mac_ {
403444
mac_invoc(@path, mac_arg, mac_body),
404-
mac_invoc_tt(@path,~[token_tree]),//will kill mac_invoc and steal its name
405-
mac_embed_type(@ty),
406-
mac_embed_block(blk),
407-
mac_ellipsis,
445+
mac_invoc_tt(@path,~[token_tree]), // will kill mac_invoc and steal its name
446+
mac_embed_type(@ty), // obsolete quoter
447+
mac_embed_block(blk), // obsolete quoter
448+
mac_ellipsis, // obsolete pattern-match terminal
449+
408450
// the span is used by the quoter/anti-quoter ...
409451
mac_aq(span /* span of quote */, @expr), // anti-quote
410452
mac_var(uint)

src/libsyntax/ext/base.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,43 @@ import diagnostic::span_handler;
44
import codemap::{codemap, span, expn_info, expanded_from};
55
import std::map::str_hash;
66

7+
8+
// Nomenclature / abbreviations in the ext modules:
9+
//
10+
// ms: matcher span, wraps a matcher with fake span
11+
// mtc: matcher
12+
// mtcs: matchers
13+
// tt: token tree
14+
// bt: backtrace
15+
// cx: expansion context
16+
// mr: macro result
17+
//
18+
19+
// obsolete old-style #macro code:
20+
//
21+
// syntax_expander, normal, macro_defining, macro_definer,
22+
// builtin
23+
//
24+
// new-style macro! tt code:
25+
//
26+
// syntax_expander_tt, syntax_expander_tt_item, mac_result,
27+
// expr_tt, item_tt
28+
//
29+
// also note that ast::mac has way too many cases and can probably
30+
// be trimmed down substantially.
31+
732
// second argument is the span to blame for general argument problems
833
type syntax_expander_ =
934
fn@(ext_ctxt, span, ast::mac_arg, ast::mac_body) -> @ast::expr;
1035
// second argument is the origin of the macro, if user-defined
1136
type syntax_expander = {expander: syntax_expander_, span: option<span>};
1237

1338
type macro_def = {ident: ast::ident, ext: syntax_extension};
39+
40+
// macro_definer is obsolete, remove when #old_macros go away.
1441
type macro_definer =
1542
fn@(ext_ctxt, span, ast::mac_arg, ast::mac_body) -> macro_def;
43+
1644
type item_decorator =
1745
fn@(ext_ctxt, span, ast::meta_item, ~[@ast::item]) -> ~[@ast::item];
1846

@@ -32,10 +60,17 @@ enum mac_result {
3260
}
3361

3462
enum syntax_extension {
63+
64+
// normal() is obsolete, remove when #old_macros go away.
3565
normal(syntax_expander),
66+
67+
// macro_defining() is obsolete, remove when #old_macros go away.
3668
macro_defining(macro_definer),
69+
70+
// #[auto_serialize] and such. will probably survive death of #old_macros
3771
item_decorator(item_decorator),
3872

73+
// Token-tree expanders
3974
expr_tt(syntax_expander_tt),
4075
item_tt(syntax_expander_tt_item),
4176
}
@@ -87,6 +122,10 @@ fn syntax_expander_table() -> hashmap<~str, syntax_extension> {
87122
ret syntax_expanders;
88123
}
89124

125+
126+
// One of these is made during expansion and incrementally updated as we go;
127+
// when a macro expansion occurs, the resulting nodes have the backtrace()
128+
// -> expn_info of their expansion context stored into their span.
90129
iface ext_ctxt {
91130
fn codemap() -> codemap;
92131
fn parse_sess() -> parse::parse_sess;
@@ -244,6 +283,9 @@ fn get_mac_body(cx: ext_ctxt, sp: span, args: ast::mac_body)
244283
}
245284
}
246285

286+
// Massage syntactic form of new-style arguments to internal representation
287+
// of old-style macro args, such that old-style macro can be run and invoked
288+
// using new syntax. This will be obsolete when #old_macros go away.
247289
fn tt_args_to_original_flavor(cx: ext_ctxt, sp: span, arg: ~[ast::token_tree])
248290
-> ast::mac_arg {
249291
import ast::{matcher, matcher_, mtc_tok, mtc_rep, mtc_bb};

src/libsyntax/ext/expand.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,12 @@ fn expand_expr(exts: hashmap<~str, syntax_extension>, cx: ext_ctxt,
1616
-> (expr_, span)
1717
{
1818
ret alt e {
19+
// expr_mac should really be expr_ext or something; it's the
20+
// entry-point for all syntax extensions.
1921
expr_mac(mac) {
22+
23+
// Old-style macros, for compatibility, will erase this whole
24+
// block once we've transitioned.
2025
alt mac.node {
2126
mac_invoc(pth, args, body) {
2227
assert (vec::len(pth.idents) > 0u);
@@ -58,6 +63,9 @@ fn expand_expr(exts: hashmap<~str, syntax_extension>, cx: ext_ctxt,
5863
}
5964
}
6065
}
66+
67+
// Token-tree macros, these will be the only case when we're
68+
// finished transitioning.
6169
mac_invoc_tt(pth, tts) {
6270
assert (vec::len(pth.idents) == 1u);
6371
let extname = pth.idents[0];
@@ -111,6 +119,15 @@ fn expand_expr(exts: hashmap<~str, syntax_extension>, cx: ext_ctxt,
111119
};
112120
}
113121

122+
// This is a secondary mechanism for invoking syntax extensions on items:
123+
// "decorator" attributes, such as #[auto_serialize]. These are invoked by an
124+
// attribute prefixing an item, and are interpreted by feeding the item
125+
// through the named attribute _as a syntax extension_ and splicing in the
126+
// resulting item vec into place in favour of the decorator. Note that
127+
// these do _not_ work for macro extensions, just item_decorator ones.
128+
//
129+
// NB: there is some redundancy between this and expand_item, below, and
130+
// they might benefit from some amount of semantic and language-UI merger.
114131
fn expand_mod_items(exts: hashmap<~str, syntax_extension>, cx: ext_ctxt,
115132
module: ast::_mod, fld: ast_fold,
116133
orig: fn@(ast::_mod, ast_fold) -> ast::_mod)
@@ -145,7 +162,8 @@ fn expand_mod_items(exts: hashmap<~str, syntax_extension>, cx: ext_ctxt,
145162
ret {items: new_items with module};
146163
}
147164

148-
/* record module we enter for `#mod` */
165+
// Support for item-position macro invocations, exactly the same
166+
// logic as for expression-position macro invocations.
149167
fn expand_item(exts: hashmap<~str, syntax_extension>,
150168
cx: ext_ctxt, &&it: @ast::item, fld: ast_fold,
151169
orig: fn@(&&@ast::item, ast_fold) -> option<@ast::item>)

src/libsyntax/ext/tt/earley_parser.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,24 @@ fn initial_matcher_pos(ms: ~[matcher], sep: option<token>, lo: uint)
7777
match_lo: 0u, match_hi: match_idx_hi, sp_lo: lo}
7878
}
7979

80-
/* logically, an arb_depth should contain only one kind of nonterminal */
80+
// arb_depth is a pattern-match result for a single black-box matcher
81+
// (ast::mtc_bb): so it is associated with a single ident in a parse, and all
82+
// leaves in the arb_depth have the same nonterminal type (expr, item,
83+
// etc). All the leaves in a single arb_depth correspond to a single mtc_bb in
84+
// the ast::matcher that produced it.
85+
//
86+
// It should probably be renamed, it has more or less exact correspondence to
87+
// ast::match nodes, and the in-memory structure of a particular arb_depth
88+
// represents the match that occurred when a particular subset of an
89+
// ast::match -- those ast::matcher nodes leading to a single mtc_bb -- was
90+
// applied to a particular token tree.
91+
//
92+
// The width of each seq in the arb_depth, and the identity of the leaf nodes,
93+
// will depend on the token tree it was applied to: each seq corresponds to a
94+
// single mtc_rep in the originating ast::matcher. The depth of the arb_depth
95+
// structure will therefore depend only on the nesting depth of mtc_reps in
96+
// the originating ast::matcher it was derived from.
97+
8198
enum arb_depth { leaf(whole_nt), seq(~[@arb_depth], codemap::span) }
8299

83100
type earley_item = matcher_pos;

0 commit comments

Comments
 (0)