Skip to content

Commit 48dbee6

Browse files
committed
Add elipses, reorganize the macro components into their own AST node.
1 parent 4257323 commit 48dbee6

File tree

14 files changed

+206
-103
lines changed

14 files changed

+206
-103
lines changed

src/comp/middle/trans.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6378,7 +6378,7 @@ fn trans_expr_out(&@block_ctxt cx, &@ast::expr e, out_method output) ->
63786378
case (ast::expr_rec(?args, ?base)) {
63796379
ret trans_rec(cx, args, base, e.id);
63806380
}
6381-
case (ast::expr_ext(_, _, _)) {
6381+
case (ast::expr_mac(_)) {
63826382
ret cx.fcx.lcx.ccx.sess.bug("unexpanded macro");
63836383
}
63846384
case (ast::expr_fail(?expr)) {

src/comp/middle/tstate/pre_post_conditions.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,7 @@ fn find_pre_post_expr(&fn_ctxt fcx, @expr e) {
570570
case (expr_break) { clear_pp(expr_pp(fcx.ccx, e)); }
571571
case (expr_cont) { clear_pp(expr_pp(fcx.ccx, e)); }
572572
case (expr_port(_)) { clear_pp(expr_pp(fcx.ccx, e)); }
573-
case (expr_ext(_, _, _)) {
573+
case (expr_mac(_)) {
574574
fcx.ccx.tcx.sess.bug("unexpanded macro");
575575
}
576576
case (expr_anon_obj(?anon_obj, _)) {

src/comp/middle/tstate/states.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ fn find_pre_post_state_expr(&fn_ctxt fcx, &prestate pres, @expr e) -> bool {
367367
case (expr_chan(?ex)) {
368368
ret find_pre_post_state_sub(fcx, pres, ex, e.id, none);
369369
}
370-
case (expr_ext(_, _, _)) {
370+
case (expr_mac(_)) {
371371
fcx.ccx.tcx.sess.bug("unexpanded macro");
372372
}
373373
case (expr_put(?maybe_e)) {

src/comp/middle/typeck.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1780,7 +1780,7 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) {
17801780
}
17811781
write::ty_only_fixup(fcx, id, tpt._1);
17821782
}
1783-
case (ast::expr_ext(_,_,_)) {
1783+
case (ast::expr_mac(_)) {
17841784
fcx.ccx.tcx.sess.bug("unexpanded macro");
17851785
}
17861786
case (ast::expr_fail(?expr_opt)) {

src/comp/syntax/ast.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,6 @@ tag expr_ {
305305
expr_field(@expr, ident);
306306
expr_index(@expr, @expr);
307307
expr_path(path);
308-
expr_ext(path, (@expr)[], option::t[str]);
309308
expr_fail(option::t[@expr]);
310309
expr_break;
311310
expr_cont;
@@ -323,7 +322,18 @@ tag expr_ {
323322
to expr_if_check. */
324323
expr_if_check(@expr, block, option::t[@expr]);
325324
expr_port(option::t[@ty]);
325+
expr_chan(@expr);
326326
expr_anon_obj(anon_obj, ty_param[]);
327+
expr_mac(mac);
328+
}
329+
330+
type mac = spanned[mac_];
331+
332+
tag mac_ {
333+
mac_invoc(path, (@expr)[], option::t[str]);
334+
mac_embed_type(@ty);
335+
mac_embed_block(block);
336+
mac_elipsis;
327337
}
328338
329339
type lit = spanned[lit_];
@@ -433,6 +443,7 @@ tag ty_ {
433443
ty_path(path, node_id);
434444
ty_type;
435445
ty_constr(@ty, (@constr)[]);
446+
ty_mac(mac);
436447
}
437448

438449

src/comp/syntax/ext/expand.rs

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import codemap::emit_error;
33
import driver::session;
44
import syntax::ast::crate;
55
import syntax::ast::expr_;
6-
import syntax::ast::expr_ext;
6+
import syntax::ast::expr_mac;
7+
import syntax::ast::mac_invoc;
78
import syntax::fold::*;
89

910
import std::option::none;
@@ -16,27 +17,39 @@ fn expand_expr(&hashmap[str, base::syntax_extension] exts,
1617
&session::session sess, &expr_ e, ast_fold fld,
1718
&fn(&ast::expr_, ast_fold) -> expr_ orig) -> expr_ {
1819
ret alt(e) {
19-
case (expr_ext(?pth, ?args, ?body)) {
20-
assert(ivec::len(pth.node.idents) > 0u);
21-
auto extname = pth.node.idents.(0);
22-
auto ext_cx = base::mk_ctxt(sess);
23-
alt (exts.find(extname)) {
24-
case (none) {
25-
emit_error(some(pth.span), "unknown syntax expander: '"
26-
+ extname + "'", sess.get_codemap());
27-
fail
28-
}
29-
case (some(base::normal(?ext))) {
30-
//keep going, outside-in
31-
fld.fold_expr(ext(ext_cx, pth.span, args, body)).node
20+
case (expr_mac(?mac)) {
21+
alt(mac.node) {
22+
case (mac_invoc(?pth, ?args, ?body)) {
23+
assert(ivec::len(pth.node.idents) > 0u);
24+
auto extname = pth.node.idents.(0);
25+
auto ext_cx = base::mk_ctxt(sess);
26+
alt (exts.find(extname)) {
27+
case (none) {
28+
emit_error(some(pth.span),
29+
"unknown syntax expander: '"
30+
+ extname + "'", sess.get_codemap());
31+
fail
32+
}
33+
case (some(base::normal(?ext))) {
34+
//keep going, outside-in
35+
fld.fold_expr(ext(ext_cx, pth.span,
36+
args, body)).node
37+
}
38+
case (some(base::macro_defining(?ext))) {
39+
auto named_extension
40+
= ext(ext_cx, pth.span, args, body);
41+
exts.insert(named_extension._0,
42+
named_extension._1);
43+
ast::expr_tup(~[])
44+
}
45+
}
3246
}
33-
case (some(base::macro_defining(?ext))) {
34-
auto named_extension = ext(ext_cx, pth.span, args, body);
35-
exts.insert(named_extension._0, named_extension._1);
36-
ast::expr_tup([])
47+
case (_) {
48+
emit_error(some(mac.span), "naked syntactic bit",
49+
sess.get_codemap());
50+
fail
3751
}
3852
}
39-
4053
}
4154
case (_) { orig(e, fld) }
4255
};

src/comp/syntax/ext/simplext.rs

Lines changed: 44 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,12 @@ import ast::path;
2222
import ast::path_;
2323
import ast::expr_path;
2424
import ast::expr_vec;
25-
import ast::expr_ext;
25+
import ast::expr_mac;
26+
import ast::mac_invoc;
2627

2728
export add_new_extension;
2829

29-
fn lookup(&vec[invk_binding] ibs, ident i) -> option::t[invk_binding] {
30+
fn lookup(&(invk_binding)[] ibs, ident i) -> option::t[invk_binding] {
3031
for (invk_binding ib in ibs) {
3132
alt (ib) {
3233
case (ident_binding(?p_id, _)) { if (i == p_id) { ret some(ib); }}
@@ -96,7 +97,7 @@ fn subst_expr(&ext_ctxt cx, &(invk_binding)[] ibs, &ast::expr_ e,
9697
}
9798
}
9899

99-
type pat_ext = rec(vec[@ast::expr] invk, @ast::expr body);
100+
type pat_ext = rec((@ast::expr)[] invk, @ast::expr body);
100101

101102
// maybe box?
102103
tag invk_binding {
@@ -113,6 +114,24 @@ fn path_to_ident(&path pth) -> option::t[ident] {
113114
ret none;
114115
}
115116

117+
fn process_clause(&ext_ctxt cx, &mutable vec[pat_ext] pes,
118+
&mutable option::t[str] macro_name, &path pth,
119+
&(@ast::expr)[] invoc_args, @ast::expr body) {
120+
let str clause_name = alt(path_to_ident(pth)) {
121+
case (some(?id)) { id }
122+
case (none) {
123+
cx.span_fatal(pth.span, "macro name must not be a path")
124+
}
125+
};
126+
if (macro_name == none) {
127+
macro_name = some(clause_name);
128+
} else if (macro_name != some(clause_name)) {
129+
cx.span_fatal(pth.span, "#macro can only introduce one name");
130+
}
131+
pes += [rec(invk=invoc_args, body=body)];
132+
}
133+
134+
116135
fn add_new_extension(&ext_ctxt cx, span sp, &(@ast::expr)[] args,
117136
option::t[str] body) -> tup(str, syntax_extension) {
118137
let option::t[str] macro_name = none;
@@ -121,28 +140,19 @@ fn add_new_extension(&ext_ctxt cx, span sp, &(@ast::expr)[] args,
121140
alt(arg.node) {
122141
case(expr_vec(?elts, ?mut, ?seq_kind)) {
123142

124-
if (len(elts) != 2u) {
143+
if (ivec::len(elts) != 2u) {
125144
cx.span_fatal((*arg).span,
126145
"extension clause must consist of [" +
127146
"macro invocation, expansion body]");
128147
}
129148
alt(elts.(0u).node) {
130-
case(expr_ext(?pth, ?invk_args, ?body)) {
131-
let str clause_name = alt(path_to_ident(pth)) {
132-
case (some(?id)) { id }
133-
case (none) {
134-
cx.span_fatal
135-
(elts.(0u).span,
136-
"macro name must not be a path")
149+
case(expr_mac(?mac)) {
150+
alt (mac.node) {
151+
case (mac_invoc(?pth, ?invoc_args, ?body)) {
152+
process_clause(cx, pat_exts, macro_name,
153+
pth, invoc_args, elts.(1u));
137154
}
138-
};
139-
if (macro_name == none) {
140-
macro_name = some(clause_name);
141-
} else if (macro_name != some(clause_name)) {
142-
cx.span_fatal(elts.(0u).span, "macros must have"
143-
+ " only one name");
144155
}
145-
pat_exts += [rec(invk=invk_args, body=elts.(1u))];
146156
}
147157
case(_) {
148158
cx.span_fatal(elts.(0u).span, "extension clause must"
@@ -169,25 +179,25 @@ fn add_new_extension(&ext_ctxt cx, span sp, &(@ast::expr)[] args,
169179
normal(ext));
170180

171181

172-
fn generic_extension(&ext_ctxt cx, span sp, &vec[@ast::expr] args,
182+
fn generic_extension(&ext_ctxt cx, span sp, &(@ast::expr)[] args,
173183
option::t[str] body, @vec[pat_ext] clauses)
174184
-> @ast::expr {
175185

176186
/* returns a list of bindings, or none if the match fails. */
177187
fn match_invk(@ast::expr pattern, @ast::expr argument)
178-
-> option::t[vec[invk_binding]] {
188+
-> option::t[(invk_binding)[]] {
179189
auto pat = pattern.node;
180190
auto arg = argument.node;
181191
ret alt (pat) {
182192
case (expr_vec(?p_elts, _, _)) {
183193
alt (arg) {
184194
case (expr_vec(?a_elts, _, _)) {
185-
if (vec::len(p_elts) != vec::len(a_elts)) {
195+
if (ivec::len(p_elts) != ivec::len(a_elts)) {
186196
none[vec[invk_binding]]
187197
}
188198
let uint i = 0u;
189-
let vec[invk_binding] res = [];
190-
while (i < vec::len(p_elts)) {
199+
let (invk_binding)[] res = ~[];
200+
while (i < ivec::len(p_elts)) {
191201
alt (match_invk(p_elts.(i), a_elts.(i))) {
192202
case (some(?v)) { res += v; }
193203
case (none) { ret none; }
@@ -207,34 +217,36 @@ fn add_new_extension(&ext_ctxt cx, span sp, &(@ast::expr)[] args,
207217
case (expr_path(?a_pth)) {
208218
alt (path_to_ident(a_pth)) {
209219
case (some(?a_id)) {
210-
some([ident_binding
211-
(p_id, respan(argument.span,
220+
some(~[ident_binding
221+
(p_id,
222+
respan(argument.span,
212223
a_id))])
213224
}
214225
case (none) {
215-
some([path_binding(p_id, @a_pth)])
226+
some(~[path_binding(p_id,
227+
@a_pth)])
216228
}
217229
}
218230
}
219231
case (_) {
220-
some([expr_binding(p_id, argument)])
232+
some(~[expr_binding(p_id, argument)])
221233
}
222234
}
223235
}
224236
// FIXME this still compares on internal spans
225-
case (_) { if(pat == arg) { some([]) } else { none } }
237+
case (_) { if(pat == arg) { some(~[]) } else { none }}
226238
}
227239
}
228240
// FIXME this still compares on internal spans
229-
case (_) { if (pat == arg) { some([]) } else { none } }
241+
case (_) { if (pat == arg) { some(~[]) } else { none }}
230242
}
231243
}
232244

233245
for (pat_ext pe in *clauses) {
234-
if (vec::len(args) != vec::len(pe.invk)) { cont; }
246+
if (ivec::len(args) != ivec::len(pe.invk)) { cont; }
235247
let uint i = 0u;
236-
let vec[invk_binding] bindings = [];
237-
while (i < vec::len(args)) {
248+
let (invk_binding)[] bindings = ~[];
249+
while (i < ivec::len(args)) {
238250
alt (match_invk(pe.invk.(i), args.(i))) {
239251
case (some(?v)) { bindings += v; }
240252
case (none) { cont }

src/comp/syntax/fold.rs

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,25 @@ fn fold_arg_(&arg a, ast_fold fld) -> arg {
126126
ret rec(mode=a.mode, ty=fld.fold_ty(a.ty),
127127
ident=fld.fold_ident(a.ident), id=a.id);
128128
}
129+
//used in noop_fold_expr, and possibly elsewhere in the future
130+
fn fold_mac_(&mac m, ast_fold fld) -> mac {
131+
ret rec(node=
132+
alt(m.node) {
133+
case (mac_invoc(?pth,?args,?body)) {
134+
mac_invoc(fld.fold_path(pth),
135+
ivec::map(fld.fold_expr, args), body)
136+
}
137+
case (mac_embed_type(?ty)) {
138+
mac_embed_type(fld.fold_ty(ty))
139+
}
140+
case (mac_embed_block(?block)) {
141+
mac_embed_block(fld.fold_block(block))
142+
}
143+
case (mac_elipsis) { mac_elipsis }
144+
},
145+
span=m.span);
146+
}
147+
129148

130149

131150

@@ -319,6 +338,7 @@ fn noop_fold_expr(&expr_ e, ast_fold fld) -> expr_ {
319338
}
320339
auto fold_anon_obj = bind fold_anon_obj_(_,fld);
321340

341+
auto fold_mac = bind fold_mac_(_,fld);
322342

323343
ret alt (e) {
324344
case (expr_vec(?exprs, ?mut, ?seq_kind)) {
@@ -414,10 +434,6 @@ fn noop_fold_expr(&expr_ e, ast_fold fld) -> expr_ {
414434
case (expr_path(?pth)) {
415435
expr_path(fld.fold_path(pth))
416436
}
417-
case (expr_ext(?pth, ?args, ?body)) {
418-
expr_ext(fld.fold_path(pth), ivec::map(fld.fold_expr, args),
419-
body, fld.fold_expr(expanded))
420-
}
421437
case (expr_fail(?e)) { expr_fail(option::map(fld.fold_expr, e)) }
422438
case (expr_break()) { e }
423439
case (expr_cont()) { e }
@@ -445,11 +461,8 @@ fn noop_fold_expr(&expr_ e, ast_fold fld) -> expr_ {
445461
case (expr_anon_obj(?ao, ?typms)) {
446462
expr_anon_obj(fold_anon_obj(ao), typms)
447463
}
448-
case (expr_embeded_type(?ty)) {
449-
expr_embeded_type(fld.fold_ty(ty))
450-
}
451-
case (expr_embeded_block(?blk)) {
452-
expr_embeded_block(fld.fold_block(blk))
464+
case (expr_mac(?mac)) {
465+
expr_mac(fold_mac(mac))
453466
}
454467
}
455468
}

src/comp/syntax/parse/lexer.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,15 @@ fn next_token(&reader rdr) -> token::token {
365365
case ('?') { rdr.bump(); ret token::QUES; }
366366
case (';') { rdr.bump(); ret token::SEMI; }
367367
case (',') { rdr.bump(); ret token::COMMA; }
368-
case ('.') { rdr.bump(); ret token::DOT; }
368+
case ('.') {
369+
rdr.bump();
370+
if (rdr.curr() == '.' && rdr.next() == '.') {
371+
rdr.bump();
372+
rdr.bump();
373+
ret token::ELIPSIS;
374+
}
375+
ret token::DOT;
376+
}
369377
case ('(') { rdr.bump(); ret token::LPAREN; }
370378
case (')') { rdr.bump(); ret token::RPAREN; }
371379
case ('{') { rdr.bump(); ret token::LBRACE; }

0 commit comments

Comments
 (0)