Inject "core macros" into default syntax-expansion environment. Bit of a kludge but enough to work on logging-via-macros.
This commit is contained in:
parent
a24c19e867
commit
3bc4da96f1
4 changed files with 48 additions and 21 deletions
|
@ -34,12 +34,16 @@ fn next_line(file: filemap, chpos: uint, byte_pos: uint) {
|
||||||
type lookup_fn = fn(file_pos) -> uint;
|
type lookup_fn = fn(file_pos) -> uint;
|
||||||
|
|
||||||
fn lookup_pos(map: codemap, pos: uint, lookup: lookup_fn) -> loc {
|
fn lookup_pos(map: codemap, pos: uint, lookup: lookup_fn) -> loc {
|
||||||
|
let len = vec::len(map.files);
|
||||||
let a = 0u;
|
let a = 0u;
|
||||||
let b = vec::len(map.files);
|
let b = len;
|
||||||
while b - a > 1u {
|
while b - a > 1u {
|
||||||
let m = (a + b) / 2u;
|
let m = (a + b) / 2u;
|
||||||
if lookup(map.files[m].start_pos) > pos { b = m; } else { a = m; }
|
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];
|
let f = map.files[a];
|
||||||
a = 0u;
|
a = 0u;
|
||||||
b = vec::len(f.lines);
|
b = vec::len(f.lines);
|
||||||
|
|
|
@ -34,9 +34,7 @@ fn syntax_expander_table() -> hashmap<str, syntax_extension> {
|
||||||
}
|
}
|
||||||
|
|
||||||
obj ext_ctxt(sess: @session,
|
obj ext_ctxt(sess: @session,
|
||||||
crate_file_name_hack: str,
|
|
||||||
mutable backtrace: codemap::opt_span) {
|
mutable backtrace: codemap::opt_span) {
|
||||||
fn crate_file_name() -> str { ret crate_file_name_hack; }
|
|
||||||
|
|
||||||
fn session() -> @session { ret sess; }
|
fn session() -> @session { ret sess; }
|
||||||
|
|
||||||
|
@ -82,16 +80,7 @@ obj ext_ctxt(sess: @session,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mk_ctxt(sess: session) -> ext_ctxt {
|
fn mk_ctxt(sess: session) -> ext_ctxt {
|
||||||
// FIXME: Some extensions work by building ASTs with paths to functions
|
ret ext_ctxt(@sess, codemap::os_none);
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expr_to_str(cx: ext_ctxt, expr: @ast::expr, error: str) -> str {
|
fn expr_to_str(cx: ext_ctxt, expr: @ast::expr, error: str) -> str {
|
||||||
|
|
|
@ -8,7 +8,7 @@ import vec;
|
||||||
import syntax::ast::{crate, expr_, expr_mac, mac_invoc};
|
import syntax::ast::{crate, expr_, expr_mac, mac_invoc};
|
||||||
import syntax::fold::*;
|
import syntax::fold::*;
|
||||||
import syntax::ext::base::*;
|
import syntax::ext::base::*;
|
||||||
|
import syntax::parse::parser::parse_expr_from_source_str;
|
||||||
|
|
||||||
fn expand_expr(exts: hashmap<str, syntax_extension>, cx: ext_ctxt, e: expr_,
|
fn expand_expr(exts: hashmap<str, syntax_extension>, cx: ext_ctxt, e: expr_,
|
||||||
fld: ast_fold, orig: fn@(expr_, ast_fold) -> expr_) -> expr_ {
|
fld: ast_fold, orig: fn@(expr_, ast_fold) -> expr_) -> expr_ {
|
||||||
|
@ -47,6 +47,21 @@ fn expand_expr(exts: hashmap<str, syntax_extension>, 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 {
|
fn expand_crate(sess: session::session, c: @crate) -> @crate {
|
||||||
let exts = syntax_expander_table();
|
let exts = syntax_expander_table();
|
||||||
let afp = default_ast_fold();
|
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)
|
{fold_expr: bind expand_expr(exts, cx, _, _, afp.fold_expr)
|
||||||
with *afp};
|
with *afp};
|
||||||
let f = make_fold(f_pre);
|
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);
|
let res = @f.fold_crate(*c);
|
||||||
ret res;
|
ret res;
|
||||||
|
|
||||||
}
|
}
|
||||||
// Local Variables:
|
// Local Variables:
|
||||||
// mode: rust
|
// mode: rust
|
||||||
|
|
|
@ -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);
|
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,
|
fn new_parser(sess: parse_sess, cfg: ast::crate_cfg, rdr: lexer::reader,
|
||||||
ftype: file_type) -> parser {
|
ftype: file_type) -> parser {
|
||||||
obj stdio_parser(sess: parse_sess,
|
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);
|
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,
|
fn parse_crate_from_source_str(name: str, source: str, cfg: ast::crate_cfg,
|
||||||
sess: parse_sess) -> @ast::crate {
|
sess: parse_sess) -> @ast::crate {
|
||||||
let ftype = SOURCE_FILE;
|
let p = new_parser_from_source_str(sess, cfg, name, source);
|
||||||
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);
|
|
||||||
ret parse_crate_mod(p, cfg);
|
ret parse_crate_mod(p, cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue