diff options
| author | Corey Richardson <corey@octayn.net> | 2014-06-09 13:12:30 -0700 |
|---|---|---|
| committer | Corey Richardson <corey@octayn.net> | 2014-07-09 00:06:27 -0700 |
| commit | 4989a56448c7e3047e0538ff4ef54c49db8a5a4f (patch) | |
| tree | 99a15ab91675cd360008b542c3cde8a1f74d6f86 /src/libsyntax/ext | |
| parent | 5716abe3f019ab7d9c8cdde9879332040191cf88 (diff) | |
| download | rust-4989a56448c7e3047e0538ff4ef54c49db8a5a4f.tar.gz rust-4989a56448c7e3047e0538ff4ef54c49db8a5a4f.zip | |
syntax: doc comments all the things
Diffstat (limited to 'src/libsyntax/ext')
| -rw-r--r-- | src/libsyntax/ext/base.rs | 23 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/encodable.rs | 143 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/generic/mod.rs | 332 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/generic/ty.rs | 14 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/show.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 10 | ||||
| -rw-r--r-- | src/libsyntax/ext/format.rs | 16 | ||||
| -rw-r--r-- | src/libsyntax/ext/mtwt.rs | 52 | ||||
| -rw-r--r-- | src/libsyntax/ext/source_util.rs | 14 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/macro_parser.rs | 175 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/macro_rules.rs | 8 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/transcribe.rs | 12 |
12 files changed, 397 insertions, 406 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index a2a442f8b6a..bbf38fd7a9d 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -278,9 +278,9 @@ pub enum SyntaxExtension { pub type NamedSyntaxExtension = (Name, SyntaxExtension); pub struct BlockInfo { - // should macros escape from this scope? + /// Should macros escape from this scope? pub macros_escape: bool, - // what are the pending renames? + /// What are the pending renames? pub pending_renames: mtwt::RenameList, } @@ -293,8 +293,8 @@ impl BlockInfo { } } -// The base map of methods for expanding syntax extension -// AST nodes into full ASTs +/// The base map of methods for expanding syntax extension +/// AST nodes into full ASTs pub fn syntax_expander_table() -> SyntaxEnv { // utility function to simplify creating NormalTT syntax extensions fn builtin_normal_expander(f: MacroExpanderFn) -> SyntaxExtension { @@ -398,9 +398,9 @@ pub fn syntax_expander_table() -> SyntaxEnv { syntax_expanders } -// One of these is made during expansion and incrementally updated as we go; -// when a macro expansion occurs, the resulting nodes have the backtrace() -// -> expn_info of their expansion context stored into their span. +/// One of these is made during expansion and incrementally updated as we go; +/// when a macro expansion occurs, the resulting nodes have the backtrace() +/// -> expn_info of their expansion context stored into their span. pub struct ExtCtxt<'a> { pub parse_sess: &'a parse::ParseSess, pub cfg: ast::CrateConfig, @@ -612,11 +612,11 @@ pub fn get_exprs_from_tts(cx: &mut ExtCtxt, Some(es) } -// in order to have some notion of scoping for macros, -// we want to implement the notion of a transformation -// environment. +/// 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. +/// This environment maps Names to SyntaxExtensions. //impl question: how to implement it? Initially, the // env will contain only macros, so it might be painful @@ -633,7 +633,6 @@ struct MapChainFrame { map: HashMap<Name, SyntaxExtension>, } -// Only generic to make it easy to test pub struct SyntaxEnv { chain: Vec<MapChainFrame> , } diff --git a/src/libsyntax/ext/deriving/encodable.rs b/src/libsyntax/ext/deriving/encodable.rs index 652d593c004..3b34407edfe 100644 --- a/src/libsyntax/ext/deriving/encodable.rs +++ b/src/libsyntax/ext/deriving/encodable.rs @@ -8,79 +8,76 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -/*! - -The compiler code necessary to implement the `#[deriving(Encodable)]` -(and `Decodable`, in decodable.rs) extension. The idea here is that -type-defining items may be tagged with `#[deriving(Encodable, Decodable)]`. - -For example, a type like: - -```ignore -#[deriving(Encodable, Decodable)] -struct Node { id: uint } -``` - -would generate two implementations like: - -```ignore -impl<S:serialize::Encoder> Encodable<S> for Node { - fn encode(&self, s: &S) { - s.emit_struct("Node", 1, || { - s.emit_field("id", 0, || s.emit_uint(self.id)) - }) - } -} - -impl<D:Decoder> Decodable for node_id { - fn decode(d: &D) -> Node { - d.read_struct("Node", 1, || { - Node { - id: d.read_field("x".to_string(), 0, || decode(d)) - } - }) - } -} -``` - -Other interesting scenarios are whe the item has type parameters or -references other non-built-in types. A type definition like: - -```ignore -#[deriving(Encodable, Decodable)] -struct spanned<T> { node: T, span: Span } -``` - -would yield functions like: - -```ignore - impl< - S: Encoder, - T: Encodable<S> - > spanned<T>: Encodable<S> { - fn encode<S:Encoder>(s: &S) { - s.emit_rec(|| { - s.emit_field("node", 0, || self.node.encode(s)); - s.emit_field("span", 1, || self.span.encode(s)); - }) - } - } - - impl< - D: Decoder, - T: Decodable<D> - > spanned<T>: Decodable<D> { - fn decode(d: &D) -> spanned<T> { - d.read_rec(|| { - { - node: d.read_field("node".to_string(), 0, || decode(d)), - span: d.read_field("span".to_string(), 1, || decode(d)), - } - }) - } - } -``` -*/ +//! The compiler code necessary to implement the `#[deriving(Encodable)]` +//! (and `Decodable`, in decodable.rs) extension. The idea here is that +//! type-defining items may be tagged with `#[deriving(Encodable, Decodable)]`. +//! +//! For example, a type like: +//! +//! ```ignore +//! #[deriving(Encodable, Decodable)] +//! struct Node { id: uint } +//! ``` +//! +//! would generate two implementations like: +//! +//! ```ignore +//! impl<S:serialize::Encoder> Encodable<S> for Node { +//! fn encode(&self, s: &S) { +//! s.emit_struct("Node", 1, || { +//! s.emit_field("id", 0, || s.emit_uint(self.id)) +//! }) +//! } +//! } +//! +//! impl<D:Decoder> Decodable for node_id { +//! fn decode(d: &D) -> Node { +//! d.read_struct("Node", 1, || { +//! Node { +//! id: d.read_field("x".to_string(), 0, || decode(d)) +//! } +//! }) +//! } +//! } +//! ``` +//! +//! Other interesting scenarios are whe the item has type parameters or +//! references other non-built-in types. A type definition like: +//! +//! ```ignore +//! #[deriving(Encodable, Decodable)] +//! struct spanned<T> { node: T, span: Span } +//! ``` +//! +//! would yield functions like: +//! +//! ```ignore +//! impl< +//! S: Encoder, +//! T: Encodable<S> +//! > spanned<T>: Encodable<S> { +//! fn encode<S:Encoder>(s: &S) { +//! s.emit_rec(|| { +//! s.emit_field("node", 0, || self.node.encode(s)); +//! s.emit_field("span", 1, || self.span.encode(s)); +//! }) +//! } +//! } +//! +//! impl< +//! D: Decoder, +//! T: Decodable<D> +//! > spanned<T>: Decodable<D> { +//! fn decode(d: &D) -> spanned<T> { +//! d.read_rec(|| { +//! { +//! node: d.read_field("node".to_string(), 0, || decode(d)), +//! span: d.read_field("span".to_string(), 1, || decode(d)), +//! } +//! }) +//! } +//! } +//! ``` use ast::{MetaItem, Item, Expr, ExprRet, MutMutable, LitNil}; use codemap::Span; diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs index 764c88cc954..c9f5936a9bb 100644 --- a/src/libsyntax/ext/deriving/generic/mod.rs +++ b/src/libsyntax/ext/deriving/generic/mod.rs @@ -8,174 +8,170 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -/*! - -Some code that abstracts away much of the boilerplate of writing -`deriving` instances for traits. Among other things it manages getting -access to the fields of the 4 different sorts of structs and enum -variants, as well as creating the method and impl ast instances. - -Supported features (fairly exhaustive): - -- Methods taking any number of parameters of any type, and returning - any type, other than vectors, bottom and closures. -- Generating `impl`s for types with type parameters and lifetimes - (e.g. `Option<T>`), the parameters are automatically given the - current trait as a bound. (This includes separate type parameters - and lifetimes for methods.) -- Additional bounds on the type parameters, e.g. the `Ord` instance - requires an explicit `PartialEq` bound at the - moment. (`TraitDef.additional_bounds`) - -Unsupported: FIXME #6257: calling methods on reference fields, -e.g. deriving Eq/Ord/Clone don't work on `struct A(&int)`, -because of how the auto-dereferencing happens. - -The most important thing for implementers is the `Substructure` and -`SubstructureFields` objects. The latter groups 5 possibilities of the -arguments: - -- `Struct`, when `Self` is a struct (including tuple structs, e.g - `struct T(int, char)`). -- `EnumMatching`, when `Self` is an enum and all the arguments are the - same variant of the enum (e.g. `Some(1)`, `Some(3)` and `Some(4)`) -- `EnumNonMatching` when `Self` is an enum and the arguments are not - the same variant (e.g. `None`, `Some(1)` and `None`). If - `const_nonmatching` is true, this will contain an empty list. -- `StaticEnum` and `StaticStruct` for static methods, where the type - being derived upon is either an enum or struct respectively. (Any - argument with type Self is just grouped among the non-self - arguments.) - -In the first two cases, the values from the corresponding fields in -all the arguments are grouped together. In the `EnumNonMatching` case -this isn't possible (different variants have different fields), so the -fields are grouped by which argument they come from. There are no -fields with values in the static cases, so these are treated entirely -differently. - -The non-static cases have `Option<ident>` in several places associated -with field `expr`s. This represents the name of the field it is -associated with. It is only not `None` when the associated field has -an identifier in the source code. For example, the `x`s in the -following snippet - -```rust -struct A { x : int } - -struct B(int); - -enum C { - C0(int), - C1 { x: int } -} -``` - -The `int`s in `B` and `C0` don't have an identifier, so the -`Option<ident>`s would be `None` for them. - -In the static cases, the structure is summarised, either into the just -spans of the fields or a list of spans and the field idents (for tuple -structs and record structs, respectively), or a list of these, for -enums (one for each variant). For empty struct and empty enum -variants, it is represented as a count of 0. - -# Examples - -The following simplified `PartialEq` is used for in-code examples: - -```rust -trait PartialEq { - fn eq(&self, other: &Self); -} -impl PartialEq for int { - fn eq(&self, other: &int) -> bool { - *self == *other - } -} -``` - -Some examples of the values of `SubstructureFields` follow, using the -above `PartialEq`, `A`, `B` and `C`. - -## Structs - -When generating the `expr` for the `A` impl, the `SubstructureFields` is - -~~~text -Struct(~[FieldInfo { - span: <span of x> - name: Some(<ident of x>), - self_: <expr for &self.x>, - other: ~[<expr for &other.x] - }]) -~~~ - -For the `B` impl, called with `B(a)` and `B(b)`, - -~~~text -Struct(~[FieldInfo { - span: <span of `int`>, - name: None, - <expr for &a> - ~[<expr for &b>] - }]) -~~~ - -## Enums - -When generating the `expr` for a call with `self == C0(a)` and `other -== C0(b)`, the SubstructureFields is - -~~~text -EnumMatching(0, <ast::Variant for C0>, - ~[FieldInfo { - span: <span of int> - name: None, - self_: <expr for &a>, - other: ~[<expr for &b>] - }]) -~~~ - -For `C1 {x}` and `C1 {x}`, - -~~~text -EnumMatching(1, <ast::Variant for C1>, - ~[FieldInfo { - span: <span of x> - name: Some(<ident of x>), - self_: <expr for &self.x>, - other: ~[<expr for &other.x>] - }]) -~~~ - -For `C0(a)` and `C1 {x}` , - -~~~text -EnumNonMatching(~[(0, <ast::Variant for B0>, - ~[(<span of int>, None, <expr for &a>)]), - (1, <ast::Variant for B1>, - ~[(<span of x>, Some(<ident of x>), - <expr for &other.x>)])]) -~~~ - -(and vice versa, but with the order of the outermost list flipped.) - -## Static - -A static method on the above would result in, - -~~~text -StaticStruct(<ast::StructDef of A>, Named(~[(<ident of x>, <span of x>)])) - -StaticStruct(<ast::StructDef of B>, Unnamed(~[<span of x>])) - -StaticEnum(<ast::EnumDef of C>, ~[(<ident of C0>, <span of C0>, Unnamed(~[<span of int>])), - (<ident of C1>, <span of C1>, - Named(~[(<ident of x>, <span of x>)]))]) -~~~ - -*/ +//! Some code that abstracts away much of the boilerplate of writing +//! `deriving` instances for traits. Among other things it manages getting +//! access to the fields of the 4 different sorts of structs and enum +//! variants, as well as creating the method and impl ast instances. +//! +//! Supported features (fairly exhaustive): +//! +//! - Methods taking any number of parameters of any type, and returning +//! any type, other than vectors, bottom and closures. +//! - Generating `impl`s for types with type parameters and lifetimes +//! (e.g. `Option<T>`), the parameters are automatically given the +//! current trait as a bound. (This includes separate type parameters +//! and lifetimes for methods.) +//! - Additional bounds on the type parameters, e.g. the `Ord` instance +//! requires an explicit `PartialEq` bound at the +//! moment. (`TraitDef.additional_bounds`) +//! +//! Unsupported: FIXME #6257: calling methods on reference fields, +//! e.g. deriving Eq/Ord/Clone don't work on `struct A(&int)`, +//! because of how the auto-dereferencing happens. +//! +//! The most important thing for implementers is the `Substructure` and +//! `SubstructureFields` objects. The latter groups 5 possibilities of the +//! arguments: +//! +//! - `Struct`, when `Self` is a struct (including tuple structs, e.g +//! `struct T(int, char)`). +//! - `EnumMatching`, when `Self` is an enum and all the arguments are the +//! same variant of the enum (e.g. `Some(1)`, `Some(3)` and `Some(4)`) +//! - `EnumNonMatching` when `Self` is an enum and the arguments are not +//! the same variant (e.g. `None`, `Some(1)` and `None`). If +//! `const_nonmatching` is true, this will contain an empty list. +//! - `StaticEnum` and `StaticStruct` for static methods, where the type +//! being derived upon is either an enum or struct respectively. (Any +//! argument with type Self is just grouped among the non-self +//! arguments.) +//! +//! In the first two cases, the values from the corresponding fields in +//! all the arguments are grouped together. In the `EnumNonMatching` case +//! this isn't possible (different variants have different fields), so the +//! fields are grouped by which argument they come from. There are no +//! fields with values in the static cases, so these are treated entirely +//! differently. +//! +//! The non-static cases have `Option<ident>` in several places associated +//! with field `expr`s. This represents the name of the field it is +//! associated with. It is only not `None` when the associated field has +//! an identifier in the source code. For example, the `x`s in the +//! following snippet +//! +//! ```rust +//! struct A { x : int } +//! +//! struct B(int); +//! +//! enum C { +//! C0(int), +//! C1 { x: int } +//! } +//! ``` +//! +//! The `int`s in `B` and `C0` don't have an identifier, so the +//! `Option<ident>`s would be `None` for them. +//! +//! In the static cases, the structure is summarised, either into the just +//! spans of the fields or a list of spans and the field idents (for tuple +//! structs and record structs, respectively), or a list of these, for +//! enums (one for each variant). For empty struct and empty enum +//! variants, it is represented as a count of 0. +//! +//! # Examples +//! +//! The following simplified `PartialEq` is used for in-code examples: +//! +//! ```rust +//! trait PartialEq { +//! fn eq(&self, other: &Self); +//! } +//! impl PartialEq for int { +//! fn eq(&self, other: &int) -> bool { +//! *self == *other +//! } +//! } +//! ``` +//! +//! Some examples of the values of `SubstructureFields` follow, using the +//! above `PartialEq`, `A`, `B` and `C`. +//! +//! ## Structs +//! +//! When generating the `expr` for the `A` impl, the `SubstructureFields` is +//! +//! ~~~text +//! Struct(~[FieldInfo { +//! span: <span of x> +//! name: Some(<ident of x>), +//! self_: <expr for &self.x>, +//! other: ~[<expr for &other.x] +//! }]) +//! ~~~ +//! +//! For the `B` impl, called with `B(a)` and `B(b)`, +//! +//! ~~~text +//! Struct(~[FieldInfo { +//! span: <span of `int`>, +//! name: None, +//! <expr for &a> +//! ~[<expr for &b>] +//! }]) +//! ~~~ +//! +//! ## Enums +//! +//! When generating the `expr` for a call with `self == C0(a)` and `other +//! == C0(b)`, the SubstructureFields is +//! +//! ~~~text +//! EnumMatching(0, <ast::Variant for C0>, +//! ~[FieldInfo { +//! span: <span of int> +//! name: None, +//! self_: <expr for &a>, +//! other: ~[<expr for &b>] +//! }]) +//! ~~~ +//! +//! For `C1 {x}` and `C1 {x}`, +//! +//! ~~~text +//! EnumMatching(1, <ast::Variant for C1>, +//! ~[FieldInfo { +//! span: <span of x> +//! name: Some(<ident of x>), +//! self_: <expr for &self.x>, +//! other: ~[<expr for &other.x>] +//! }]) +//! ~~~ +//! +//! For `C0(a)` and `C1 {x}` , +//! +//! ~~~text +//! EnumNonMatching(~[(0, <ast::Variant for B0>, +//! ~[(<span of int>, None, <expr for &a>)]), +//! (1, <ast::Variant for B1>, +//! ~[(<span of x>, Some(<ident of x>), +//! <expr for &other.x>)])]) +//! ~~~ +//! +//! (and vice versa, but with the order of the outermost list flipped.) +//! +//! ## Static +//! +//! A static method on the above would result in, +//! +//! ~~~text +//! StaticStruct(<ast::StructDef of A>, Named(~[(<ident of x>, <span of x>)])) +//! +//! StaticStruct(<ast::StructDef of B>, Unnamed(~[<span of x>])) +//! +//! StaticEnum(<ast::EnumDef of C>, ~[(<ident of C0>, <span of C0>, Unnamed(~[<span of int>])), +//! (<ident of C1>, <span of C1>, +//! Named(~[(<ident of x>, <span of x>)]))]) +//! ~~~ use std::cell::RefCell; use std::gc::{Gc, GC}; diff --git a/src/libsyntax/ext/deriving/generic/ty.rs b/src/libsyntax/ext/deriving/generic/ty.rs index b53281f9963..f6a39d7b2e6 100644 --- a/src/libsyntax/ext/deriving/generic/ty.rs +++ b/src/libsyntax/ext/deriving/generic/ty.rs @@ -25,8 +25,10 @@ use std::gc::Gc; /// The types of pointers pub enum PtrTy<'a> { - Send, // ~ - Borrowed(Option<&'a str>, ast::Mutability), // &['lifetime] [mut] + /// ~ + Send, + /// &'lifetime mut + Borrowed(Option<&'a str>, ast::Mutability), } /// A path, e.g. `::std::option::Option::<int>` (global). Has support @@ -83,12 +85,12 @@ impl<'a> Path<'a> { /// A type. Supports pointers (except for *), Self, and literals pub enum Ty<'a> { Self, - // &/Box/ Ty + /// &/Box/ Ty Ptr(Box<Ty<'a>>, PtrTy<'a>), - // mod::mod::Type<[lifetime], [Params...]>, including a plain type - // parameter, and things like `int` + /// mod::mod::Type<[lifetime], [Params...]>, including a plain type + /// parameter, and things like `int` Literal(Path<'a>), - // includes nil + /// includes unit Tuple(Vec<Ty<'a>> ) } diff --git a/src/libsyntax/ext/deriving/show.rs b/src/libsyntax/ext/deriving/show.rs index 8e673ff2465..05b5131d7e4 100644 --- a/src/libsyntax/ext/deriving/show.rs +++ b/src/libsyntax/ext/deriving/show.rs @@ -55,8 +55,8 @@ pub fn expand_deriving_show(cx: &mut ExtCtxt, trait_def.expand(cx, mitem, item, push) } -// we construct a format string and then defer to std::fmt, since that -// knows what's up with formatting at so on. +/// We construct a format string and then defer to std::fmt, since that +/// knows what's up with formatting and so on. fn show_substructure(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> Gc<Expr> { // build `<name>`, `<name>({}, {}, ...)` or `<name> { <field>: {}, diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 9fe431cfb6c..a095317f663 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -246,11 +246,11 @@ pub fn expand_expr(e: Gc<ast::Expr>, fld: &mut MacroExpander) -> Gc<ast::Expr> { } } -// Rename loop label and expand its loop body -// -// The renaming procedure for loop is different in the sense that the loop -// body is in a block enclosed by loop head so the renaming of loop label -// must be propagated to the enclosed context. +/// Rename loop label and expand its loop body +/// +/// The renaming procedure for loop is different in the sense that the loop +/// body is in a block enclosed by loop head so the renaming of loop label +/// must be propagated to the enclosed context. fn expand_loop_block(loop_block: P<Block>, opt_ident: Option<Ident>, fld: &mut MacroExpander) -> (P<Block>, Option<Ident>) { diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs index f486d2de339..786fd953f89 100644 --- a/src/libsyntax/ext/format.rs +++ b/src/libsyntax/ext/format.rs @@ -37,24 +37,24 @@ struct Context<'a, 'b> { ecx: &'a mut ExtCtxt<'b>, fmtsp: Span, - // Parsed argument expressions and the types that we've found so far for - // them. + /// Parsed argument expressions and the types that we've found so far for + /// them. args: Vec<Gc<ast::Expr>>, arg_types: Vec<Option<ArgumentType>>, - // Parsed named expressions and the types that we've found for them so far. - // Note that we keep a side-array of the ordering of the named arguments - // found to be sure that we can translate them in the same order that they - // were declared in. + /// Parsed named expressions and the types that we've found for them so far. + /// Note that we keep a side-array of the ordering of the named arguments + /// found to be sure that we can translate them in the same order that they + /// were declared in. names: HashMap<String, Gc<ast::Expr>>, name_types: HashMap<String, ArgumentType>, name_ordering: Vec<String>, - // Collection of the compiled `rt::Piece` structures + /// Collection of the compiled `rt::Piece` structures pieces: Vec<Gc<ast::Expr>>, name_positions: HashMap<String, uint>, method_statics: Vec<Gc<ast::Item>>, - // Updated as arguments are consumed or methods are entered + /// Updated as arguments are consumed or methods are entered nest_level: uint, next_arg: uint, } diff --git a/src/libsyntax/ext/mtwt.rs b/src/libsyntax/ext/mtwt.rs index 18466e381a5..8608f7fb545 100644 --- a/src/libsyntax/ext/mtwt.rs +++ b/src/libsyntax/ext/mtwt.rs @@ -21,16 +21,16 @@ use std::cell::RefCell; use std::rc::Rc; use std::collections::HashMap; -// the SCTable contains a table of SyntaxContext_'s. It -// represents a flattened tree structure, to avoid having -// managed pointers everywhere (that caused an ICE). -// the mark_memo and rename_memo fields are side-tables -// that ensure that adding the same mark to the same context -// gives you back the same context as before. This shouldn't -// change the semantics--everything here is immutable--but -// it should cut down on memory use *a lot*; applying a mark -// to a tree containing 50 identifiers would otherwise generate -// 50 new contexts +/// The SCTable contains a table of SyntaxContext_'s. It +/// represents a flattened tree structure, to avoid having +/// managed pointers everywhere (that caused an ICE). +/// the mark_memo and rename_memo fields are side-tables +/// that ensure that adding the same mark to the same context +/// gives you back the same context as before. This shouldn't +/// change the semantics--everything here is immutable--but +/// it should cut down on memory use *a lot*; applying a mark +/// to a tree containing 50 identifiers would otherwise generate +/// 50 new contexts pub struct SCTable { table: RefCell<Vec<SyntaxContext_>>, mark_memo: RefCell<HashMap<(SyntaxContext,Mrk),SyntaxContext>>, @@ -41,16 +41,16 @@ pub struct SCTable { pub enum SyntaxContext_ { EmptyCtxt, Mark (Mrk,SyntaxContext), - // flattening the name and syntaxcontext into the rename... - // HIDDEN INVARIANTS: - // 1) the first name in a Rename node - // can only be a programmer-supplied name. - // 2) Every Rename node with a given Name in the - // "to" slot must have the same name and context - // in the "from" slot. In essence, they're all - // pointers to a single "rename" event node. + /// flattening the name and syntaxcontext into the rename... + /// HIDDEN INVARIANTS: + /// 1) the first name in a Rename node + /// can only be a programmer-supplied name. + /// 2) Every Rename node with a given Name in the + /// "to" slot must have the same name and context + /// in the "from" slot. In essence, they're all + /// pointers to a single "rename" event node. Rename (Ident,Name,SyntaxContext), - // actually, IllegalCtxt may not be necessary. + /// actually, IllegalCtxt may not be necessary. IllegalCtxt } @@ -62,7 +62,7 @@ pub fn apply_mark(m: Mrk, ctxt: SyntaxContext) -> SyntaxContext { with_sctable(|table| apply_mark_internal(m, ctxt, table)) } -// Extend a syntax context with a given mark and sctable (explicit memoization) +/// Extend a syntax context with a given mark and sctable (explicit memoization) fn apply_mark_internal(m: Mrk, ctxt: SyntaxContext, table: &SCTable) -> SyntaxContext { let key = (ctxt, m); let new_ctxt = |_: &(SyntaxContext, Mrk)| @@ -77,7 +77,7 @@ pub fn apply_rename(id: Ident, to:Name, with_sctable(|table| apply_rename_internal(id, to, ctxt, table)) } -// Extend a syntax context with a given rename and sctable (explicit memoization) +/// Extend a syntax context with a given rename and sctable (explicit memoization) fn apply_rename_internal(id: Ident, to: Name, ctxt: SyntaxContext, @@ -141,7 +141,7 @@ pub fn clear_tables() { with_resolve_table_mut(|table| *table = HashMap::new()); } -// Add a value to the end of a vec, return its index +/// Add a value to the end of a vec, return its index fn idx_push<T>(vec: &mut Vec<T> , val: T) -> u32 { vec.push(val); (vec.len() - 1) as u32 @@ -173,8 +173,8 @@ fn with_resolve_table_mut<T>(op: |&mut ResolveTable| -> T) -> T { } } -// Resolve a syntax object to a name, per MTWT. -// adding memoization to resolve 500+ seconds in resolve for librustc (!) +/// Resolve a syntax object to a name, per MTWT. +/// adding memoization to resolve 500+ seconds in resolve for librustc (!) fn resolve_internal(id: Ident, table: &SCTable, resolve_table: &mut ResolveTable) -> Name { @@ -264,8 +264,8 @@ pub fn outer_mark(ctxt: SyntaxContext) -> Mrk { }) } -// Push a name... unless it matches the one on top, in which -// case pop and discard (so two of the same marks cancel) +/// Push a name... unless it matches the one on top, in which +/// case pop and discard (so two of the same marks cancel) fn xor_push(marks: &mut Vec<Mrk>, mark: Mrk) { if (marks.len() > 0) && (*marks.last().unwrap() == mark) { marks.pop().unwrap(); diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index 8922f423aad..5ac9dc86fce 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -28,7 +28,7 @@ use std::str; // the column/row/filename of the expression, or they include // a given file into the current one. -/* line!(): expands to the current line number */ +/// line!(): expands to the current line number pub fn expand_line(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) -> Box<base::MacResult> { base::check_zero_tts(cx, sp, tts, "line!"); @@ -49,9 +49,9 @@ pub fn expand_col(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) base::MacExpr::new(cx.expr_uint(topmost.call_site, loc.col.to_uint())) } -/* file!(): expands to the current filename */ -/* The filemap (`loc.file`) contains a bunch more information we could spit - * out if we wanted. */ +/// file!(): expands to the current filename */ +/// The filemap (`loc.file`) contains a bunch more information we could spit +/// out if we wanted. pub fn expand_file(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) -> Box<base::MacResult> { base::check_zero_tts(cx, sp, tts, "file!"); @@ -82,9 +82,9 @@ pub fn expand_mod(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) token::intern_and_get_ident(string.as_slice()))) } -// include! : parse the given file as an expr -// This is generally a bad idea because it's going to behave -// unhygienically. +/// include! : parse the given file as an expr +/// This is generally a bad idea because it's going to behave +/// unhygienically. pub fn expand_include(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) -> Box<base::MacResult> { let file = match get_single_str_from_tts(cx, sp, tts, "include!") { diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index b30ede70f0e..bdf1f6eb600 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -8,7 +8,72 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// Earley-like parser for macros. +//! This is an Earley-like parser, without support for in-grammar nonterminals, +//! only by calling out to the main rust parser for named nonterminals (which it +//! commits to fully when it hits one in a grammar). This means that there are no +//! completer or predictor rules, and therefore no need to store one column per +//! token: instead, there's a set of current Earley items and a set of next +//! ones. Instead of NTs, we have a special case for Kleene star. The big-O, in +//! pathological cases, is worse than traditional Earley parsing, but it's an +//! easier fit for Macro-by-Example-style rules, and I think the overhead is +//! lower. (In order to prevent the pathological case, we'd need to lazily +//! construct the resulting `NamedMatch`es at the very end. It'd be a pain, +//! and require more memory to keep around old items, but it would also save +//! overhead) +//! +//! Quick intro to how the parser works: +//! +//! A 'position' is a dot in the middle of a matcher, usually represented as a +//! dot. For example `· a $( a )* a b` is a position, as is `a $( · a )* a b`. +//! +//! The parser walks through the input a character at a time, maintaining a list +//! of items consistent with the current position in the input string: `cur_eis`. +//! +//! As it processes them, it fills up `eof_eis` with items that would be valid if +//! the macro invocation is now over, `bb_eis` with items that are waiting on +//! a Rust nonterminal like `$e:expr`, and `next_eis` with items that are waiting +//! on the a particular token. Most of the logic concerns moving the · through the +//! repetitions indicated by Kleene stars. It only advances or calls out to the +//! real Rust parser when no `cur_eis` items remain +//! +//! Example: Start parsing `a a a a b` against [· a $( a )* a b]. +//! +//! Remaining input: `a a a a b` +//! next_eis: [· a $( a )* a b] +//! +//! - - - Advance over an `a`. - - - +//! +//! Remaining input: `a a a b` +//! cur: [a · $( a )* a b] +//! Descend/Skip (first item). +//! next: [a $( · a )* a b] [a $( a )* · a b]. +//! +//! - - - Advance over an `a`. - - - +//! +//! Remaining input: `a a b` +//! cur: [a $( a · )* a b] next: [a $( a )* a · b] +//! Finish/Repeat (first item) +//! next: [a $( a )* · a b] [a $( · a )* a b] [a $( a )* a · b] +//! +//! - - - Advance over an `a`. - - - (this looks exactly like the last step) +//! +//! Remaining input: `a b` +//! cur: [a $( a · )* a b] next: [a $( a )* a · b] +//! Finish/Repeat (first item) +//! next: [a $( a )* · a b] [a $( · a )* a b] [a $( a )* a · b] +//! +//! - - - Advance over an `a`. - - - (this looks exactly like the last step) +//! +//! Remaining input: `b` +//! cur: [a $( a · )* a b] next: [a $( a )* a · b] +//! Finish/Repeat (first item) +//! next: [a $( a )* · a b] [a $( · a )* a b] +//! +//! - - - Advance over a `b`. - - - +//! +//! Remaining input: `` +//! eof: [a $( a )* a b ·] + use ast; use ast::{Matcher, MatchTok, MatchSeq, MatchNonterminal, Ident}; @@ -25,75 +90,6 @@ use std::rc::Rc; use std::gc::GC; use std::collections::HashMap; -/* This is an Earley-like parser, without support for in-grammar nonterminals, -only by calling out to the main rust parser for named nonterminals (which it -commits to fully when it hits one in a grammar). This means that there are no -completer or predictor rules, and therefore no need to store one column per -token: instead, there's a set of current Earley items and a set of next -ones. Instead of NTs, we have a special case for Kleene star. The big-O, in -pathological cases, is worse than traditional Earley parsing, but it's an -easier fit for Macro-by-Example-style rules, and I think the overhead is -lower. (In order to prevent the pathological case, we'd need to lazily -construct the resulting `NamedMatch`es at the very end. It'd be a pain, -and require more memory to keep around old items, but it would also save -overhead)*/ - -/* Quick intro to how the parser works: - -A 'position' is a dot in the middle of a matcher, usually represented as a -dot. For example `· a $( a )* a b` is a position, as is `a $( · a )* a b`. - -The parser walks through the input a character at a time, maintaining a list -of items consistent with the current position in the input string: `cur_eis`. - -As it processes them, it fills up `eof_eis` with items that would be valid if -the macro invocation is now over, `bb_eis` with items that are waiting on -a Rust nonterminal like `$e:expr`, and `next_eis` with items that are waiting -on the a particular token. Most of the logic concerns moving the · through the -repetitions indicated by Kleene stars. It only advances or calls out to the -real Rust parser when no `cur_eis` items remain - -Example: Start parsing `a a a a b` against [· a $( a )* a b]. - -Remaining input: `a a a a b` -next_eis: [· a $( a )* a b] - -- - - Advance over an `a`. - - - - -Remaining input: `a a a b` -cur: [a · $( a )* a b] -Descend/Skip (first item). -next: [a $( · a )* a b] [a $( a )* · a b]. - -- - - Advance over an `a`. - - - - -Remaining input: `a a b` -cur: [a $( a · )* a b] next: [a $( a )* a · b] -Finish/Repeat (first item) -next: [a $( a )* · a b] [a $( · a )* a b] [a $( a )* a · b] - -- - - Advance over an `a`. - - - (this looks exactly like the last step) - -Remaining input: `a b` -cur: [a $( a · )* a b] next: [a $( a )* a · b] -Finish/Repeat (first item) -next: [a $( a )* · a b] [a $( · a )* a b] [a $( a )* a · b] - -- - - Advance over an `a`. - - - (this looks exactly like the last step) - -Remaining input: `b` -cur: [a $( a · )* a b] next: [a $( a )* a · b] -Finish/Repeat (first item) -next: [a $( a )* · a b] [a $( · a )* a b] - -- - - Advance over a `b`. - - - - -Remaining input: `` -eof: [a $( a )* a b ·] - - */ - - /* to avoid costly uniqueness checks, we require that `MatchSeq` always has a nonempty body. */ @@ -147,24 +143,24 @@ pub fn initial_matcher_pos(ms: Vec<Matcher> , sep: Option<Token>, lo: BytePos) } } -// NamedMatch is a pattern-match result for a single ast::MatchNonterminal: -// so it is associated with a single ident in a parse, and all -// MatchedNonterminal's in the NamedMatch have the same nonterminal type -// (expr, item, etc). All the leaves in a single NamedMatch correspond to a -// single matcher_nonterminal in the ast::Matcher that produced it. -// -// It should probably be renamed, it has more or less exact correspondence to -// ast::match nodes, and the in-memory structure of a particular NamedMatch -// represents the match that occurred when a particular subset of an -// ast::match -- those ast::Matcher nodes leading to a single -// MatchNonterminal -- was applied to a particular token tree. -// -// The width of each MatchedSeq in the NamedMatch, and the identity of the -// MatchedNonterminal's, will depend on the token tree it was applied to: each -// MatchedSeq corresponds to a single MatchSeq in the originating -// ast::Matcher. The depth of the NamedMatch structure will therefore depend -// only on the nesting depth of ast::MatchSeq's in the originating -// ast::Matcher it was derived from. +/// NamedMatch is a pattern-match result for a single ast::MatchNonterminal: +/// so it is associated with a single ident in a parse, and all +/// MatchedNonterminal's in the NamedMatch have the same nonterminal type +/// (expr, item, etc). All the leaves in a single NamedMatch correspond to a +/// single matcher_nonterminal in the ast::Matcher that produced it. +/// +/// It should probably be renamed, it has more or less exact correspondence to +/// ast::match nodes, and the in-memory structure of a particular NamedMatch +/// represents the match that occurred when a particular subset of an +/// ast::match -- those ast::Matcher nodes leading to a single +/// MatchNonterminal -- was applied to a particular token tree. +/// +/// The width of each MatchedSeq in the NamedMatch, and the identity of the +/// MatchedNonterminal's, will depend on the token tree it was applied to: each +/// MatchedSeq corresponds to a single MatchSeq in the originating +/// ast::Matcher. The depth of the NamedMatch structure will therefore depend +/// only on the nesting depth of ast::MatchSeq's in the originating +/// ast::Matcher it was derived from. pub enum NamedMatch { MatchedSeq(Vec<Rc<NamedMatch>>, codemap::Span), @@ -224,7 +220,8 @@ pub fn parse_or_else(sess: &ParseSess, } } -// perform a token equality check, ignoring syntax context (that is, an unhygienic comparison) +/// Perform a token equality check, ignoring syntax context (that is, an +/// unhygienic comparison) pub fn token_name_eq(t1 : &Token, t2 : &Token) -> bool { match (t1,t2) { (&token::IDENT(id1,_),&token::IDENT(id2,_)) diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 2b481cb0596..249e9305150 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -119,7 +119,7 @@ impl MacResult for MacroRulesDefiner { } } -// Given `lhses` and `rhses`, this is the new macro we create +/// Given `lhses` and `rhses`, this is the new macro we create fn generic_extension(cx: &ExtCtxt, sp: Span, name: Ident, @@ -193,9 +193,9 @@ fn generic_extension(cx: &ExtCtxt, cx.span_fatal(best_fail_spot, best_fail_msg.as_slice()); } -// this procedure performs the expansion of the -// macro_rules! macro. It parses the RHS and adds -// an extension to the current context. +/// This procedure performs the expansion of the +/// macro_rules! macro. It parses the RHS and adds +/// an extension to the current context. pub fn add_new_extension(cx: &mut ExtCtxt, sp: Span, name: Ident, diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index c0c066fe466..726a7315f69 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -32,7 +32,7 @@ struct TtFrame { #[deriving(Clone)] pub struct TtReader<'a> { pub sp_diag: &'a SpanHandler, - // the unzipped tree: + /// the unzipped tree: stack: Vec<TtFrame>, /* for MBE-style macro transcription */ interpolations: HashMap<Ident, Rc<NamedMatch>>, @@ -43,9 +43,9 @@ pub struct TtReader<'a> { pub cur_span: Span, } -/** This can do Macro-By-Example transcription. On the other hand, if - * `src` contains no `TTSeq`s and `TTNonterminal`s, `interp` can (and - * should) be none. */ +/// This can do Macro-By-Example transcription. On the other hand, if +/// `src` contains no `TTSeq`s and `TTNonterminal`s, `interp` can (and +/// should) be none. pub fn new_tt_reader<'a>(sp_diag: &'a SpanHandler, interp: Option<HashMap<Ident, Rc<NamedMatch>>>, src: Vec<ast::TokenTree> ) @@ -138,8 +138,8 @@ fn lockstep_iter_size(t: &TokenTree, r: &TtReader) -> LockstepIterSize { } } -// return the next token from the TtReader. -// EFFECT: advances the reader's token field +/// Return the next token from the TtReader. +/// EFFECT: advances the reader's token field pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan { // FIXME(pcwalton): Bad copy? let ret_val = TokenAndSpan { |
