Add support for parsing quasi-quotes, doesn't do anything useful yet.
This commit is contained in:
parent
75edd9ff69
commit
5ef53382ae
10 changed files with 74 additions and 2 deletions
|
@ -277,6 +277,10 @@ enum mac_ {
|
|||
mac_embed_type(@ty),
|
||||
mac_embed_block(blk),
|
||||
mac_ellipsis,
|
||||
// the span is used by the quoter/anti-quoter ...
|
||||
mac_qq(span /* span of expr */, @expr), // quasi-quote
|
||||
mac_aq(span /* span of quote */, @expr), // anti-quote
|
||||
mac_var(uint),
|
||||
}
|
||||
|
||||
type lit = spanned<lit_>;
|
||||
|
|
|
@ -5,7 +5,7 @@ import option::{none, some};
|
|||
import std::map::hashmap;
|
||||
import vec;
|
||||
|
||||
import syntax::ast::{crate, expr_, expr_mac, mac_invoc};
|
||||
import syntax::ast::{crate, expr_, expr_mac, mac_invoc, mac_qq};
|
||||
import syntax::fold::*;
|
||||
import syntax::ext::base::*;
|
||||
import syntax::parse::parser::parse_expr_from_source_str;
|
||||
|
@ -45,6 +45,7 @@ fn expand_expr(exts: hashmap<str, syntax_extension>, cx: ext_ctxt,
|
|||
}
|
||||
}
|
||||
}
|
||||
mac_qq(sp, exp) { (expand_qquote(cx, sp, exp), s) }
|
||||
_ { cx.span_bug(mac.span, "naked syntactic bit") }
|
||||
}
|
||||
}
|
||||
|
@ -52,6 +53,13 @@ fn expand_expr(exts: hashmap<str, syntax_extension>, cx: ext_ctxt,
|
|||
};
|
||||
}
|
||||
|
||||
fn expand_qquote(cx: ext_ctxt, sp: span, e: @ast::expr) -> ast::expr_ {
|
||||
import syntax::ext::build::*;
|
||||
let str = codemap::span_to_snippet(sp, cx.session().parse_sess.cm);
|
||||
let expr = make_new_str(cx, e.span, str);
|
||||
ret expr.node;
|
||||
}
|
||||
|
||||
// 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
|
||||
|
|
|
@ -587,6 +587,9 @@ fn p_t_s_r_mac(cx: ext_ctxt, mac: ast::mac, s: selector, b: binders) {
|
|||
none { no_des(cx, blk.span, "under `#{}`"); }
|
||||
}
|
||||
}
|
||||
ast::mac_qq(_,_) { no_des(cx, mac.span, "quasiquotes"); }
|
||||
ast::mac_aq(_,_) { no_des(cx, mac.span, "antiquotes"); }
|
||||
ast::mac_var(_) { no_des(cx, mac.span, "antiquote variables"); }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -138,6 +138,9 @@ fn fold_mac_(m: mac, fld: ast_fold) -> mac {
|
|||
mac_embed_type(ty) { mac_embed_type(fld.fold_ty(ty)) }
|
||||
mac_embed_block(blk) { mac_embed_block(fld.fold_block(blk)) }
|
||||
mac_ellipsis { mac_ellipsis }
|
||||
mac_qq(_,_) { /* fixme */ m.node }
|
||||
mac_aq(_,_) { /* fixme */ m.node }
|
||||
mac_var(_) { /* fixme */ m.node }
|
||||
},
|
||||
span: m.span};
|
||||
}
|
||||
|
|
|
@ -349,6 +349,7 @@ fn next_token_inner(rdr: reader) -> token::token {
|
|||
'#' {
|
||||
rdr.bump();
|
||||
if rdr.curr == '<' { rdr.bump(); ret token::POUND_LT; }
|
||||
if rdr.curr == '(' { rdr.bump(); ret token::POUND_LPAREN; }
|
||||
if rdr.curr == '{' { rdr.bump(); ret token::POUND_LBRACE; }
|
||||
ret token::POUND;
|
||||
}
|
||||
|
@ -361,6 +362,23 @@ fn next_token_inner(rdr: reader) -> token::token {
|
|||
} else { ret token::COLON; }
|
||||
}
|
||||
|
||||
'$' {
|
||||
rdr.bump();
|
||||
if is_dec_digit(rdr.curr) {
|
||||
let val = dec_digit_val(rdr.curr) as uint;
|
||||
while is_dec_digit(rdr.next()) {
|
||||
rdr.bump();
|
||||
val = val * 10u + (dec_digit_val(rdr.curr) as uint);
|
||||
}
|
||||
rdr.bump();
|
||||
ret token::DOLLAR_NUM(val);
|
||||
} else if c == '(' {
|
||||
ret token::DOLLAR_LPAREN;
|
||||
} else {
|
||||
rdr.fatal("expected digit3");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -628,6 +628,13 @@ fn parse_seq<T: copy>(bra: token::token, ket: token::token,
|
|||
ret spanned(lo, hi, result);
|
||||
}
|
||||
|
||||
fn have_dollar(p: parser) -> option::t<ast::mac_> {
|
||||
alt p.token {
|
||||
token::DOLLAR_NUM(num) {p.bump(); some(ast::mac_var(num))}
|
||||
_ {none}
|
||||
}
|
||||
}
|
||||
|
||||
fn lit_from_token(p: parser, tok: token::token) -> ast::lit_ {
|
||||
alt tok {
|
||||
token::LIT_INT(i, it) { ast::lit_int(i, it) }
|
||||
|
@ -755,6 +762,12 @@ fn parse_bottom_expr(p: parser) -> pexpr {
|
|||
let hi = p.span.hi;
|
||||
|
||||
let ex: ast::expr_;
|
||||
|
||||
alt have_dollar(p) {
|
||||
some(x) {ret pexpr(mk_mac_expr(p, lo, p.span.hi, x));}
|
||||
_ {}
|
||||
}
|
||||
|
||||
if p.token == token::LPAREN {
|
||||
p.bump();
|
||||
if p.token == token::RPAREN {
|
||||
|
@ -843,6 +856,12 @@ fn parse_bottom_expr(p: parser) -> pexpr {
|
|||
} else if p.token == token::ELLIPSIS {
|
||||
p.bump();
|
||||
ret pexpr(mk_mac_expr(p, lo, p.span.hi, ast::mac_ellipsis));
|
||||
} else if p.token == token::POUND_LPAREN {
|
||||
p.bump();
|
||||
let e = parse_expr(p);
|
||||
expect(p, token::RPAREN);
|
||||
ret pexpr(mk_mac_expr(p, lo, p.span.hi,
|
||||
ast::mac_qq(e.span, e)));
|
||||
} else if eat_word(p, "bind") {
|
||||
let e = parse_expr_res(p, RESTRICT_NO_CALL_EXPRS);
|
||||
fn parse_expr_opt(p: parser) -> option<@ast::expr> {
|
||||
|
|
|
@ -53,9 +53,13 @@ enum token {
|
|||
LBRACE,
|
||||
RBRACE,
|
||||
POUND,
|
||||
POUND_LPAREN,
|
||||
POUND_LBRACE,
|
||||
POUND_LT,
|
||||
|
||||
DOLLAR_LPAREN,
|
||||
DOLLAR_NUM(uint),
|
||||
|
||||
/* Literals */
|
||||
LIT_INT(i64, ast::int_ty),
|
||||
LIT_UINT(u64, ast::uint_ty),
|
||||
|
@ -69,6 +73,7 @@ enum token {
|
|||
UNDERSCORE,
|
||||
BRACEQUOTE(str_num),
|
||||
EOF,
|
||||
|
||||
}
|
||||
|
||||
fn binop_to_str(o: binop) -> str {
|
||||
|
@ -123,9 +128,15 @@ fn to_str(r: reader, t: token) -> str {
|
|||
LBRACE { ret "{"; }
|
||||
RBRACE { ret "}"; }
|
||||
POUND { ret "#"; }
|
||||
POUND_LPAREN { ret "#("; }
|
||||
POUND_LBRACE { ret "#{"; }
|
||||
POUND_LT { ret "#<"; }
|
||||
|
||||
DOLLAR_LPAREN { ret "$("; }
|
||||
DOLLAR_NUM(u) {
|
||||
ret "$" + uint::to_str(u as uint, 10u);
|
||||
}
|
||||
|
||||
/* Literals */
|
||||
LIT_INT(c, ast::ty_char) {
|
||||
// FIXME: escape.
|
||||
|
|
|
@ -739,6 +739,8 @@ fn print_mac(s: ps, m: ast::mac) {
|
|||
print_possibly_embedded_block(s, blk, block_normal, indent_unit);
|
||||
}
|
||||
ast::mac_ellipsis { word(s.s, "..."); }
|
||||
ast::mac_var(v) { word(s.s, #fmt("$%u", v)); }
|
||||
_ { /* fixme */ }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -277,6 +277,9 @@ fn visit_mac<E>(m: mac, e: E, v: vt<E>) {
|
|||
ast::mac_embed_type(ty) { v.visit_ty(ty, e, v); }
|
||||
ast::mac_embed_block(blk) { v.visit_block(blk, e, v); }
|
||||
ast::mac_ellipsis { }
|
||||
ast::mac_qq(_, e) { /* FIXME: maybe visit */ }
|
||||
ast::mac_aq(_, e) { /* FIXME: maybe visit */ }
|
||||
ast::mac_var(_) { }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// xfail-test
|
||||
// error-pattern:expected a syntax expander name
|
||||
|
||||
fn main() {
|
||||
#();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue