diff options
| author | Paul Stansifer <paul.stansifer@gmail.com> | 2011-08-05 13:06:11 -0700 |
|---|---|---|
| committer | Paul Stansifer <paul.stansifer@gmail.com> | 2011-08-15 15:35:27 -0700 |
| commit | 6d39be465f77992d969a428befaa3ffcea9fe0da (patch) | |
| tree | 1afa3f7bdfb67aa4f446105d37d84987b6e16621 /src/comp/syntax | |
| parent | 5428d4ee6d7afbd9d587658903a7c686eb97f9c3 (diff) | |
| download | rust-6d39be465f77992d969a428befaa3ffcea9fe0da.tar.gz rust-6d39be465f77992d969a428befaa3ffcea9fe0da.zip | |
Add backtraces for syntax problems.
Diffstat (limited to 'src/comp/syntax')
| -rw-r--r-- | src/comp/syntax/ext/base.rs | 70 | ||||
| -rw-r--r-- | src/comp/syntax/ext/expand.rs | 52 | ||||
| -rw-r--r-- | src/comp/syntax/ext/fmt.rs | 2 |
3 files changed, 60 insertions, 64 deletions
diff --git a/src/comp/syntax/ext/base.rs b/src/comp/syntax/ext/base.rs index fd37b6c2d3c..5aad9c5cd14 100644 --- a/src/comp/syntax/ext/base.rs +++ b/src/comp/syntax/ext/base.rs @@ -32,41 +32,46 @@ fn syntax_expander_table() -> hashmap[str, syntax_extension] { ret syntax_expanders; } -type span_msg_fn = fn(span, str) -> ! ; -type msg_fn = fn(str) -> ! ; +obj ext_ctxt(sess: @session, crate_file_name_hack: str, + mutable backtrace: span[]) { + fn crate_file_name() -> str { ret crate_file_name_hack; } -type next_id_fn = fn() -> ast::node_id ; - - -// Provides a limited set of services necessary for syntax extensions -// to do their thing -type ext_ctxt = - {crate_file_name_hack: str, - span_fatal: span_msg_fn, - span_unimpl: span_msg_fn, - span_bug: span_msg_fn, - bug: msg_fn, - next_id: next_id_fn}; + fn print_backtrace() { + for sp: span in backtrace { + sess.span_note(sp, "(while expanding this)") + } + } + + fn bt_push(sp: span) { backtrace += ~[sp]; } + fn bt_pop() { ivec::pop(backtrace); } -fn mk_ctxt(sess: &session) -> ext_ctxt { - fn ext_span_fatal_(sess: &session, sp: span, msg: str) -> ! { + fn span_fatal(sp: span, msg: str) -> ! { + self.print_backtrace(); + sess.span_fatal(sp, msg); + } + fn span_err(sp: span, msg: str) { + self.print_backtrace(); sess.span_err(sp, msg); - fail; } - let ext_span_fatal = bind ext_span_fatal_(sess, _, _); - fn ext_span_unimpl_(sess: &session, sp: span, msg: str) -> ! { - sess.span_err(sp, "unimplemented " + msg); - fail; + fn span_unimpl(sp:span, msg: str) -> ! { + self.print_backtrace(); + sess.span_unimpl(sp, msg); } - let ext_span_bug = bind ext_span_bug_(sess, _, _); - fn ext_span_bug_(sess: &session, sp: span, msg: str) -> ! { - sess.span_bug(sp, msg); + fn span_bug(sp:span, msg: str) -> ! { + self.print_backtrace(); + sess.span_bug(sp, msg); + } + fn bug(msg: str) -> ! { + self.print_backtrace(); + sess.bug(msg); + } + fn next_id() -> ast::node_id { + ret sess.next_node_id(); } - let ext_span_unimpl = bind ext_span_unimpl_(sess, _, _); - fn ext_bug_(sess: &session, msg: str) -> ! { sess.bug(msg); } - let ext_bug = bind ext_bug_(sess, _); +} +fn mk_ctxt(sess: &session) -> ext_ctxt { // FIXME: Some extensions work by building ASTs with paths to functions // they need to call at runtime. As those functions live in the std crate, // the paths are prefixed with "std::". Unfortunately, these paths can't @@ -76,16 +81,7 @@ fn mk_ctxt(sess: &session) -> ext_ctxt { // super-ugly and needs a better solution. let crate_file_name_hack = sess.get_codemap().files.(0).name; - fn ext_next_id_(sess: &session) -> ast::node_id { - ret sess.next_node_id(); // temporary, until bind works better - } - let ext_next_id = bind ext_next_id_(sess); - ret {crate_file_name_hack: crate_file_name_hack, - span_fatal: ext_span_fatal, - span_unimpl: ext_span_unimpl, - span_bug: ext_span_bug, - bug: ext_bug, - next_id: ext_next_id}; + ret ext_ctxt(@sess, crate_file_name_hack, ~[]); } fn expr_to_str(cx: &ext_ctxt, expr: @ast::expr, error: str) -> str { diff --git a/src/comp/syntax/ext/expand.rs b/src/comp/syntax/ext/expand.rs index e47a0fc2a71..790e892cec2 100644 --- a/src/comp/syntax/ext/expand.rs +++ b/src/comp/syntax/ext/expand.rs @@ -1,11 +1,4 @@ - -import codemap::emit_error; import driver::session; -import syntax::ast::crate; -import syntax::ast::expr_; -import syntax::ast::expr_mac; -import syntax::ast::mac_invoc; -import syntax::fold::*; import std::option::none; import std::option::some; @@ -13,40 +6,46 @@ import std::option::some; import std::map::hashmap; import std::ivec; -fn expand_expr(exts: &hashmap[str, base::syntax_extension], - sess: &session::session, e: &expr_, fld: ast_fold, - orig: &fn(&ast::expr_, ast_fold) -> expr_ ) -> expr_ { +import syntax::ast::crate; +import syntax::ast::expr_; +import syntax::ast::expr_mac; +import syntax::ast::mac_invoc; +import syntax::fold::*; +import syntax::ext::base::*; + + +fn expand_expr(exts: &hashmap[str, syntax_extension], cx: &ext_ctxt, + e: &expr_, fld: ast_fold, + orig: &fn(&expr_, ast_fold) -> expr_ ) -> expr_ { ret alt e { expr_mac(mac) { alt mac.node { mac_invoc(pth, args, body) { assert (ivec::len(pth.node.idents) > 0u); let extname = pth.node.idents.(0); - let ext_cx = base::mk_ctxt(sess); alt exts.find(extname) { none. { - emit_error(some(pth.span), - "unknown syntax expander: '" + extname + "'", - sess.get_codemap()); - fail + cx.span_fatal(pth.span, + #fmt["macro undefined: '%s'", extname]) } - some(base::normal(ext)) { + some(normal(ext)) { + let expanded = ext(cx, pth.span, args, body); + cx.bt_push(mac.span); //keep going, outside-in - fld.fold_expr(ext(ext_cx, pth.span, args, body)).node + let fully_expanded = fld.fold_expr(expanded).node; + cx.bt_pop(); + + fully_expanded } - some(base::macro_defining(ext)) { - let named_extension = ext(ext_cx, pth.span, args, body); + some(macro_defining(ext)) { + let named_extension = ext(cx, pth.span, args, body); exts.insert(named_extension.ident, named_extension.ext); ast::expr_rec(~[], none) } } } - _ { - emit_error(some(mac.span), "naked syntactic bit", - sess.get_codemap()); - fail - } + _ { cx.span_bug(mac.span, "naked syntactic bit") } } } _ { orig(e, fld) } @@ -54,10 +53,11 @@ fn expand_expr(exts: &hashmap[str, base::syntax_extension], } fn expand_crate(sess: &session::session, c: &@crate) -> @crate { - let exts = ext::base::syntax_expander_table(); + let exts = syntax_expander_table(); let afp = default_ast_fold(); + let cx: ext_ctxt = mk_ctxt(sess); let f_pre = - {fold_expr: bind expand_expr(exts, sess, _, _, afp.fold_expr) + {fold_expr: bind expand_expr(exts, cx, _, _, afp.fold_expr) with *afp}; let f = make_fold(f_pre); let res = @f.fold_crate(*c); diff --git a/src/comp/syntax/ext/fmt.rs b/src/comp/syntax/ext/fmt.rs index 8aa9ce308a7..27fcece7fb5 100644 --- a/src/comp/syntax/ext/fmt.rs +++ b/src/comp/syntax/ext/fmt.rs @@ -98,7 +98,7 @@ fn pieces_to_expr(cx: &ext_ctxt, sp: span, pieces: &[piece], } fn make_path_vec(cx: &ext_ctxt, ident: str) -> [str] { fn compiling_std(cx: &ext_ctxt) -> bool { - ret str::find(cx.crate_file_name_hack, "std.rc") >= 0; + ret str::find(cx.crate_file_name(), "std.rc") >= 0; } if compiling_std(cx) { ret ~["extfmt", "rt", ident]; |
