From 44575f708aed13f4260c6ce27b35ab102e5dd9f2 Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Sat, 16 Jul 2016 19:11:28 +0000 Subject: Rename `mtwt` to `hygiene` --- src/libsyntax/ast.rs | 2 +- src/libsyntax/ext/expand.rs | 2 +- src/libsyntax/ext/hygiene.rs | 151 +++++++++++++++++++++++++++++++++++++++++++ src/libsyntax/ext/mtwt.rs | 151 ------------------------------------------- src/libsyntax/lib.rs | 2 +- 5 files changed, 154 insertions(+), 154 deletions(-) create mode 100644 src/libsyntax/ext/hygiene.rs delete mode 100644 src/libsyntax/ext/mtwt.rs (limited to 'src/libsyntax') diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 1f716923a16..a8bb255fba4 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -19,7 +19,7 @@ pub use util::ThinVec; use syntax_pos::{mk_sp, Span, DUMMY_SP, ExpnId}; use codemap::{respan, Spanned}; use abi::Abi; -use ext::mtwt::SyntaxContext; +use ext::hygiene::SyntaxContext; use parse::token::{self, keywords, InternedString}; use print::pprust; use ptr::P; diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 767d1ddb8e2..18342f2e38c 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -11,7 +11,7 @@ use ast::{Block, Crate, Ident, Mac_, Name, PatKind}; use ast::{MacStmtStyle, Stmt, StmtKind, ItemKind}; use ast; -use ext::mtwt::Mark; +use ext::hygiene::Mark; use attr::{self, HasAttrs}; use attr::AttrMetaMethods; use codemap::{dummy_spanned, ExpnInfo, NameAndSpan, MacroBang, MacroAttribute}; diff --git a/src/libsyntax/ext/hygiene.rs b/src/libsyntax/ext/hygiene.rs new file mode 100644 index 00000000000..521930f69a9 --- /dev/null +++ b/src/libsyntax/ext/hygiene.rs @@ -0,0 +1,151 @@ +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Machinery for hygienic macros, inspired by the MTWT[1] paper. +//! +//! [1] Matthew Flatt, Ryan Culpepper, David Darais, and Robert Bruce Findler. +//! 2012. *Macros that work together: Compile-time bindings, partial expansion, +//! and definition contexts*. J. Funct. Program. 22, 2 (March 2012), 181-216. +//! DOI=10.1017/S0956796812000093 http://dx.doi.org/10.1017/S0956796812000093 + +use std::cell::RefCell; +use std::collections::HashMap; +use std::fmt; + +/// A SyntaxContext represents a chain of macro expansions (represented by marks). +#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Default)] +pub struct SyntaxContext(u32); + +#[derive(Copy, Clone)] +pub struct SyntaxContextData { + pub outer_mark: Mark, + pub prev_ctxt: SyntaxContext, +} + +/// A mark represents a unique id associated with a macro expansion. +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Default)] +pub struct Mark(u32); + +impl Mark { + pub fn fresh() -> Self { + HygieneData::with(|data| { + let next_mark = Mark(data.next_mark.0 + 1); + ::std::mem::replace(&mut data.next_mark, next_mark) + }) + } +} + +struct HygieneData { + syntax_contexts: Vec, + markings: HashMap<(SyntaxContext, Mark), SyntaxContext>, + next_mark: Mark, +} + +impl HygieneData { + fn new() -> Self { + HygieneData { + syntax_contexts: vec![SyntaxContextData { + outer_mark: Mark(0), // the null mark + prev_ctxt: SyntaxContext(0), // the empty context + }], + markings: HashMap::new(), + next_mark: Mark(1), + } + } + + fn with T>(f: F) -> T { + thread_local! { + static HYGIENE_DATA: RefCell = RefCell::new(HygieneData::new()); + } + HYGIENE_DATA.with(|data| f(&mut *data.borrow_mut())) + } +} + +pub fn reset_hygiene_data() { + HygieneData::with(|data| *data = HygieneData::new()) +} + +impl SyntaxContext { + pub const fn empty() -> Self { + SyntaxContext(0) + } + + pub fn data(self) -> SyntaxContextData { + HygieneData::with(|data| data.syntax_contexts[self.0 as usize]) + } + + /// Extend a syntax context with a given mark + pub fn apply_mark(self, mark: Mark) -> SyntaxContext { + // Applying the same mark twice is a no-op + let ctxt_data = self.data(); + if mark == ctxt_data.outer_mark { + return ctxt_data.prev_ctxt; + } + + HygieneData::with(|data| { + let syntax_contexts = &mut data.syntax_contexts; + *data.markings.entry((self, mark)).or_insert_with(|| { + syntax_contexts.push(SyntaxContextData { + outer_mark: mark, + prev_ctxt: self, + }); + SyntaxContext(syntax_contexts.len() as u32 - 1) + }) + }) + } + + /// If `ident` is macro expanded, return the source ident from the macro definition + /// and the mark of the expansion that created the macro definition. + pub fn source(self) -> (Self /* source context */, Mark /* source macro */) { + let macro_def_ctxt = self.data().prev_ctxt.data(); + (macro_def_ctxt.prev_ctxt, macro_def_ctxt.outer_mark) + } +} + +impl fmt::Debug for SyntaxContext { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "#{}", self.0) + } +} + +#[cfg(test)] +mod tests { + use ast::{EMPTY_CTXT, Mrk, SyntaxContext}; + use super::{apply_mark_internal, new_sctable_internal, Mark, SCTable}; + + // extend a syntax context with a sequence of marks given + // in a vector. v[0] will be the outermost mark. + fn unfold_marks(mrks: Vec , tail: SyntaxContext, table: &SCTable) + -> SyntaxContext { + mrks.iter().rev().fold(tail, |tail:SyntaxContext, mrk:&Mrk| + {apply_mark_internal(*mrk,tail,table)}) + } + + #[test] fn unfold_marks_test() { + let mut t = new_sctable_internal(); + + assert_eq!(unfold_marks(vec!(3,7),EMPTY_CTXT,&mut t),SyntaxContext(2)); + { + let table = t.table.borrow(); + assert!((*table)[1] == Mark(7,EMPTY_CTXT)); + assert!((*table)[2] == Mark(3,SyntaxContext(1))); + } + } + + #[test] + fn hashing_tests () { + let mut t = new_sctable_internal(); + assert_eq!(apply_mark_internal(12,EMPTY_CTXT,&mut t),SyntaxContext(1)); + assert_eq!(apply_mark_internal(13,EMPTY_CTXT,&mut t),SyntaxContext(2)); + // using the same one again should result in the same index: + assert_eq!(apply_mark_internal(12,EMPTY_CTXT,&mut t),SyntaxContext(1)); + // I'm assuming that the rename table will behave the same.... + } +} diff --git a/src/libsyntax/ext/mtwt.rs b/src/libsyntax/ext/mtwt.rs deleted file mode 100644 index c4af4a1f85b..00000000000 --- a/src/libsyntax/ext/mtwt.rs +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Machinery for hygienic macros, as described in the MTWT[1] paper. -//! -//! [1] Matthew Flatt, Ryan Culpepper, David Darais, and Robert Bruce Findler. -//! 2012. *Macros that work together: Compile-time bindings, partial expansion, -//! and definition contexts*. J. Funct. Program. 22, 2 (March 2012), 181-216. -//! DOI=10.1017/S0956796812000093 http://dx.doi.org/10.1017/S0956796812000093 - -use std::cell::RefCell; -use std::collections::HashMap; -use std::fmt; - -/// A SyntaxContext represents a chain of macro expansions (represented by marks). -#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Default)] -pub struct SyntaxContext(u32); - -#[derive(Copy, Clone)] -pub struct SyntaxContextData { - pub outer_mark: Mark, - pub prev_ctxt: SyntaxContext, -} - -/// A mark represents a unique id associated with a macro expansion. -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Default)] -pub struct Mark(u32); - -impl Mark { - pub fn fresh() -> Self { - HygieneData::with(|data| { - let next_mark = Mark(data.next_mark.0 + 1); - ::std::mem::replace(&mut data.next_mark, next_mark) - }) - } -} - -struct HygieneData { - syntax_contexts: Vec, - markings: HashMap<(SyntaxContext, Mark), SyntaxContext>, - next_mark: Mark, -} - -impl HygieneData { - fn new() -> Self { - HygieneData { - syntax_contexts: vec![SyntaxContextData { - outer_mark: Mark(0), // the null mark - prev_ctxt: SyntaxContext(0), // the empty context - }], - markings: HashMap::new(), - next_mark: Mark(1), - } - } - - fn with T>(f: F) -> T { - thread_local! { - static HYGIENE_DATA: RefCell = RefCell::new(HygieneData::new()); - } - HYGIENE_DATA.with(|data| f(&mut *data.borrow_mut())) - } -} - -pub fn reset_hygiene_data() { - HygieneData::with(|data| *data = HygieneData::new()) -} - -impl SyntaxContext { - pub const fn empty() -> Self { - SyntaxContext(0) - } - - pub fn data(self) -> SyntaxContextData { - HygieneData::with(|data| data.syntax_contexts[self.0 as usize]) - } - - /// Extend a syntax context with a given mark - pub fn apply_mark(self, mark: Mark) -> SyntaxContext { - // Applying the same mark twice is a no-op - let ctxt_data = self.data(); - if mark == ctxt_data.outer_mark { - return ctxt_data.prev_ctxt; - } - - HygieneData::with(|data| { - let syntax_contexts = &mut data.syntax_contexts; - *data.markings.entry((self, mark)).or_insert_with(|| { - syntax_contexts.push(SyntaxContextData { - outer_mark: mark, - prev_ctxt: self, - }); - SyntaxContext(syntax_contexts.len() as u32 - 1) - }) - }) - } - - /// If `ident` is macro expanded, return the source ident from the macro definition - /// and the mark of the expansion that created the macro definition. - pub fn source(self) -> (Self /* source context */, Mark /* source macro */) { - let macro_def_ctxt = self.data().prev_ctxt.data(); - (macro_def_ctxt.prev_ctxt, macro_def_ctxt.outer_mark) - } -} - -impl fmt::Debug for SyntaxContext { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "#{}", self.0) - } -} - -#[cfg(test)] -mod tests { - use ast::{EMPTY_CTXT, Mrk, SyntaxContext}; - use super::{apply_mark_internal, new_sctable_internal, Mark, SCTable}; - - // extend a syntax context with a sequence of marks given - // in a vector. v[0] will be the outermost mark. - fn unfold_marks(mrks: Vec , tail: SyntaxContext, table: &SCTable) - -> SyntaxContext { - mrks.iter().rev().fold(tail, |tail:SyntaxContext, mrk:&Mrk| - {apply_mark_internal(*mrk,tail,table)}) - } - - #[test] fn unfold_marks_test() { - let mut t = new_sctable_internal(); - - assert_eq!(unfold_marks(vec!(3,7),EMPTY_CTXT,&mut t),SyntaxContext(2)); - { - let table = t.table.borrow(); - assert!((*table)[1] == Mark(7,EMPTY_CTXT)); - assert!((*table)[2] == Mark(3,SyntaxContext(1))); - } - } - - #[test] - fn hashing_tests () { - let mut t = new_sctable_internal(); - assert_eq!(apply_mark_internal(12,EMPTY_CTXT,&mut t),SyntaxContext(1)); - assert_eq!(apply_mark_internal(13,EMPTY_CTXT,&mut t),SyntaxContext(2)); - // using the same one again should result in the same index: - assert_eq!(apply_mark_internal(12,EMPTY_CTXT,&mut t),SyntaxContext(1)); - // I'm assuming that the rename table will behave the same.... - } -} diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 8febf1c49ec..5ad17444188 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -127,7 +127,7 @@ pub mod ext { pub mod base; pub mod build; pub mod expand; - pub mod mtwt; + pub mod hygiene; pub mod quote; pub mod source_util; -- cgit 1.4.1-3-g733a5