mirror of
https://github.com/typst/typst
synced 2025-05-18 02:55:28 +08:00
Add documentation
This commit is contained in:
parent
49fb3cd4e2
commit
42afb27cef
@ -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<usize> {
|
||||
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<GreenNode> {
|
||||
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<NodeKind> {
|
||||
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()
|
||||
}
|
||||
|
@ -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<Green>) -> 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<Green>) -> 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<Rc<GreenNode>> 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<GreenData> 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<T>(self) -> Option<T>
|
||||
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<Item = RedRef<'a>> + 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<Error> {
|
||||
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<RedRef> {
|
||||
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<T: TypedNode>(&self) -> Option<T> {
|
||||
self.children().find_map(RedRef::cast)
|
||||
}
|
||||
|
||||
/// Get the last child that can cast to some AST type.
|
||||
pub(crate) fn cast_last_child<T: TypedNode>(&self) -> Option<T> {
|
||||
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<GreenNode>, 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<T>(self) -> Option<T>
|
||||
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<Item = RedRef<'a>> + Clone {
|
||||
self.as_ref().children()
|
||||
}
|
||||
|
||||
/// The error messages for this node and its descendants.
|
||||
pub fn errors<'a>(&'a self) -> Vec<Error> {
|
||||
self.as_ref().errors()
|
||||
}
|
||||
|
||||
/// Get the first child of some type.
|
||||
pub(crate) fn typed_child(&self, kind: &NodeKind) -> Option<RedNode> {
|
||||
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<T: TypedNode>(&self) -> Option<T> {
|
||||
self.as_ref().cast_first_child()
|
||||
}
|
||||
|
||||
/// Get the last child that can cast to some AST type.
|
||||
pub(crate) fn cast_last_child<T: TypedNode>(&self) -> Option<T> {
|
||||
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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user