From af46f3ed0d2b65df451ff54b0a22263b74f11e46 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sat, 4 Jun 2011 15:41:45 -0400 Subject: [PATCH] rustc: Introduce ext module. Move some things from parser to ext. Introduce an ext_ctxt record to provide a span_err method for use while expanding syntax extensions. Hopefully it will be useful for other things. --- src/comp/front/ext.rs | 49 ++++++++++++++++++++++++++++++++++++++++ src/comp/front/extenv.rs | 5 +++- src/comp/front/extfmt.rs | 5 +++- src/comp/front/parser.rs | 32 ++++++++------------------ src/comp/rustc.rc | 1 + 5 files changed, 68 insertions(+), 24 deletions(-) create mode 100644 src/comp/front/ext.rs diff --git a/src/comp/front/ext.rs b/src/comp/front/ext.rs new file mode 100644 index 000000000000..428ac1bf295e --- /dev/null +++ b/src/comp/front/ext.rs @@ -0,0 +1,49 @@ +import std::option; +import std::map::hashmap; + +import driver::session::session; +import util::common::span; +import util::common::new_str_hash; + +type syntax_expander = fn(&ext_ctxt, &parser::parser, span, + &vec[@ast::expr], + option::t[str]) -> @ast::expr; + +// Temporary: to introduce a tag in order to make a recursive type work +tag syntax_extension { + x(syntax_expander); +} + +// A temporary hard-coded map of methods for expanding syntax extension +// AST nodes into full ASTs +fn syntax_expander_table() -> hashmap[str, syntax_extension] { + auto syntax_expanders = new_str_hash[syntax_extension](); + syntax_expanders.insert("fmt", x(extfmt::expand_syntax_ext)); + syntax_expanders.insert("env", x(extenv::expand_syntax_ext)); + ret syntax_expanders; +} + +type span_err_fn = fn (span sp, str msg) -> !; + +// Provides a limited set of services necessary for syntax extensions +// to do their thing +type ext_ctxt = rec(span_err_fn span_err); + +fn mk_ctxt(session sess) -> ext_ctxt { + fn ext_span_err_(session sess, span sp, str err) -> ! { + sess.span_err(sp, err); + } + auto ext_span_err = bind ext_span_err_(sess, _, _); + ret rec(span_err = ext_span_err); +} + +// +// Local Variables: +// mode: rust +// fill-column: 78; +// indent-tabs-mode: nil +// c-basic-offset: 4 +// buffer-file-coding-system: utf-8-unix +// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'"; +// End: +// diff --git a/src/comp/front/extenv.rs b/src/comp/front/extenv.rs index ecceabd9c07d..fc7d889d8f6f 100644 --- a/src/comp/front/extenv.rs +++ b/src/comp/front/extenv.rs @@ -11,10 +11,13 @@ import std::vec; import std::option; import std::generic_os; +import ext::*; + 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(&ext_ctxt cx, + &parser::parser p, common::span sp, &vec[@ast::expr] args, option::t[str] body) -> @ast::expr { diff --git a/src/comp/front/extfmt.rs b/src/comp/front/extfmt.rs index 672de538510f..a2fdd6742aec 100644 --- a/src/comp/front/extfmt.rs +++ b/src/comp/front/extfmt.rs @@ -15,9 +15,12 @@ import std::option::some; import std::extfmt::ct::*; +import ext::*; + export expand_syntax_ext; -fn expand_syntax_ext(&parser p, common::span sp, +fn expand_syntax_ext(&ext_ctxt cx, + &parser p, common::span sp, &vec[@ast::expr] args, option::t[str] body) -> @ast::expr { diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs index eb4742939d3d..a07838d03e7c 100644 --- a/src/comp/front/parser.rs +++ b/src/comp/front/parser.rs @@ -27,11 +27,6 @@ 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 syntax_extension { - x(syntax_expander); -} - state type parser = state obj { fn peek() -> token::token; @@ -53,15 +48,12 @@ state type parser = fn get_reader() -> lexer::reader; fn get_filemap() -> codemap::filemap; fn get_bad_expr_words() -> hashmap[str, ()]; - fn get_syntax_expanders() -> hashmap[str, syntax_extension]; + fn get_syntax_expanders() -> hashmap[str, ext::syntax_extension]; fn get_chpos() -> uint; fn get_ann() -> ast::ann; fn next_ann_num() -> uint; }; -type syntax_expander = 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, @@ -80,7 +72,8 @@ fn new_parser(session::session sess, vec[op_spec] precs, mutable uint next_ann_var, hashmap[str, ()] bad_words, - hashmap[str, syntax_extension] syntax_expanders) + hashmap[str, ext::syntax_extension] + syntax_expanders) { fn peek() -> token::token { ret tok; @@ -153,7 +146,7 @@ fn new_parser(session::session sess, ret bad_words; } - fn get_syntax_expanders() -> hashmap[str, syntax_extension] { + fn get_syntax_expanders() -> hashmap[str, ext::syntax_extension] { ret syntax_expanders; } @@ -183,7 +176,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(), syntax_expander_table()); + bad_expr_word_table(), ext::syntax_expander_table()); } // These are the words that shouldn't be allowed as value identifiers, @@ -227,13 +220,6 @@ fn bad_expr_word_table() -> hashmap[str, ()] { ret words; } -fn syntax_expander_table() -> hashmap[str, syntax_extension] { - auto syntax_expanders = new_str_hash[syntax_extension](); - syntax_expanders.insert("fmt", x(extfmt::expand_syntax_ext)); - syntax_expanders.insert("env", x(extenv::expand_syntax_ext)); - ret syntax_expanders; -} - fn unexpected(&parser p, token::token t) -> ! { let str s = "unexpected token: "; s += token::to_str(p.get_reader(), t); @@ -1060,11 +1046,13 @@ fn expand_syntax_ext(&parser p, common::span sp, auto extname = path.node.idents.(0); alt (p.get_syntax_expanders().find(extname)) { - case (none[syntax_extension]) { + case (none) { p.err("unknown syntax expander: '" + extname + "'"); } - case (some[syntax_extension](x(?ext))) { - ret ast::expr_ext(path, args, body, ext(p, sp, args, body), + case (some(ext::x(?ext))) { + auto ext_cx = ext::mk_ctxt(p.get_session()); + ret ast::expr_ext(path, args, body, + ext(ext_cx, p, sp, args, body), p.get_ann()); } } diff --git a/src/comp/rustc.rc b/src/comp/rustc.rc index 7fe5d603585e..55683ba7ffa3 100644 --- a/src/comp/rustc.rc +++ b/src/comp/rustc.rc @@ -38,6 +38,7 @@ mod pretty { mod front { mod ast; mod creader; + mod ext; mod extfmt; mod extenv; mod codemap;