about summary refs log tree commit diff
path: root/src/comp
diff options
context:
space:
mode:
authorPaul Stansifer <paul.stansifer@gmail.com>2011-06-02 18:58:23 -0700
committerGraydon Hoare <graydon@mozilla.com>2011-06-03 18:47:11 -0700
commit79fcd51b4659aabb8cf92bcc69a20207dbd53492 (patch)
treef05cd2b936664691a4ca25e39bb123d9aeb04e6d /src/comp
parentcfc75695a57de94de618b1f5f7c163d213fbc36b (diff)
downloadrust-79fcd51b4659aabb8cf92bcc69a20207dbd53492.tar.gz
rust-79fcd51b4659aabb8cf92bcc69a20207dbd53492.zip
Make the macro system more modular.
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/front/extenv.rs4
-rw-r--r--src/comp/front/extfmt.rs35
-rw-r--r--src/comp/front/parser.rs95
3 files changed, 59 insertions, 75 deletions
diff --git a/src/comp/front/extenv.rs b/src/comp/front/extenv.rs
index 858f9f9f568..ecceabd9c07 100644
--- a/src/comp/front/extenv.rs
+++ b/src/comp/front/extenv.rs
@@ -14,9 +14,9 @@ import std::generic_os;
 export expand_syntax_ext;
 
 // FIXME: Need to thread parser through here to handle errors correctly
-fn expand_syntax_ext(parser::parser p,
+fn expand_syntax_ext(&parser::parser p,
                      common::span sp,
-                     vec[@ast::expr] args,
+                     &vec[@ast::expr] args,
                      option::t[str] body) -> @ast::expr {
 
     if (vec::len[@ast::expr](args) != 1u) {
diff --git a/src/comp/front/extfmt.rs b/src/comp/front/extfmt.rs
index f6ad1d04a39..672de538510 100644
--- a/src/comp/front/extfmt.rs
+++ b/src/comp/front/extfmt.rs
@@ -13,41 +13,12 @@ import std::option;
 import std::option::none;
 import std::option::some;
 
-import std::extfmt::ct::signedness;
-import std::extfmt::ct::signed;
-import std::extfmt::ct::unsigned;
-import std::extfmt::ct::caseness;
-import std::extfmt::ct::case_upper;
-import std::extfmt::ct::case_lower;
-import std::extfmt::ct::ty;
-import std::extfmt::ct::ty_bool;
-import std::extfmt::ct::ty_str;
-import std::extfmt::ct::ty_char;
-import std::extfmt::ct::ty_int;
-import std::extfmt::ct::ty_bits;
-import std::extfmt::ct::ty_hex;
-import std::extfmt::ct::ty_octal;
-import std::extfmt::ct::flag;
-import std::extfmt::ct::flag_left_justify;
-import std::extfmt::ct::flag_left_zero_pad;
-import std::extfmt::ct::flag_space_for_sign;
-import std::extfmt::ct::flag_sign_always;
-import std::extfmt::ct::flag_alternate;
-import std::extfmt::ct::count;
-import std::extfmt::ct::count_is;
-import std::extfmt::ct::count_is_param;
-import std::extfmt::ct::count_is_next_param;
-import std::extfmt::ct::count_implied;
-import std::extfmt::ct::conv;
-import std::extfmt::ct::piece;
-import std::extfmt::ct::piece_string;
-import std::extfmt::ct::piece_conv;
-import std::extfmt::ct::parse_fmt_string;
+import std::extfmt::ct::*;
 
 export expand_syntax_ext;
 
-fn expand_syntax_ext(parser p,
-                     vec[@ast::expr] args,
+fn expand_syntax_ext(&parser p, common::span sp, 
+                     &vec[@ast::expr] args,
                      option::t[str] body) -> @ast::expr {
 
     if (vec::len[@ast::expr](args) == 0u) {
diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs
index dbfdea89c21..bafde70c9d7 100644
--- a/src/comp/front/parser.rs
+++ b/src/comp/front/parser.rs
@@ -27,32 +27,41 @@ tag file_type {
 
 type ty_or_bang = util::common::ty_or_bang[@ast::ty];
 
+// Temporary: to introduce a tag in order to make a recursive type work
+tag xmacro {
+    x(macro);
+}
+
 state type parser =
     state obj {
-          fn peek() -> token::token;
-          fn bump();
-          fn err(str s) -> !;
-          fn restrict(restriction r);
-          fn get_restriction() -> restriction;
-          fn get_file_type() -> file_type;
-          fn get_env() -> eval::env;
-          fn get_session() -> session::session;
-          fn get_span() -> common::span;
-          fn get_lo_pos() -> uint;
-          fn get_hi_pos() -> uint;
-          fn get_last_lo_pos() -> uint;
-          fn next_def_id() -> ast::def_id;
-          fn set_def(ast::def_num);
-          fn get_prec_table() -> vec[op_spec];
-          fn get_str(token::str_num) -> str;
-          fn get_reader() -> lexer::reader;
-          fn get_filemap() -> codemap::filemap;
-          fn get_bad_expr_words() -> std::map::hashmap[str, ()];
-          fn get_chpos() -> uint;
-          fn get_ann() -> ast::ann;
-          fn next_ann_num() -> uint;
+        fn peek() -> token::token;
+        fn bump();
+        fn err(str s) -> !;
+        fn restrict(restriction r);
+        fn get_restriction() -> restriction;
+        fn get_file_type() -> file_type;
+        fn get_env() -> eval::env;
+        fn get_session() -> session::session;
+        fn get_span() -> common::span;
+        fn get_lo_pos() -> uint;
+        fn get_hi_pos() -> uint;
+        fn get_last_lo_pos() -> uint;
+        fn next_def_id() -> ast::def_id;
+        fn set_def(ast::def_num);
+        fn get_prec_table() -> vec[op_spec];
+        fn get_str(token::str_num) -> str;
+        fn get_reader() -> lexer::reader;
+        fn get_filemap() -> codemap::filemap;
+        fn get_bad_expr_words() -> std::map::hashmap[str, ()];
+        fn get_macros() -> std::map::hashmap[str, xmacro];
+        fn get_chpos() -> uint;
+        fn get_ann() -> ast::ann;
+        fn next_ann_num() -> uint;
     };
 
+type macro = fn(&parser, common::span, &vec[@ast::expr], option::t[str]) 
+    -> @ast::expr;
+
 fn new_parser(session::session sess,
                      eval::env env,
                      ast::def_id initial_def,
@@ -70,7 +79,8 @@ fn new_parser(session::session sess,
                            lexer::reader rdr,
                            vec[op_spec] precs,
                            mutable uint next_ann_var,
-                           std::map::hashmap[str, ()] bad_words)
+                           std::map::hashmap[str, ()] bad_words,
+                           std::map::hashmap[str, xmacro] macros)
         {
             fn peek() -> token::token {
                 ret tok;
@@ -143,6 +153,10 @@ fn new_parser(session::session sess,
                 ret bad_words;
             }
 
+            fn get_macros() -> std::map::hashmap[str, xmacro] {
+                ret macros;
+            }
+
             fn get_chpos() -> uint {ret rdr.get_chpos();}
 
             fn get_ann() -> ast::ann {
@@ -169,7 +183,7 @@ fn new_parser(session::session sess,
     ret stdio_parser(sess, env, ftype, lexer::next_token(rdr),
                      npos, npos, npos, initial_def._1, UNRESTRICTED,
                      initial_def._0, rdr, prec_table(), next_ann,
-                     bad_expr_word_table());
+                     bad_expr_word_table(), macro_table());
 }
 
 // These are the words that shouldn't be allowed as value identifiers,
@@ -213,6 +227,13 @@ fn bad_expr_word_table() -> std::map::hashmap[str, ()] {
     ret words;
 }
 
+fn macro_table() -> std::map::hashmap[str, xmacro] {
+    auto macros = new_str_hash[xmacro]();
+    macros.insert("fmt", x(extfmt::expand_syntax_ext));
+    macros.insert("env", x(extenv::expand_syntax_ext));
+    ret macros;
+}
+
 fn unexpected(&parser p, token::token t) -> ! {
     let str s = "unexpected token: ";
     s += token::to_str(p.get_reader(), t);
@@ -1037,23 +1058,15 @@ fn expand_syntax_ext(&parser p, common::span sp,
 
     assert (vec::len[ast::ident](path.node.idents) > 0u);
     auto extname = path.node.idents.(0);
-    if (str::eq(extname, "fmt")) {
-        auto expanded = extfmt::expand_syntax_ext(p, args, body);
-        auto newexpr = ast::expr_ext(path, args, body,
-                                    expanded,
-                                    p.get_ann());
-
-        ret newexpr;
-    } else if (str::eq(extname, "env")) {
-        auto expanded = extenv::expand_syntax_ext(p, sp, args, body);
-        auto newexpr = ast::expr_ext(path, args, body,
-                                    expanded,
-                                    p.get_ann());
-
-        ret newexpr;
-    } else {
-        p.err("unknown syntax extension");
-        fail;
+
+    alt (p.get_macros().find(extname)) {
+        case (none[xmacro]) {
+            p.err("unknown macro: '" + extname + "'");
+        }
+        case (some[xmacro](x(?ext))) {
+            ret ast::expr_ext(path, args, body, ext(p, sp, args, body), 
+                              p.get_ann());
+        }
     }
 }