From 42afb27cef5540535420fb6d8d9d2fcda7300a47 Mon Sep 17 00:00:00 2001 From: Martin Haug Date: Mon, 1 Nov 2021 13:45:33 +0100 Subject: [PATCH] Add documentation --- src/parse/parser.rs | 29 +++++++++++++++++++++--- src/syntax/mod.rs | 55 ++++++++++++++++++++++++++++++++++++--------- 2 files changed, 71 insertions(+), 13 deletions(-) diff --git a/src/parse/parser.rs b/src/parse/parser.rs index 374e7c09f..8c68d6308 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -112,10 +112,14 @@ impl<'s> Parser<'s> { } } + /// Return the a child from the current stack frame specified by its + /// non-trivia index from the back. pub fn child(&self, child: usize) -> Option<&Green> { self.node_index_from_back(child).map(|i| &self.children[i]) } + /// Map a non-trivia index from the back of the current stack frame to a + /// normal index. fn node_index_from_back(&self, child: usize) -> Option { let len = self.children.len(); let code = self.tokens.mode() == TokenMode::Code; @@ -172,6 +176,8 @@ impl<'s> Parser<'s> { (stack_offset, diff) } + /// Wrap a specified node in the current stack frame (indexed from the back, + /// not including trivia). pub fn wrap(&mut self, index: usize, kind: NodeKind) { let index = self.node_index_from_back(index).unwrap(); let child = std::mem::take(&mut self.children[index]); @@ -179,6 +185,7 @@ impl<'s> Parser<'s> { self.children[index] = item.into(); } + /// Eat and wrap the next token. pub fn convert(&mut self, kind: NodeKind) { let len = self.tokens.index() - self.next_start; @@ -194,9 +201,11 @@ impl<'s> Parser<'s> { self.success = true; } - pub fn convert_with(&mut self, preserve: usize, kind: NodeKind) { + /// Wrap the last `amount` children in the current stack frame with a new + /// node. + pub fn convert_with(&mut self, amount: usize, kind: NodeKind) { let preserved: Vec<_> = - self.children.drain(self.children.len() - preserve ..).collect(); + self.children.drain(self.children.len() - amount ..).collect(); let len = preserved.iter().map(|c| c.len()).sum(); self.children .push(GreenNode::with_children(kind, len, preserved).into()); @@ -219,6 +228,8 @@ impl<'s> Parser<'s> { self.success = false; } + /// This function [`Self::lift`]s if the last operation was unsuccessful and + /// returns whether it did. pub fn may_lift_abort(&mut self) -> bool { if !self.success { self.lift(); @@ -229,6 +240,8 @@ impl<'s> Parser<'s> { } } + /// This function [`Self::end`]s if the last operation was unsuccessful and + /// returns whether it did. pub fn may_end_abort(&mut self, kind: NodeKind) -> bool { if !self.success { self.end(kind); @@ -251,6 +264,7 @@ impl<'s> Parser<'s> { } } + /// End the parsing process and return the last child. pub fn finish(&mut self) -> Rc { match self.children.pop().unwrap() { Green::Node(n) => n, @@ -263,6 +277,7 @@ impl<'s> Parser<'s> { self.peek().is_none() } + /// Consume the next token and return its kind. fn eat_peeked(&mut self) -> Option { let token = self.peek()?.clone(); self.eat(); @@ -490,6 +505,8 @@ impl<'s> Parser<'s> { } } + /// Returns whether the given type can be skipped over given the current + /// newline mode. pub fn skip_type_ext(token: &NodeKind, stop_at_newline: bool) -> bool { match token { NodeKind::Space(n) => n < &1 || !stop_at_newline, @@ -499,11 +516,12 @@ impl<'s> Parser<'s> { } } + /// Returns whether the given type can be skipped over. fn skip_type(&self, token: &NodeKind) -> bool { Self::skip_type_ext(token, self.stop_at_newline()) } - /// Move to the next token. + /// Consume the next token. pub fn eat(&mut self) { self.children.push( GreenData::new( @@ -516,6 +534,7 @@ impl<'s> Parser<'s> { self.fast_forward(); } + /// Move to the next token. pub fn fast_forward(&mut self) { if !self.next.as_ref().map_or(false, |x| self.skip_type(x)) { self.prev_end = self.tokens.index().into(); @@ -567,20 +586,24 @@ impl<'s> Parser<'s> { self.groups.iter().any(|g| g.kind == kind) } + /// Returns the last child of the current stack frame. pub fn last_child(&self) -> Option<&Green> { self.children.last() } + /// Whether the last operation was successful. pub fn success(&mut self) -> bool { let s = self.success; self.success = true; s } + /// Declare the last operation as unsuccessful. pub fn unsuccessful(&mut self) { self.success = false; } + /// Amount of children in the current stack frame. pub fn child_count(&self) -> usize { self.children.len() } diff --git a/src/syntax/mod.rs b/src/syntax/mod.rs index ca41d33f7..61e0bb7e3 100644 --- a/src/syntax/mod.rs +++ b/src/syntax/mod.rs @@ -30,6 +30,7 @@ pub enum Green { } impl Green { + /// Returns the metadata of the node. fn data(&self) -> &GreenData { match self { Green::Node(n) => &n.data, @@ -37,18 +38,22 @@ impl Green { } } + /// The type of the node. pub fn kind(&self) -> &NodeKind { self.data().kind() } + /// The length of the node. pub fn len(&self) -> usize { self.data().len() } + /// Whether the node or its children contain an error. pub fn erroneous(&self) -> bool { self.data().erroneous() } + /// The node's children. pub fn children(&self) -> &[Green] { match self { Green::Node(n) => &n.children(), @@ -87,23 +92,19 @@ pub struct GreenNode { } impl GreenNode { - pub fn new(kind: NodeKind, len: usize) -> Self { - Self { - data: GreenData::new(kind, len), - children: Vec::new(), - } - } - + /// Creates a new node with the given kind and children. pub fn with_children(kind: NodeKind, len: usize, children: Vec) -> Self { let mut data = GreenData::new(kind, len); data.erroneous |= children.iter().any(|c| c.erroneous()); Self { data, children } } + /// Creates a new node with the given kind and a single child. pub fn with_child(kind: NodeKind, len: usize, child: impl Into) -> Self { Self::with_children(kind, len, vec![child.into()]) } + /// The node's children. pub fn children(&self) -> &[Green] { &self.children } @@ -121,7 +122,7 @@ impl From> for Green { } } -/// Data shared between [`GreenNode`]s and [`GreenToken`]s. +/// Data shared between [`GreenNode`]s and leaf nodes. #[derive(Clone, PartialEq)] pub struct GreenData { /// What kind of node this is (each kind would have its own struct in a @@ -134,18 +135,22 @@ pub struct GreenData { } impl GreenData { + /// Create new node metadata. pub fn new(kind: NodeKind, len: usize) -> Self { Self { len, erroneous: kind.is_error(), kind } } + /// The type of the node. pub fn kind(&self) -> &NodeKind { &self.kind } + /// The length of the node. pub fn len(&self) -> usize { self.len } + /// Whether the node or its children contain an error. pub fn erroneous(&self) -> bool { self.erroneous } @@ -157,6 +162,8 @@ impl From for Green { } } +/// A borrowed wrapper for the [`GreenNode`] type that allows to access spans, +/// error lists and cast to an AST. #[derive(Copy, Clone, PartialEq)] pub struct RedRef<'a> { id: SourceId, @@ -165,6 +172,7 @@ pub struct RedRef<'a> { } impl<'a> RedRef<'a> { + /// Convert to an owned representation. pub fn own(self) -> RedNode { RedNode { id: self.id, @@ -173,18 +181,22 @@ impl<'a> RedRef<'a> { } } + /// The type of the node. pub fn kind(&self) -> &NodeKind { self.green.kind() } + /// The span of the node. pub fn span(&self) -> Span { Span::new(self.id, self.offset, self.offset + self.green.len()) } + /// The length of the node. pub fn len(&self) -> usize { self.green.len() } + /// Convert the node to a typed AST node. pub fn cast(self) -> Option where T: TypedNode, @@ -192,10 +204,12 @@ impl<'a> RedRef<'a> { T::cast_from(self) } + /// Whether the node or its children contain an error. pub fn erroneous(&self) -> bool { self.green.erroneous() } + /// The node's children. pub fn children(self) -> impl Iterator> + Clone { let children = match &self.green { Green::Node(node) => node.children(), @@ -210,6 +224,7 @@ impl<'a> RedRef<'a> { }) } + /// The error messages for this node and its descendants. pub fn errors(&self) -> Vec { if !self.green.erroneous() { return vec![]; @@ -233,15 +248,18 @@ impl<'a> RedRef<'a> { } } + /// Get the first child of some type. pub(crate) fn typed_child(&self, kind: &NodeKind) -> Option { self.children() .find(|x| mem::discriminant(x.kind()) == mem::discriminant(kind)) } + /// Get the first child that can cast to some AST type. pub(crate) fn cast_first_child(&self) -> Option { self.children().find_map(RedRef::cast) } + /// Get the last child that can cast to some AST type. pub(crate) fn cast_last_child(&self) -> Option { self.children().filter_map(RedRef::cast).last() } @@ -259,6 +277,8 @@ impl Debug for RedRef<'_> { } } +/// An owned wrapper for the [`GreenNode`] type that allows to access spans, +/// error lists and cast to an AST. #[derive(Clone, PartialEq)] pub struct RedNode { id: SourceId, @@ -267,10 +287,12 @@ pub struct RedNode { } impl RedNode { + /// Create a new root node from a [`GreenNode`]. pub fn new_root(root: Rc, id: SourceId) -> Self { Self { id, offset: 0, green: root.into() } } + /// Convert to a borrowed representation. pub fn as_ref<'a>(&'a self) -> RedRef<'a> { RedRef { id: self.id, @@ -279,14 +301,17 @@ impl RedNode { } } + /// The span of the node. pub fn span(&self) -> Span { self.as_ref().span() } + /// The length of the node. pub fn len(&self) -> usize { self.as_ref().len() } + /// Convert the node to a typed AST node. pub fn cast(self) -> Option where T: TypedNode, @@ -294,26 +319,32 @@ impl RedNode { T::cast_from(self.as_ref()) } + /// The type of the node. pub fn kind(&self) -> &NodeKind { self.green.kind() } + /// The children of the node. pub fn children<'a>(&'a self) -> impl Iterator> + Clone { self.as_ref().children() } + /// The error messages for this node and its descendants. pub fn errors<'a>(&'a self) -> Vec { self.as_ref().errors() } + /// Get the first child of some type. pub(crate) fn typed_child(&self, kind: &NodeKind) -> Option { self.as_ref().typed_child(kind).map(RedRef::own) } + /// Get the first child that can cast to some AST type. pub(crate) fn cast_first_child(&self) -> Option { self.as_ref().cast_first_child() } + /// Get the last child that can cast to some AST type. pub(crate) fn cast_last_child(&self) -> Option { self.as_ref().cast_last_child() } @@ -477,7 +508,7 @@ pub enum NodeKind { /// A percentage: `50%`. /// /// _Note_: `50%` is stored as `50.0` here, as in the corresponding - /// [literal](super::Lit::Percent). + /// [literal](Lit::Percent). Percentage(f64), /// A fraction unit: `3fr`. Fraction(f64), @@ -595,6 +626,7 @@ impl Display for NodeKind { } impl NodeKind { + /// Whether this is some kind of parenthesis. pub fn is_paren(&self) -> bool { match self { Self::LeftParen => true, @@ -603,6 +635,7 @@ impl NodeKind { } } + /// Whether this is some kind of bracket. pub fn is_bracket(&self) -> bool { match self { Self::LeftBracket => true, @@ -611,6 +644,7 @@ impl NodeKind { } } + /// Whether this is some kind of brace. pub fn is_brace(&self) -> bool { match self { Self::LeftBrace => true, @@ -619,8 +653,9 @@ impl NodeKind { } } + /// Whether this is some kind of error. pub fn is_error(&self) -> bool { - matches!(self, NodeKind::Error(_, _)) + matches!(self, NodeKind::Error(_, _) | NodeKind::Unknown(_)) } pub fn as_str(&self) -> &'static str {