Make extracting syntax extension arguments easier.
This commit is contained in:
parent
cdcce3ed5d
commit
9fe547d3a7
12 changed files with 62 additions and 80 deletions
|
@ -136,7 +136,7 @@ fn connect_many(paths: [path]) -> path {
|
|||
}
|
||||
|
||||
#[doc = "
|
||||
Split a path into it's individual components
|
||||
Split a path into its individual components
|
||||
|
||||
Splits a given path by path separators and returns a vector containing
|
||||
each piece of the path. On Windows, if the path is absolute then
|
||||
|
|
|
@ -153,10 +153,37 @@ fn make_new_lit(cx: ext_ctxt, sp: codemap::span, lit: ast::lit_) ->
|
|||
ret @{id: cx.next_id(), node: ast::expr_lit(sp_lit), span: sp};
|
||||
}
|
||||
|
||||
fn get_mac_arg(cx: ext_ctxt, sp: span, arg: ast::mac_arg) -> @ast::expr {
|
||||
alt (arg) {
|
||||
some(expr) {expr}
|
||||
none {cx.span_fatal(sp, "missing macro args")}
|
||||
fn get_mac_args_no_max(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
|
||||
min: uint, name: str) -> [@ast::expr] {
|
||||
ret get_mac_args(cx, sp, arg, min, none, name);
|
||||
}
|
||||
|
||||
fn get_mac_args(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
|
||||
min: uint, max: option<uint>, name: str) -> [@ast::expr] {
|
||||
alt arg {
|
||||
some(expr) {
|
||||
alt expr.node {
|
||||
ast::expr_vec(elts, _) {
|
||||
let elts_len = vec::len(elts);
|
||||
alt max {
|
||||
some(max) if ! (min <= elts_len && elts_len <= max) {
|
||||
cx.span_fatal(sp,
|
||||
#fmt["#%s takes between %u and %u arguments.",
|
||||
name, min, max]);
|
||||
}
|
||||
none if ! (min <= elts_len) {
|
||||
cx.span_fatal(sp, #fmt["#%s needs at least %u arguments.",
|
||||
name, min]);
|
||||
}
|
||||
_ { ret elts; /* we're good */}
|
||||
}
|
||||
}
|
||||
_ {
|
||||
cx.span_fatal(sp, #fmt["#%s: malformed invocation", name])
|
||||
}
|
||||
}
|
||||
}
|
||||
none {cx.span_fatal(sp, #fmt["#%s: missing arguments", name])}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,14 +2,7 @@ import base::*;
|
|||
|
||||
fn expand_syntax_ext(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg,
|
||||
_body: ast::mac_body) -> @ast::expr {
|
||||
let arg = get_mac_arg(cx,sp,arg);
|
||||
let args: [@ast::expr] =
|
||||
alt arg.node {
|
||||
ast::expr_vec(elts, _) { elts }
|
||||
_ {
|
||||
cx.span_fatal(sp, "#concat_idents requires a vector argument .")
|
||||
}
|
||||
};
|
||||
let args = get_mac_args_no_max(cx,sp,arg,1u,"concat_idents");
|
||||
let mut res: ast::ident = "";
|
||||
for args.each {|e|
|
||||
res += expr_to_ident(cx, e, "expected an ident");
|
||||
|
|
|
@ -9,17 +9,8 @@ export expand_syntax_ext;
|
|||
|
||||
fn expand_syntax_ext(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg,
|
||||
_body: ast::mac_body) -> @ast::expr {
|
||||
let arg = get_mac_arg(cx,sp,arg);
|
||||
let args: [@ast::expr] =
|
||||
alt arg.node {
|
||||
ast::expr_vec(elts, _) { elts }
|
||||
_ {
|
||||
cx.span_fatal(sp, "#env requires arguments of the form `[...]`.")
|
||||
}
|
||||
};
|
||||
if vec::len::<@ast::expr>(args) != 1u {
|
||||
cx.span_fatal(sp, "malformed #env call");
|
||||
}
|
||||
let args = get_mac_args(cx, sp, arg, 1u, option::some(1u), "env");
|
||||
|
||||
// FIXME: if this was more thorough it would manufacture an
|
||||
// option<str> rather than just an maybe-empty string. (Issue #2248)
|
||||
|
||||
|
|
|
@ -13,17 +13,7 @@ export expand_syntax_ext;
|
|||
|
||||
fn expand_syntax_ext(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
|
||||
_body: ast::mac_body) -> @ast::expr {
|
||||
let arg = get_mac_arg(cx,sp,arg);
|
||||
let args: [@ast::expr] =
|
||||
alt arg.node {
|
||||
ast::expr_vec(elts, _) { elts }
|
||||
_ {
|
||||
cx.span_fatal(sp, "#fmt requires arguments of the form `[...]`.")
|
||||
}
|
||||
};
|
||||
if vec::len::<@ast::expr>(args) == 0u {
|
||||
cx.span_fatal(sp, "#fmt requires a format string");
|
||||
}
|
||||
let args = get_mac_args_no_max(cx, sp, arg, 1u, "fmt");
|
||||
let fmt =
|
||||
expr_to_str(cx, args[0],
|
||||
"first argument to #fmt must be a string literal.");
|
||||
|
|
|
@ -1,21 +1,11 @@
|
|||
import base::*;
|
||||
import option;
|
||||
|
||||
fn expand_syntax_ext(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg,
|
||||
_body: ast::mac_body) -> @ast::expr {
|
||||
let arg = get_mac_arg(cx,sp,arg);
|
||||
let args: [@ast::expr] =
|
||||
alt arg.node {
|
||||
ast::expr_vec(elts, _) { elts }
|
||||
_ {
|
||||
cx.span_fatal(sp, "#ident_to_str requires a vector argument .")
|
||||
}
|
||||
};
|
||||
if vec::len::<@ast::expr>(args) != 1u {
|
||||
cx.span_fatal(sp, "malformed #ident_to_str call");
|
||||
}
|
||||
let args = get_mac_args(cx,sp,arg,1u,option::some(1u),"ident_to_str");
|
||||
|
||||
ret make_new_lit(cx, sp,
|
||||
ast::lit_str(expr_to_ident(cx, args[0u],
|
||||
"expected an ident")));
|
||||
|
||||
}
|
||||
|
|
|
@ -14,18 +14,8 @@ export str;
|
|||
mod str {
|
||||
fn expand_syntax_ext(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg,
|
||||
_body: ast::mac_body) -> @ast::expr {
|
||||
let arg = get_mac_arg(cx,sp,arg);
|
||||
let args: [@ast::expr] =
|
||||
alt arg.node {
|
||||
ast::expr_vec(elts, _) { elts }
|
||||
_ {
|
||||
cx.span_fatal(sp, "#include_str requires arguments \
|
||||
of the form `[...]`.")
|
||||
}
|
||||
};
|
||||
if vec::len::<@ast::expr>(args) != 1u {
|
||||
cx.span_fatal(sp, "malformed #include_str call");
|
||||
}
|
||||
let args = get_mac_args(cx,sp,arg,1u,option::some(1u),"include_str");
|
||||
|
||||
let mut path = expr_to_str(cx, args[0], "#include_str requires \
|
||||
a string");
|
||||
|
||||
|
|
|
@ -3,9 +3,12 @@ import io::writer_util;
|
|||
|
||||
fn expand_syntax_ext(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg,
|
||||
_body: ast::mac_body) -> @ast::expr {
|
||||
let arg = get_mac_arg(cx,sp,arg);
|
||||
let args = get_mac_args_no_max(cx,sp,arg,0u,"log_syntax");
|
||||
cx.print_backtrace();
|
||||
io::stdout().write_line(print::pprust::expr_to_str(arg));
|
||||
io::stdout().write_line(
|
||||
str::connect(vec::map(args,
|
||||
{|&&ex| print::pprust::expr_to_str(ex)}), ", ")
|
||||
);
|
||||
|
||||
//trivial expression
|
||||
ret @{id: cx.next_id(), node: ast::expr_rec([], option::none), span: sp};
|
||||
|
|
|
@ -668,15 +668,7 @@ fn p_t_s_r_actual_vector(cx: ext_ctxt, elts: [@expr], _repeat_after: bool,
|
|||
|
||||
fn add_new_extension(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
|
||||
_body: ast::mac_body) -> base::macro_def {
|
||||
let arg = get_mac_arg(cx,sp,arg);
|
||||
let args: [@ast::expr] =
|
||||
alt arg.node {
|
||||
ast::expr_vec(elts, _) { elts }
|
||||
_ {
|
||||
cx.span_fatal(sp,
|
||||
"#macro requires arguments of the form `[...]`.")
|
||||
}
|
||||
};
|
||||
let args = get_mac_args_no_max(cx, sp, arg, 0u, "macro");
|
||||
|
||||
let mut macro_name: option<str> = none;
|
||||
let mut clauses: [@clause] = [];
|
||||
|
@ -712,9 +704,13 @@ fn add_new_extension(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
|
|||
"macro name must not be a path");
|
||||
}
|
||||
}
|
||||
let arg = alt invoc_arg {
|
||||
some(arg) { arg }
|
||||
none { cx.span_fatal(mac.span,
|
||||
"macro must have arguments")}
|
||||
};
|
||||
clauses +=
|
||||
[@{params: pattern_to_selectors
|
||||
(cx, get_mac_arg(cx,mac.span,invoc_arg)),
|
||||
[@{params: pattern_to_selectors(cx, arg),
|
||||
body: elts[1u]}];
|
||||
|
||||
// FIXME: check duplicates (or just simplify
|
||||
|
@ -746,16 +742,18 @@ fn add_new_extension(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
|
|||
alt macro_name {
|
||||
some(id) { id }
|
||||
none {
|
||||
cx.span_fatal(sp,
|
||||
"macro definition must have " +
|
||||
cx.span_fatal(sp, "macro definition must have " +
|
||||
"at least one clause")
|
||||
}
|
||||
},
|
||||
ext: normal({expander: ext, span: some(arg.span)})};
|
||||
ext: normal({expander: ext, span: some(option::get(arg).span)})};
|
||||
|
||||
fn generic_extension(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
|
||||
_body: ast::mac_body, clauses: [@clause]) -> @expr {
|
||||
let arg = get_mac_arg(cx,sp,arg);
|
||||
let arg = alt arg {
|
||||
some(arg) { arg }
|
||||
none { cx.span_fatal(sp, "macro must have arguments")}
|
||||
};
|
||||
for clauses.each {|c|
|
||||
alt use_selectors_to_bind(c.params, arg) {
|
||||
some(bindings) { ret transcribe(cx, bindings, c.body); }
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
// error-pattern:malformed #env call
|
||||
// error-pattern:#env takes between 1 and 1 arguments
|
||||
|
||||
fn main() { #env[]; }
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
// error-pattern:malformed #env call
|
||||
// error-pattern:#env takes between 1 and 1 arguments
|
||||
|
||||
fn main() { #env["one", "two"]; }
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
// error-pattern:format string
|
||||
// error-pattern:#fmt needs at least 1 arguments
|
||||
|
||||
fn main() { #fmt[]; }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue