Skip to content

Commit 473b1ec

Browse files
committed
Make token trees parseable.
1 parent b6ed1de commit 473b1ec

File tree

8 files changed

+82
-5
lines changed

8 files changed

+82
-5
lines changed

src/libsyntax/ast.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import std::serialization::{serializer,
1717
deserialize_str,
1818
serialize_bool,
1919
deserialize_bool};
20+
import parse::token;
21+
2022

2123
/* Note #1972 -- spans are serialized but not deserialized */
2224
fn serialize_span<S>(_s: S, _v: span) {
@@ -371,6 +373,16 @@ enum blk_sort {
371373
}
372374
*/
373375

376+
#[auto_serialize]
377+
type token_tree = spanned<token_tree_>;
378+
379+
#[auto_serialize]
380+
enum token_tree_ {
381+
/* for macro invocations; parsing is the macro's job */
382+
tt_delim(token::token, [token_tree]),
383+
tt_flat(token::token)
384+
}
385+
374386
#[auto_serialize]
375387
type mac = spanned<mac_>;
376388

@@ -386,6 +398,7 @@ type mac_body = option<mac_body_>;
386398
#[auto_serialize]
387399
enum mac_ {
388400
mac_invoc(@path, mac_arg, mac_body),
401+
mac_invoc_tt(@path, token_tree), //will kill mac_invoc and steal its name
389402
mac_embed_type(@ty),
390403
mac_embed_block(blk),
391404
mac_ellipsis,

src/libsyntax/ext/simplext.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,7 @@ fn p_t_s_r_mac(cx: ext_ctxt, mac: ast::mac, s: selector, b: binders) {
549549
alt mac.node {
550550
ast::mac_ellipsis { cx.span_fatal(mac.span, "misused `...`"); }
551551
ast::mac_invoc(_, _, _) { no_des(cx, mac.span, "macro calls"); }
552+
ast::mac_invoc_tt(_, _) { no_des(cx, mac.span, "macro calls"); }
552553
ast::mac_embed_type(ty) {
553554
alt ty.node {
554555
ast::ty_path(pth, _) {

src/libsyntax/fold.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ fn fold_mac_(m: mac, fld: ast_fold) -> mac {
119119
mac_invoc(fld.fold_path(pth),
120120
option::map(arg, fld.fold_expr), body)
121121
}
122+
mac_invoc_tt(pth, tt) { m.node }
122123
mac_embed_type(ty) { mac_embed_type(fld.fold_ty(ty)) }
123124
mac_embed_block(blk) { mac_embed_block(fld.fold_block(blk)) }
124125
mac_ellipsis { mac_ellipsis }

src/libsyntax/parse/attr.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ impl parser_attr for parser {
2424
ret some(left([first_attr] + self.parse_outer_attributes()));
2525
} else if !(self.look_ahead(1u) == token::LT
2626
|| self.look_ahead(1u) == token::LBRACKET
27+
|| self.look_ahead(1u) == token::POUND
2728
|| expect_item_next) {
2829
self.bump();
2930
ret some(right(self.parse_syntax_ext_naked(lo)));

src/libsyntax/parse/parser.rs

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import std::map::{hashmap, str_hash};
44
import token::{can_begin_expr, is_ident, is_plain_ident};
55
import codemap::{span,fss_none};
66
import util::interner;
7-
import ast_util::{spanned, mk_sp, ident_to_path, operator_prec};
7+
import ast_util::{spanned, respan, mk_sp, ident_to_path, operator_prec};
88
import ast::*;
99
import lexer::reader;
1010
import prec::{as_prec, token_to_binop};
@@ -801,10 +801,16 @@ class parser {
801801
{|p| p.parse_expr()});
802802
hi = self.span.hi;
803803
ex = expr_vec(es, mutbl);
804+
} else if self.token == token::POUND
805+
&& self.look_ahead(1u) == token::POUND {
806+
self.bump(); self.bump();
807+
let macname = self.parse_path_without_tps();
808+
let macbody = self.parse_token_tree();
809+
ret pexpr(self.mk_mac_expr(lo, self.span.hi,
810+
mac_invoc_tt(macname, macbody)));
804811
} else if self.token == token::POUND
805812
&& self.look_ahead(1u) == token::LT {
806-
self.bump();
807-
self.bump();
813+
self.bump(); self.bump();
808814
let ty = self.parse_ty(false);
809815
self.expect(token::GT);
810816

@@ -813,8 +819,7 @@ class parser {
813819
mac_embed_type(ty)));
814820
} else if self.token == token::POUND
815821
&& self.look_ahead(1u) == token::LBRACE {
816-
self.bump();
817-
self.bump();
822+
self.bump(); self.bump();
818823
let blk = mac_embed_block(
819824
self.parse_block_tail(lo, default_blk));
820825
ret pexpr(self.mk_mac_expr(lo, self.span.hi, blk));
@@ -1053,6 +1058,47 @@ class parser {
10531058
ret e;
10541059
}
10551060

1061+
fn parse_token_tree() -> token_tree {
1062+
#[doc="what's the opposite delimiter?"]
1063+
fn flip(t: token::token) -> token::token {
1064+
alt t {
1065+
token::LPAREN { token::RPAREN }
1066+
token::LBRACE { token::RBRACE }
1067+
token::LBRACKET { token::RBRACKET }
1068+
_ { fail }
1069+
}
1070+
}
1071+
1072+
fn parse_tt_flat(p: parser, delim_ok: bool) -> token_tree {
1073+
alt p.token {
1074+
token::RPAREN | token::RBRACE | token::RBRACKET
1075+
if !delim_ok {
1076+
p.fatal("incorrect close delimiter: `"
1077+
+ token_to_str(p.reader, p.token) + "`");
1078+
}
1079+
token::EOF {
1080+
p.fatal("file ended in the middle of a macro invocation");
1081+
}
1082+
_ { /* ok */ }
1083+
}
1084+
let res = tt_flat(p.span.lo, p.token);
1085+
p.bump();
1086+
ret res;
1087+
}
1088+
1089+
ret alt self.token {
1090+
token::LPAREN | token::LBRACE | token::LBRACKET {
1091+
let ket = flip(self.token);
1092+
tt_delim([parse_tt_flat(self, true)] +
1093+
self.parse_seq_to_before_end(ket, seq_sep_none(),
1094+
{|p| p.parse_token_tree()})
1095+
+ [parse_tt_flat(self, true)])
1096+
}
1097+
_ { parse_tt_flat(self, false) }
1098+
};
1099+
}
1100+
1101+
10561102
fn parse_prefix_expr() -> pexpr {
10571103
let lo = self.span.lo;
10581104
let mut hi;

src/libsyntax/parse/token.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,21 @@
11
import util::interner;
22
import util::interner::interner;
33
import std::map::{hashmap, str_hash};
4+
import std::serialization::{serializer,
5+
deserializer,
6+
serialize_uint,
7+
deserialize_uint,
8+
serialize_i64,
9+
deserialize_i64,
10+
serialize_u64,
11+
deserialize_u64,
12+
serialize_bool,
13+
deserialize_bool};
414

15+
#[auto_serialize]
516
type str_num = uint;
617

18+
#[auto_serialize]
719
enum binop {
820
PLUS,
921
MINUS,
@@ -17,6 +29,7 @@ enum binop {
1729
SHR,
1830
}
1931

32+
#[auto_serialize]
2033
enum token {
2134
/* Expression-operator symbols. */
2235
EQ,

src/libsyntax/syntax.rc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ mod util {
3030
mod parse {
3131
export parser;
3232
export lexer;
33+
export token;
3334
export comments;
3435
export prec;
3536
export classify;

src/libsyntax/visit.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,7 @@ fn visit_mac<E>(m: mac, e: E, v: vt<E>) {
351351
alt m.node {
352352
ast::mac_invoc(pth, arg, body) {
353353
option::map(arg) {|arg| v.visit_expr(arg, e, v)}; }
354+
ast::mac_invoc_tt(pth, tt) { /* no user-serviceable parts inside */ }
354355
ast::mac_embed_type(ty) { v.visit_ty(ty, e, v); }
355356
ast::mac_embed_block(blk) { v.visit_block(blk, e, v); }
356357
ast::mac_ellipsis { }

0 commit comments

Comments
 (0)