Skip to content

Commit 9fe547d

Browse files
committed
Make extracting syntax extension arguments easier.
1 parent cdcce3e commit 9fe547d

File tree

12 files changed

+62
-80
lines changed

12 files changed

+62
-80
lines changed

src/libcore/path.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ fn connect_many(paths: [path]) -> path {
136136
}
137137

138138
#[doc = "
139-
Split a path into it's individual components
139+
Split a path into its individual components
140140
141141
Splits a given path by path separators and returns a vector containing
142142
each piece of the path. On Windows, if the path is absolute then

src/librustsyntax/ext/base.rs

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,10 +153,37 @@ fn make_new_lit(cx: ext_ctxt, sp: codemap::span, lit: ast::lit_) ->
153153
ret @{id: cx.next_id(), node: ast::expr_lit(sp_lit), span: sp};
154154
}
155155

156-
fn get_mac_arg(cx: ext_ctxt, sp: span, arg: ast::mac_arg) -> @ast::expr {
157-
alt (arg) {
158-
some(expr) {expr}
159-
none {cx.span_fatal(sp, "missing macro args")}
156+
fn get_mac_args_no_max(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
157+
min: uint, name: str) -> [@ast::expr] {
158+
ret get_mac_args(cx, sp, arg, min, none, name);
159+
}
160+
161+
fn get_mac_args(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
162+
min: uint, max: option<uint>, name: str) -> [@ast::expr] {
163+
alt arg {
164+
some(expr) {
165+
alt expr.node {
166+
ast::expr_vec(elts, _) {
167+
let elts_len = vec::len(elts);
168+
alt max {
169+
some(max) if ! (min <= elts_len && elts_len <= max) {
170+
cx.span_fatal(sp,
171+
#fmt["#%s takes between %u and %u arguments.",
172+
name, min, max]);
173+
}
174+
none if ! (min <= elts_len) {
175+
cx.span_fatal(sp, #fmt["#%s needs at least %u arguments.",
176+
name, min]);
177+
}
178+
_ { ret elts; /* we're good */}
179+
}
180+
}
181+
_ {
182+
cx.span_fatal(sp, #fmt["#%s: malformed invocation", name])
183+
}
184+
}
185+
}
186+
none {cx.span_fatal(sp, #fmt["#%s: missing arguments", name])}
160187
}
161188
}
162189

src/librustsyntax/ext/concat_idents.rs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,7 @@ import base::*;
22

33
fn expand_syntax_ext(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg,
44
_body: ast::mac_body) -> @ast::expr {
5-
let arg = get_mac_arg(cx,sp,arg);
6-
let args: [@ast::expr] =
7-
alt arg.node {
8-
ast::expr_vec(elts, _) { elts }
9-
_ {
10-
cx.span_fatal(sp, "#concat_idents requires a vector argument .")
11-
}
12-
};
5+
let args = get_mac_args_no_max(cx,sp,arg,1u,"concat_idents");
136
let mut res: ast::ident = "";
147
for args.each {|e|
158
res += expr_to_ident(cx, e, "expected an ident");

src/librustsyntax/ext/env.rs

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,8 @@ export expand_syntax_ext;
99

1010
fn expand_syntax_ext(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg,
1111
_body: ast::mac_body) -> @ast::expr {
12-
let arg = get_mac_arg(cx,sp,arg);
13-
let args: [@ast::expr] =
14-
alt arg.node {
15-
ast::expr_vec(elts, _) { elts }
16-
_ {
17-
cx.span_fatal(sp, "#env requires arguments of the form `[...]`.")
18-
}
19-
};
20-
if vec::len::<@ast::expr>(args) != 1u {
21-
cx.span_fatal(sp, "malformed #env call");
22-
}
12+
let args = get_mac_args(cx, sp, arg, 1u, option::some(1u), "env");
13+
2314
// FIXME: if this was more thorough it would manufacture an
2415
// option<str> rather than just an maybe-empty string. (Issue #2248)
2516

src/librustsyntax/ext/fmt.rs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,7 @@ export expand_syntax_ext;
1313

1414
fn expand_syntax_ext(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
1515
_body: ast::mac_body) -> @ast::expr {
16-
let arg = get_mac_arg(cx,sp,arg);
17-
let args: [@ast::expr] =
18-
alt arg.node {
19-
ast::expr_vec(elts, _) { elts }
20-
_ {
21-
cx.span_fatal(sp, "#fmt requires arguments of the form `[...]`.")
22-
}
23-
};
24-
if vec::len::<@ast::expr>(args) == 0u {
25-
cx.span_fatal(sp, "#fmt requires a format string");
26-
}
16+
let args = get_mac_args_no_max(cx, sp, arg, 1u, "fmt");
2717
let fmt =
2818
expr_to_str(cx, args[0],
2919
"first argument to #fmt must be a string literal.");

src/librustsyntax/ext/ident_to_str.rs

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,11 @@
11
import base::*;
2+
import option;
23

34
fn expand_syntax_ext(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg,
45
_body: ast::mac_body) -> @ast::expr {
5-
let arg = get_mac_arg(cx,sp,arg);
6-
let args: [@ast::expr] =
7-
alt arg.node {
8-
ast::expr_vec(elts, _) { elts }
9-
_ {
10-
cx.span_fatal(sp, "#ident_to_str requires a vector argument .")
11-
}
12-
};
13-
if vec::len::<@ast::expr>(args) != 1u {
14-
cx.span_fatal(sp, "malformed #ident_to_str call");
15-
}
6+
let args = get_mac_args(cx,sp,arg,1u,option::some(1u),"ident_to_str");
167

178
ret make_new_lit(cx, sp,
189
ast::lit_str(expr_to_ident(cx, args[0u],
1910
"expected an ident")));
20-
2111
}

src/librustsyntax/ext/include.rs

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,8 @@ export str;
1414
mod str {
1515
fn expand_syntax_ext(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg,
1616
_body: ast::mac_body) -> @ast::expr {
17-
let arg = get_mac_arg(cx,sp,arg);
18-
let args: [@ast::expr] =
19-
alt arg.node {
20-
ast::expr_vec(elts, _) { elts }
21-
_ {
22-
cx.span_fatal(sp, "#include_str requires arguments \
23-
of the form `[...]`.")
24-
}
25-
};
26-
if vec::len::<@ast::expr>(args) != 1u {
27-
cx.span_fatal(sp, "malformed #include_str call");
28-
}
17+
let args = get_mac_args(cx,sp,arg,1u,option::some(1u),"include_str");
18+
2919
let mut path = expr_to_str(cx, args[0], "#include_str requires \
3020
a string");
3121

src/librustsyntax/ext/log_syntax.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@ import io::writer_util;
33

44
fn expand_syntax_ext(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg,
55
_body: ast::mac_body) -> @ast::expr {
6-
let arg = get_mac_arg(cx,sp,arg);
6+
let args = get_mac_args_no_max(cx,sp,arg,0u,"log_syntax");
77
cx.print_backtrace();
8-
io::stdout().write_line(print::pprust::expr_to_str(arg));
8+
io::stdout().write_line(
9+
str::connect(vec::map(args,
10+
{|&&ex| print::pprust::expr_to_str(ex)}), ", ")
11+
);
912

1013
//trivial expression
1114
ret @{id: cx.next_id(), node: ast::expr_rec([], option::none), span: sp};

src/librustsyntax/ext/simplext.rs

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -668,15 +668,7 @@ fn p_t_s_r_actual_vector(cx: ext_ctxt, elts: [@expr], _repeat_after: bool,
668668

669669
fn add_new_extension(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
670670
_body: ast::mac_body) -> base::macro_def {
671-
let arg = get_mac_arg(cx,sp,arg);
672-
let args: [@ast::expr] =
673-
alt arg.node {
674-
ast::expr_vec(elts, _) { elts }
675-
_ {
676-
cx.span_fatal(sp,
677-
"#macro requires arguments of the form `[...]`.")
678-
}
679-
};
671+
let args = get_mac_args_no_max(cx, sp, arg, 0u, "macro");
680672

681673
let mut macro_name: option<str> = none;
682674
let mut clauses: [@clause] = [];
@@ -712,9 +704,13 @@ fn add_new_extension(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
712704
"macro name must not be a path");
713705
}
714706
}
707+
let arg = alt invoc_arg {
708+
some(arg) { arg }
709+
none { cx.span_fatal(mac.span,
710+
"macro must have arguments")}
711+
};
715712
clauses +=
716-
[@{params: pattern_to_selectors
717-
(cx, get_mac_arg(cx,mac.span,invoc_arg)),
713+
[@{params: pattern_to_selectors(cx, arg),
718714
body: elts[1u]}];
719715

720716
// FIXME: check duplicates (or just simplify
@@ -746,16 +742,18 @@ fn add_new_extension(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
746742
alt macro_name {
747743
some(id) { id }
748744
none {
749-
cx.span_fatal(sp,
750-
"macro definition must have " +
751-
"at least one clause")
745+
cx.span_fatal(sp, "macro definition must have " +
746+
"at least one clause")
752747
}
753748
},
754-
ext: normal({expander: ext, span: some(arg.span)})};
749+
ext: normal({expander: ext, span: some(option::get(arg).span)})};
755750

756751
fn generic_extension(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
757752
_body: ast::mac_body, clauses: [@clause]) -> @expr {
758-
let arg = get_mac_arg(cx,sp,arg);
753+
let arg = alt arg {
754+
some(arg) { arg }
755+
none { cx.span_fatal(sp, "macro must have arguments")}
756+
};
759757
for clauses.each {|c|
760758
alt use_selectors_to_bind(c.params, arg) {
761759
some(bindings) { ret transcribe(cx, bindings, c.body); }
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
// error-pattern:malformed #env call
1+
// error-pattern:#env takes between 1 and 1 arguments
22

33
fn main() { #env[]; }
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
// error-pattern:malformed #env call
1+
// error-pattern:#env takes between 1 and 1 arguments
22

33
fn main() { #env["one", "two"]; }
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
// error-pattern:format string
1+
// error-pattern:#fmt needs at least 1 arguments
22

33
fn main() { #fmt[]; }

0 commit comments

Comments
 (0)