Implement quasi-quotes in more macro form: #ast{...}.
The #(...) form is still supported for now.
This commit is contained in:
parent
1c91fb4d91
commit
4d71285c93
4 changed files with 38 additions and 5 deletions
|
@ -30,6 +30,8 @@ fn syntax_expander_table() -> hashmap<str, syntax_extension> {
|
||||||
normal(ext::ident_to_str::expand_syntax_ext));
|
normal(ext::ident_to_str::expand_syntax_ext));
|
||||||
syntax_expanders.insert("log_syntax",
|
syntax_expanders.insert("log_syntax",
|
||||||
normal(ext::log_syntax::expand_syntax_ext));
|
normal(ext::log_syntax::expand_syntax_ext));
|
||||||
|
syntax_expanders.insert("ast",
|
||||||
|
normal(ext::qquote::expand_ast));
|
||||||
ret syntax_expanders;
|
ret syntax_expanders;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ fn expand_expr(exts: hashmap<str, syntax_extension>, cx: ext_ctxt,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mac_qq(sp, exp) {
|
mac_qq(sp, exp) {
|
||||||
let r = expand_qquote(cx, sp, exp);
|
let r = expand_qquote(cx, sp, none, exp);
|
||||||
// need to keep going, resuls may contain embedded qquote or
|
// need to keep going, resuls may contain embedded qquote or
|
||||||
// macro that need expanding
|
// macro that need expanding
|
||||||
let r2 = fld.fold_expr(r);
|
let r2 = fld.fold_expr(r);
|
||||||
|
|
|
@ -8,7 +8,8 @@ import syntax::fold::*;
|
||||||
import syntax::visit::*;
|
import syntax::visit::*;
|
||||||
import syntax::ext::base::*;
|
import syntax::ext::base::*;
|
||||||
import syntax::ext::build::*;
|
import syntax::ext::build::*;
|
||||||
import syntax::parse::parser::parse_expr_from_source_str;
|
import syntax::parse::parser;
|
||||||
|
import syntax::parse::parser::{parse_from_source_str};
|
||||||
|
|
||||||
import syntax::print::*;
|
import syntax::print::*;
|
||||||
import std::io::*;
|
import std::io::*;
|
||||||
|
@ -42,8 +43,26 @@ fn is_space(c: char) -> bool {
|
||||||
syntax::parse::lexer::is_whitespace(c)
|
syntax::parse::lexer::is_whitespace(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expand_qquote(ecx: ext_ctxt, sp: span, e: @ast::expr) -> @ast::expr {
|
fn expand_ast(ecx: ext_ctxt, _sp: span, _arg: ast::mac_arg, body: ast::mac_body)
|
||||||
let str = codemap::span_to_snippet(sp, ecx.session().parse_sess.cm);
|
-> @ast::expr
|
||||||
|
{
|
||||||
|
let body = get_mac_body(ecx,_sp,body);
|
||||||
|
let str = @codemap::span_to_snippet(body.span, ecx.session().parse_sess.cm);
|
||||||
|
let {node: e, _} = parse_from_source_str(parser::parse_expr,
|
||||||
|
"<anon>", str,
|
||||||
|
ecx.session().opts.cfg,
|
||||||
|
ecx.session().parse_sess);
|
||||||
|
ret expand_qquote(ecx, e.span, some(*str), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn expand_qquote(ecx: ext_ctxt, sp: span, maybe_str: option::t<str>,
|
||||||
|
e: @ast::expr)
|
||||||
|
-> @ast::expr
|
||||||
|
{
|
||||||
|
let str = alt(maybe_str) {
|
||||||
|
some(s) {s}
|
||||||
|
none {codemap::span_to_snippet(sp, ecx.session().parse_sess.cm)}
|
||||||
|
};
|
||||||
let qcx = gather_anti_quotes(sp.lo, e);
|
let qcx = gather_anti_quotes(sp.lo, e);
|
||||||
let cx = qcx;
|
let cx = qcx;
|
||||||
let prev = 0u;
|
let prev = 0u;
|
||||||
|
|
|
@ -1013,7 +1013,7 @@ fn parse_syntax_ext_naked(p: parser, lo: uint) -> @ast::expr {
|
||||||
}
|
}
|
||||||
p.bump();
|
p.bump();
|
||||||
}
|
}
|
||||||
let hi = p.last_span.hi;
|
let hi = p.last_span.lo;
|
||||||
b = some({span: mk_sp(lo,hi)});
|
b = some({span: mk_sp(lo,hi)});
|
||||||
}
|
}
|
||||||
ret mk_mac_expr(p, lo, p.span.hi, ast::mac_invoc(pth, e, b));
|
ret mk_mac_expr(p, lo, p.span.hi, ast::mac_invoc(pth, e, b));
|
||||||
|
@ -2543,6 +2543,18 @@ fn parse_expr_from_source_str(name: str, source: @str, cfg: ast::crate_cfg,
|
||||||
ret r;
|
ret r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_from_source_str<T>(f: fn (p: parser) -> T,
|
||||||
|
name: str, source: @str, cfg: ast::crate_cfg,
|
||||||
|
sess: parse_sess)
|
||||||
|
-> {node: T, fm: codemap::filemap}
|
||||||
|
{
|
||||||
|
let p = new_parser_from_source_str(sess, cfg, name, source);
|
||||||
|
let r = f(p);
|
||||||
|
sess.chpos = p.reader.chpos;
|
||||||
|
sess.byte_pos = sess.byte_pos + p.reader.pos;
|
||||||
|
ret {node: r, fm: option::get(vec::last(sess.cm.files))};
|
||||||
|
}
|
||||||
|
|
||||||
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 p = new_parser_from_source_str(sess, cfg, name, source);
|
let p = new_parser_from_source_str(sess, cfg, name, source);
|
||||||
|
|
Loading…
Reference in a new issue