Implement quasi-quotes in more macro form: #ast{...}.

The #(...) form is still supported for now.
This commit is contained in:
Kevin Atkinson 2012-02-01 02:58:28 -07:00
parent 1c91fb4d91
commit 4d71285c93
4 changed files with 38 additions and 5 deletions

View file

@ -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;
} }

View file

@ -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);

View file

@ -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;

View file

@ -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);