Skip to content

Some syntax refactorings #15834

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 22, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/libregex_macros/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ use syntax::ext::build::AstBuilder;
use syntax::ext::base::{ExtCtxt, MacResult, MacExpr, DummyResult};
use syntax::parse::token;
use syntax::print::pprust;
use syntax::fold::Folder;

use rustc::plugin::Registry;

Expand Down Expand Up @@ -615,7 +616,7 @@ fn exec<'t>(which: ::regex::native::MatchKind, input: &'t str,
/// Otherwise, logs an error with cx.span_err and returns None.
fn parse(cx: &mut ExtCtxt, tts: &[ast::TokenTree]) -> Option<String> {
let mut parser = cx.new_parser_from_tts(tts);
let entry = cx.expand_expr(parser.parse_expr());
let entry = cx.expander().fold_expr(parser.parse_expr());
let regex = match entry.node {
ast::ExprLit(lit) => {
match lit.node {
Expand Down
61 changes: 30 additions & 31 deletions src/libsyntax/ext/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ use parse::token;
use parse::token::{InternedString, intern, str_to_ident};
use util::small_vector::SmallVector;
use ext::mtwt;
use fold::Folder;

use std::collections::HashMap;
use std::gc::{Gc, GC};
use std::rc::Rc;

// new-style macro! tt code:
//
Expand Down Expand Up @@ -104,9 +106,9 @@ pub type IdentMacroExpanderFn =
/// just into the compiler's internal macro table, for `make_def`).
pub trait MacResult {
/// Define a new macro.
// this particular flavor should go away; the idea that a macro might
// expand into either a macro definition or an expression, depending
// on what the context wants, is kind of silly.
// this should go away; the idea that a macro might expand into
// either a macro definition or an expression, depending on what
// the context wants, is kind of silly.
fn make_def(&self) -> Option<MacroDef> {
None
}
Expand Down Expand Up @@ -314,7 +316,7 @@ impl BlockInfo {

/// The base map of methods for expanding syntax extension
/// AST nodes into full ASTs
pub fn syntax_expander_table() -> SyntaxEnv {
fn initial_syntax_expander_table() -> SyntaxEnv {
// utility function to simplify creating NormalTT syntax extensions
fn builtin_normal_expander(f: MacroExpanderFn) -> SyntaxExtension {
NormalTT(box BasicMacroExpander {
Expand Down Expand Up @@ -431,7 +433,9 @@ pub struct ExtCtxt<'a> {

pub mod_path: Vec<ast::Ident> ,
pub trace_mac: bool,
pub exported_macros: Vec<Gc<ast::Item>>
pub exported_macros: Vec<Gc<ast::Item>>,

pub syntax_env: SyntaxEnv,
}

impl<'a> ExtCtxt<'a> {
Expand All @@ -445,22 +449,18 @@ impl<'a> ExtCtxt<'a> {
ecfg: ecfg,
trace_mac: false,
exported_macros: Vec::new(),
syntax_env: initial_syntax_expander_table(),
}
}

pub fn expand_expr(&mut self, mut e: Gc<ast::Expr>) -> Gc<ast::Expr> {
loop {
match e.node {
ast::ExprMac(..) => {
let mut expander = expand::MacroExpander {
extsbox: syntax_expander_table(),
cx: self,
};
e = expand::expand_expr(e, &mut expander);
}
_ => return e
}
}
#[deprecated = "Replaced with `expander().fold_expr()`"]
pub fn expand_expr(&mut self, e: Gc<ast::Expr>) -> Gc<ast::Expr> {
self.expander().fold_expr(e)
}

/// Returns a `Folder` for deeply expanding all macros in a AST node.
pub fn expander<'b>(&'b mut self) -> expand::MacroExpander<'b, 'a> {
expand::MacroExpander { cx: self }
}

pub fn new_parser_from_tts(&self, tts: &[ast::TokenTree])
Expand Down Expand Up @@ -570,7 +570,7 @@ impl<'a> ExtCtxt<'a> {
pub fn expr_to_string(cx: &mut ExtCtxt, expr: Gc<ast::Expr>, err_msg: &str)
-> Option<(InternedString, ast::StrStyle)> {
// we want to be able to handle e.g. concat("foo", "bar")
let expr = cx.expand_expr(expr);
let expr = cx.expander().fold_expr(expr);
match expr.node {
ast::ExprLit(l) => match l.node {
ast::LitStr(ref s, style) => return Some(((*s).clone(), style)),
Expand Down Expand Up @@ -627,7 +627,7 @@ pub fn get_exprs_from_tts(cx: &mut ExtCtxt,
let mut p = cx.new_parser_from_tts(tts);
let mut es = Vec::new();
while p.token != token::EOF {
es.push(cx.expand_expr(p.parse_expr()));
es.push(cx.expander().fold_expr(p.parse_expr()));
if p.eat(&token::COMMA) {
continue;
}
Expand All @@ -642,10 +642,13 @@ pub fn get_exprs_from_tts(cx: &mut ExtCtxt,
/// In order to have some notion of scoping for macros,
/// we want to implement the notion of a transformation
/// environment.

///
/// This environment maps Names to SyntaxExtensions.
pub struct SyntaxEnv {
chain: Vec<MapChainFrame> ,
}

//impl question: how to implement it? Initially, the
// impl question: how to implement it? Initially, the
// env will contain only macros, so it might be painful
// to add an empty frame for every context. Let's just
// get it working, first....
Expand All @@ -657,15 +660,11 @@ pub fn get_exprs_from_tts(cx: &mut ExtCtxt,

struct MapChainFrame {
info: BlockInfo,
map: HashMap<Name, SyntaxExtension>,
}

pub struct SyntaxEnv {
chain: Vec<MapChainFrame> ,
map: HashMap<Name, Rc<SyntaxExtension>>,
}

impl SyntaxEnv {
pub fn new() -> SyntaxEnv {
fn new() -> SyntaxEnv {
let mut map = SyntaxEnv { chain: Vec::new() };
map.push_frame();
map
Expand All @@ -692,18 +691,18 @@ impl SyntaxEnv {
unreachable!()
}

pub fn find<'a>(&'a self, k: &Name) -> Option<&'a SyntaxExtension> {
pub fn find(&self, k: &Name) -> Option<Rc<SyntaxExtension>> {
for frame in self.chain.iter().rev() {
match frame.map.find(k) {
Some(v) => return Some(v),
Some(v) => return Some(v.clone()),
None => {}
}
}
None
}

pub fn insert(&mut self, k: Name, v: SyntaxExtension) {
self.find_escape_frame().map.insert(k, v);
self.find_escape_frame().map.insert(k, Rc::new(v));
}

pub fn info<'a>(&'a mut self) -> &'a mut BlockInfo {
Expand Down
Loading