diff --git a/src/comp/syntax/codemap.rs b/src/comp/syntax/codemap.rs index 9725517ed285..8cdbcd32caef 100644 --- a/src/comp/syntax/codemap.rs +++ b/src/comp/syntax/codemap.rs @@ -34,12 +34,16 @@ fn next_line(file: filemap, chpos: uint, byte_pos: uint) { type lookup_fn = fn(file_pos) -> uint; fn lookup_pos(map: codemap, pos: uint, lookup: lookup_fn) -> loc { + let len = vec::len(map.files); let a = 0u; - let b = vec::len(map.files); + let b = len; while b - a > 1u { let m = (a + b) / 2u; if lookup(map.files[m].start_pos) > pos { b = m; } else { a = m; } } + if (a >= len) { + ret { filename: "-", line: 0u, col: 0u }; + } let f = map.files[a]; a = 0u; b = vec::len(f.lines); diff --git a/src/comp/syntax/ext/base.rs b/src/comp/syntax/ext/base.rs index 55294000f66f..798e948a12e8 100644 --- a/src/comp/syntax/ext/base.rs +++ b/src/comp/syntax/ext/base.rs @@ -34,9 +34,7 @@ fn syntax_expander_table() -> hashmap { } obj ext_ctxt(sess: @session, - crate_file_name_hack: str, mutable backtrace: codemap::opt_span) { - fn crate_file_name() -> str { ret crate_file_name_hack; } fn session() -> @session { ret sess; } @@ -82,16 +80,7 @@ obj ext_ctxt(sess: @session, } 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 - // work for code called from inside the stdard library, so here we pass - // the extensions the file name of the crate being compiled so they can - // use it to guess whether paths should be prepended with "std::". This is - // super-ugly and needs a better solution. - let crate_file_name_hack = sess.get_codemap().files[0].name; - - ret ext_ctxt(@sess, crate_file_name_hack, codemap::os_none); + ret ext_ctxt(@sess, codemap::os_none); } 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 ef2105b4271b..150f9ad97bb4 100644 --- a/src/comp/syntax/ext/expand.rs +++ b/src/comp/syntax/ext/expand.rs @@ -8,7 +8,7 @@ import vec; import syntax::ast::{crate, expr_, expr_mac, mac_invoc}; import syntax::fold::*; import syntax::ext::base::*; - +import syntax::parse::parser::parse_expr_from_source_str; fn expand_expr(exts: hashmap, cx: ext_ctxt, e: expr_, fld: ast_fold, orig: fn@(expr_, ast_fold) -> expr_) -> expr_ { @@ -47,6 +47,21 @@ fn expand_expr(exts: hashmap, cx: ext_ctxt, e: expr_, }; } +// FIXME: this is a terrible kludge to inject some macros into the default +// compilation environment. When the macro-definition system is substantially +// more mature, these should move from here, into a compiled part of libcore +// at very least. + +fn core_macros() -> str { + ret +"{ + #macro[[#error[f, ...], log_err #fmt[f, ...]]]; + #macro[[#warn[f, ...], log_err #fmt[f, ...]]]; + #macro[[#info[f, ...], log_err #fmt[f, ...]]]; + #macro[[#debug[f, ...], log_err #fmt[f, ...]]]; +}"; +} + fn expand_crate(sess: session::session, c: @crate) -> @crate { let exts = syntax_expander_table(); let afp = default_ast_fold(); @@ -55,9 +70,16 @@ fn expand_crate(sess: session::session, c: @crate) -> @crate { {fold_expr: bind expand_expr(exts, cx, _, _, afp.fold_expr) with *afp}; let f = make_fold(f_pre); + let cm = parse_expr_from_source_str("-", core_macros(), + sess.get_opts().cfg, + sess.get_parse_sess()); + + // This is run for its side-effects on the expander env, + // as it registers all the core macros as expanders. + f.fold_expr(cm); + let res = @f.fold_crate(*c); ret res; - } // Local Variables: // mode: rust diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs index 1b3bb87cddcd..43270de40495 100644 --- a/src/comp/syntax/parse/parser.rs +++ b/src/comp/syntax/parse/parser.rs @@ -71,6 +71,16 @@ fn new_parser_from_file(sess: parse_sess, cfg: ast::crate_cfg, path: str, ret new_parser(sess, cfg, rdr, ftype); } +fn new_parser_from_source_str(sess: parse_sess, cfg: ast::crate_cfg, + name: str, source: str) -> parser { + let ftype = SOURCE_FILE; + let filemap = codemap::new_filemap(name, 0u, 0u); + sess.cm.files += [filemap]; + let itr = @interner::mk(str::hash, str::eq); + let rdr = lexer::new_reader(sess.cm, source, filemap, itr); + ret new_parser(sess, cfg, rdr, ftype); +} + fn new_parser(sess: parse_sess, cfg: ast::crate_cfg, rdr: lexer::reader, ftype: file_type) -> parser { obj stdio_parser(sess: parse_sess, @@ -2417,14 +2427,16 @@ fn parse_crate_from_source_file(input: str, cfg: ast::crate_cfg, ret parse_crate_mod(p, cfg); } + +fn parse_expr_from_source_str(name: str, source: str, cfg: ast::crate_cfg, + sess: parse_sess) -> @ast::expr { + let p = new_parser_from_source_str(sess, cfg, name, source); + ret parse_expr(p); +} + fn parse_crate_from_source_str(name: str, source: str, cfg: ast::crate_cfg, sess: parse_sess) -> @ast::crate { - let ftype = SOURCE_FILE; - let filemap = codemap::new_filemap(name, 0u, 0u); - sess.cm.files += [filemap]; - let itr = @interner::mk(str::hash, str::eq); - let rdr = lexer::new_reader(sess.cm, source, filemap, itr); - let p = new_parser(sess, cfg, rdr, ftype); + let p = new_parser_from_source_str(sess, cfg, name, source); ret parse_crate_mod(p, cfg); }