about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPaul Stansifer <paul.stansifer@gmail.com>2012-05-14 15:32:32 -0700
committerPaul Stansifer <paul.stansifer@gmail.com>2012-05-18 10:05:24 -0700
commit9fe547d3a795f59217c0093c82aa5a5b86c65f72 (patch)
treeed839c2f3777782b4f6b2c2e91e78a393b82e88d
parentcdcce3ed5d0e2944e71a1660b52535c6c43e2ef2 (diff)
downloadrust-9fe547d3a795f59217c0093c82aa5a5b86c65f72.tar.gz
rust-9fe547d3a795f59217c0093c82aa5a5b86c65f72.zip
Make extracting syntax extension arguments easier.
-rw-r--r--src/libcore/path.rs2
-rw-r--r--src/librustsyntax/ext/base.rs35
-rw-r--r--src/librustsyntax/ext/concat_idents.rs9
-rw-r--r--src/librustsyntax/ext/env.rs13
-rw-r--r--src/librustsyntax/ext/fmt.rs12
-rw-r--r--src/librustsyntax/ext/ident_to_str.rs14
-rw-r--r--src/librustsyntax/ext/include.rs14
-rw-r--r--src/librustsyntax/ext/log_syntax.rs7
-rw-r--r--src/librustsyntax/ext/simplext.rs30
-rw-r--r--src/test/compile-fail/extenv-no-args.rs2
-rw-r--r--src/test/compile-fail/extenv-too-many-args.rs2
-rw-r--r--src/test/compile-fail/extfmt-no-args.rs2
12 files changed, 62 insertions, 80 deletions
diff --git a/src/libcore/path.rs b/src/libcore/path.rs
index 75ca4cb035e..a771f2b9928 100644
--- a/src/libcore/path.rs
+++ b/src/libcore/path.rs
@@ -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
diff --git a/src/librustsyntax/ext/base.rs b/src/librustsyntax/ext/base.rs
index 170ba112e31..92b6acba5b0 100644
--- a/src/librustsyntax/ext/base.rs
+++ b/src/librustsyntax/ext/base.rs
@@ -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])}
     }
 }
 
diff --git a/src/librustsyntax/ext/concat_idents.rs b/src/librustsyntax/ext/concat_idents.rs
index 409a38b378d..278321ec8bc 100644
--- a/src/librustsyntax/ext/concat_idents.rs
+++ b/src/librustsyntax/ext/concat_idents.rs
@@ -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");
diff --git a/src/librustsyntax/ext/env.rs b/src/librustsyntax/ext/env.rs
index 616c816a66d..6a4d937f083 100644
--- a/src/librustsyntax/ext/env.rs
+++ b/src/librustsyntax/ext/env.rs
@@ -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)
 
diff --git a/src/librustsyntax/ext/fmt.rs b/src/librustsyntax/ext/fmt.rs
index 1ab340c9c0e..aceeed4b9e8 100644
--- a/src/librustsyntax/ext/fmt.rs
+++ b/src/librustsyntax/ext/fmt.rs
@@ -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.");
diff --git a/src/librustsyntax/ext/ident_to_str.rs b/src/librustsyntax/ext/ident_to_str.rs
index cb7c604a489..7dfb70f1520 100644
--- a/src/librustsyntax/ext/ident_to_str.rs
+++ b/src/librustsyntax/ext/ident_to_str.rs
@@ -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")));
-
 }
diff --git a/src/librustsyntax/ext/include.rs b/src/librustsyntax/ext/include.rs
index a31d2835e8a..e9391adb222 100644
--- a/src/librustsyntax/ext/include.rs
+++ b/src/librustsyntax/ext/include.rs
@@ -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");
 
diff --git a/src/librustsyntax/ext/log_syntax.rs b/src/librustsyntax/ext/log_syntax.rs
index 4ae212047f3..5ccbb143b97 100644
--- a/src/librustsyntax/ext/log_syntax.rs
+++ b/src/librustsyntax/ext/log_syntax.rs
@@ -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};
diff --git a/src/librustsyntax/ext/simplext.rs b/src/librustsyntax/ext/simplext.rs
index 81eaa193f95..792618f2bde 100644
--- a/src/librustsyntax/ext/simplext.rs
+++ b/src/librustsyntax/ext/simplext.rs
@@ -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 " +
-                                   "at least one clause")
+                 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); }
diff --git a/src/test/compile-fail/extenv-no-args.rs b/src/test/compile-fail/extenv-no-args.rs
index ec73f0a7a45..44611424079 100644
--- a/src/test/compile-fail/extenv-no-args.rs
+++ b/src/test/compile-fail/extenv-no-args.rs
@@ -1,3 +1,3 @@
-// error-pattern:malformed #env call
+// error-pattern:#env takes between 1 and 1 arguments
 
 fn main() { #env[]; }
diff --git a/src/test/compile-fail/extenv-too-many-args.rs b/src/test/compile-fail/extenv-too-many-args.rs
index 945546fd6cb..6e70b67f9c4 100644
--- a/src/test/compile-fail/extenv-too-many-args.rs
+++ b/src/test/compile-fail/extenv-too-many-args.rs
@@ -1,3 +1,3 @@
-// error-pattern:malformed #env call
+// error-pattern:#env takes between 1 and 1 arguments
 
 fn main() { #env["one", "two"]; }
diff --git a/src/test/compile-fail/extfmt-no-args.rs b/src/test/compile-fail/extfmt-no-args.rs
index 7c13ef99dc5..f88d74dd166 100644
--- a/src/test/compile-fail/extfmt-no-args.rs
+++ b/src/test/compile-fail/extfmt-no-args.rs
@@ -1,3 +1,3 @@
-// error-pattern:format string
+// error-pattern:#fmt needs at least 1 arguments
 
 fn main() { #fmt[]; }