diff options
| author | Laurenz <laurmaedje@gmail.com> | 2022-10-05 12:49:39 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2022-10-05 12:49:39 +0200 |
| commit | ec884ec1d85f6e1d7868db3e82d572579cc5d345 (patch) | |
| tree | 92819f3a31abd6fdcd6b01adcd367bad344bef13 /src/syntax/mod.rs | |
| parent | 5a8534a395b500a25cbc46ee15ec031c8231de59 (diff) | |
Refactor syntax module
Diffstat (limited to 'src/syntax/mod.rs')
| -rw-r--r-- | src/syntax/mod.rs | 614 |
1 files changed, 7 insertions, 607 deletions
diff --git a/src/syntax/mod.rs b/src/syntax/mod.rs index 367d0062..5ff99d03 100644 --- a/src/syntax/mod.rs +++ b/src/syntax/mod.rs @@ -1,21 +1,20 @@ //! Syntax types. pub mod ast; -mod highlight; +pub mod highlight; +mod kind; mod span; -use std::fmt::{self, Debug, Display, Formatter}; -use std::hash::{Hash, Hasher}; +use std::fmt::{self, Debug, Formatter}; use std::ops::Range; use std::sync::Arc; -pub use highlight::*; +pub use kind::*; pub use span::*; -use self::ast::{RawNode, TypedNode, Unit}; +use self::ast::TypedNode; use crate::diag::SourceError; use crate::source::SourceId; -use crate::util::EcoString; /// An inner or leaf node in the untyped syntax tree. #[derive(Clone, PartialEq, Hash)] @@ -73,8 +72,8 @@ impl SyntaxNode { } match self.kind() { - &NodeKind::Error(pos, ref message) => { - vec![SourceError::new(self.span().with_pos(pos), message)] + NodeKind::Error(pos, message) => { + vec![SourceError::new(self.span().with_pos(*pos), message)] } _ => self .children() @@ -564,602 +563,3 @@ impl PartialEq for NodeData { self.kind == other.kind && self.len == other.len } } - -/// All syntactical building blocks that can be part of a Typst document. -/// -/// Can be emitted as a token by the tokenizer or as part of a syntax node by -/// the parser. -#[derive(Debug, Clone, PartialEq)] -pub enum NodeKind { - /// A line comment, two slashes followed by inner contents, terminated with - /// a newline: `//<str>\n`. - LineComment, - /// A block comment, a slash and a star followed by inner contents, - /// terminated with a star and a slash: `/*<str>*/`. - /// - /// The comment can contain nested block comments. - BlockComment, - /// One or more whitespace characters. Single spaces are collapsed into text - /// nodes if they would otherwise be surrounded by text nodes. - /// - /// Also stores how many newlines are contained. - Space { newlines: usize }, - - /// A left curly brace, starting a code block: `{`. - LeftBrace, - /// A right curly brace, terminating a code block: `}`. - RightBrace, - /// A left square bracket, starting a content block: `[`. - LeftBracket, - /// A right square bracket, terminating a content block: `]`. - RightBracket, - /// A left round parenthesis, starting a grouped expression, collection, - /// argument or parameter list: `(`. - LeftParen, - /// A right round parenthesis, terminating a grouped expression, collection, - /// argument or parameter list: `)`. - RightParen, - /// A comma separator in a sequence: `,`. - Comma, - /// A semicolon terminating an expression: `;`. - Semicolon, - /// A colon between name / key and value in a dictionary, argument or - /// parameter list, or between the term and body of a description list - /// term: `:`. - Colon, - /// The strong text toggle, multiplication operator, and wildcard import - /// symbol: `*`. - Star, - /// Toggles emphasized text and indicates a subscript in a formula: `_`. - Underscore, - /// Starts and ends a math formula. - Dollar, - /// The non-breaking space: `~`. - Tilde, - /// The soft hyphen: `-?`. - HyphQuest, - /// The en-dash: `--`. - Hyph2, - /// The em-dash: `---`. - Hyph3, - /// The ellipsis: `...`. - Dot3, - /// A smart quote: `'` or `"`. - Quote { double: bool }, - /// The unary plus and addition operator, and start of enum items: `+`. - Plus, - /// The unary negation and subtraction operator, and start of list - /// items: `-`. - Minus, - /// The division operator, start of description list items, and fraction - /// operator in a formula: `/`. - Slash, - /// The superscript operator: `^`. - Hat, - /// The math alignment operator: `&`. - Amp, - /// The field access and method call operator: `.`. - Dot, - /// The assignment operator: `=`. - Eq, - /// The equality operator: `==`. - EqEq, - /// The inequality operator: `!=`. - ExclEq, - /// The less-than operator: `<`. - Lt, - /// The less-than or equal operator: `<=`. - LtEq, - /// The greater-than operator: `>`. - Gt, - /// The greater-than or equal operator: `>=`. - GtEq, - /// The add-assign operator: `+=`. - PlusEq, - /// The subtract-assign operator: `-=`. - HyphEq, - /// The multiply-assign operator: `*=`. - StarEq, - /// The divide-assign operator: `/=`. - SlashEq, - /// The spread operator: `..`. - Dots, - /// An arrow between a closure's parameters and body: `=>`. - Arrow, - - /// The `not` operator. - Not, - /// The `and` operator. - And, - /// The `or` operator. - Or, - /// The `none` literal. - None, - /// The `auto` literal. - Auto, - /// The `let` keyword. - Let, - /// The `set` keyword. - Set, - /// The `show` keyword. - Show, - /// The `wrap` keyword. - Wrap, - /// The `if` keyword. - If, - /// The `else` keyword. - Else, - /// The `for` keyword. - For, - /// The `in` keyword. - In, - /// The `while` keyword. - While, - /// The `break` keyword. - Break, - /// The `continue` keyword. - Continue, - /// The `return` keyword. - Return, - /// The `import` keyword. - Import, - /// The `include` keyword. - Include, - /// The `from` keyword. - From, - /// The `as` keyword. - As, - - /// Markup of which all lines must have a minimal indentation. - /// - /// Notably, the number does not determine in which column the markup - /// started, but to the right of which column all markup elements must be, - /// so it is zero except for headings and lists. - Markup { min_indent: usize }, - /// A forced line break in markup or math. - Linebreak, - /// Consecutive text without markup. While basic text with just single - /// spaces is collapsed into a single node, certain symbols that could - /// possibly be markup force text into multiple nodes. - Text(EcoString), - /// A slash and the letter "u" followed by a hexadecimal unicode entity - /// enclosed in curly braces: `\u{1F5FA}`. - Escape(char), - /// Strong content: `*Strong*`. - Strong, - /// Emphasized content: `_Emphasized_`. - Emph, - /// A hyperlink. - Link(EcoString), - /// A raw block with optional syntax highlighting: `` `...` ``. - Raw(Arc<RawNode>), - /// A math formula: `$x$`, `$ x^2 $`. - Math, - /// A section heading: `= Introduction`. - Heading, - /// An item in an unordered list: `- ...`. - List, - /// An item in an enumeration (ordered list): `+ ...` or `1. ...`. - Enum, - /// An explicit enumeration numbering: `23.`. - EnumNumbering(usize), - /// An item in a description list: `/ Term: Details. - Desc, - /// A label: `<label>`. - Label(EcoString), - /// A reference: `@label`. - Ref(EcoString), - - /// An atom in a math formula: `x`, `+`, `12`. - Atom(EcoString), - /// A base with an optional sub- and superscript in a formula: `a_1^2`. - Script, - /// A fraction: `x/2`. - Frac, - /// A math alignment indicator: `&`, `&&`. - Align, - - /// An identifier: `center`. - Ident(EcoString), - /// A boolean: `true`, `false`. - Bool(bool), - /// An integer: `120`. - Int(i64), - /// A floating-point number: `1.2`, `10e-4`. - Float(f64), - /// A numeric value with a unit: `12pt`, `3cm`, `2em`, `90deg`, `50%`. - Numeric(f64, Unit), - /// A quoted string: `"..."`. - Str(EcoString), - /// A code block: `{ let x = 1; x + 2 }`. - CodeBlock, - /// A content block: `[*Hi* there!]`. - ContentBlock, - /// A grouped expression: `(1 + 2)`. - GroupExpr, - /// An array expression: `(1, "hi", 12cm)`. - ArrayExpr, - /// A dictionary expression: `(thickness: 3pt, pattern: dashed)`. - DictExpr, - /// A named pair: `thickness: 3pt`. - Named, - /// A keyed pair: `"spacy key": true`. - Keyed, - /// A unary operation: `-x`. - UnaryExpr, - /// A binary operation: `a + b`. - BinaryExpr, - /// A field access: `properties.age`. - FieldAccess, - /// An invocation of a function: `f(x, y)`. - FuncCall, - /// An invocation of a method: `array.push(v)`. - MethodCall, - /// A function call's argument list: `(x, y)`. - CallArgs, - /// Spreaded arguments or a argument sink: `..x`. - Spread, - /// A closure expression: `(x, y) => z`. - ClosureExpr, - /// A closure's parameters: `(x, y)`. - ClosureParams, - /// A let expression: `let x = 1`. - LetExpr, - /// A set expression: `set text(...)`. - SetExpr, - /// A show expression: `show node: heading as [*{nody.body}*]`. - ShowExpr, - /// A wrap expression: `wrap body in columns(2, body)`. - WrapExpr, - /// An if-else expression: `if x { y } else { z }`. - IfExpr, - /// A while loop expression: `while x { ... }`. - WhileExpr, - /// A for loop expression: `for x in y { ... }`. - ForExpr, - /// A for loop's destructuring pattern: `x` or `x, y`. - ForPattern, - /// An import expression: `import a, b, c from "utils.typ"`. - ImportExpr, - /// Items to import: `a, b, c`. - ImportItems, - /// An include expression: `include "chapter1.typ"`. - IncludeExpr, - /// A break expression: `break`. - BreakExpr, - /// A continue expression: `continue`. - ContinueExpr, - /// A return expression: `return x + 1`. - ReturnExpr, - - /// Tokens that appear in the wrong place. - Error(SpanPos, EcoString), - /// Unknown character sequences. - Unknown(EcoString), -} - -impl NodeKind { - /// Whether this is a kind of parenthesis. - pub fn is_paren(&self) -> bool { - matches!(self, Self::LeftParen | Self::RightParen) - } - - /// Whether this is a space. - pub fn is_space(&self) -> bool { - matches!(self, Self::Space { .. }) - } - - /// Whether this is trivia. - pub fn is_trivia(&self) -> bool { - self.is_space() || matches!(self, Self::LineComment | Self::BlockComment) - } - - /// Whether this is a kind of error. - pub fn is_error(&self) -> bool { - matches!(self, NodeKind::Error(_, _) | NodeKind::Unknown(_)) - } - - /// Whether `at_start` would still be true after this node given the - /// previous value of the property. - pub fn is_at_start(&self, prev: bool) -> bool { - match self { - Self::Space { newlines: (1 ..) } => true, - Self::Space { .. } | Self::LineComment | Self::BlockComment => prev, - _ => false, - } - } - - /// Whether changes _inside_ this node are safely encapsulated, so that only - /// this node must be reparsed. - pub fn is_bounded(&self) -> bool { - match self { - Self::CodeBlock - | Self::ContentBlock - | Self::Linebreak { .. } - | Self::Tilde - | Self::HyphQuest - | Self::Hyph2 - | Self::Hyph3 - | Self::Dot3 - | Self::Quote { .. } - | Self::BlockComment - | Self::Space { .. } - | Self::Escape(_) => true, - _ => false, - } - } - - /// A human-readable name for the kind. - pub fn as_str(&self) -> &'static str { - match self { - Self::LineComment => "line comment", - Self::BlockComment => "block comment", - Self::Space { .. } => "space", - - Self::LeftBrace => "opening brace", - Self::RightBrace => "closing brace", - Self::LeftBracket => "opening bracket", - Self::RightBracket => "closing bracket", - Self::LeftParen => "opening paren", - Self::RightParen => "closing paren", - Self::Comma => "comma", - Self::Semicolon => "semicolon", - Self::Colon => "colon", - Self::Star => "star", - Self::Underscore => "underscore", - Self::Dollar => "dollar sign", - Self::Tilde => "non-breaking space", - Self::HyphQuest => "soft hyphen", - Self::Hyph2 => "en dash", - Self::Hyph3 => "em dash", - Self::Dot3 => "ellipsis", - Self::Quote { double: false } => "single quote", - Self::Quote { double: true } => "double quote", - Self::Plus => "plus", - Self::Minus => "minus", - Self::Slash => "slash", - Self::Hat => "hat", - Self::Amp => "ampersand", - Self::Dot => "dot", - Self::Eq => "assignment operator", - Self::EqEq => "equality operator", - Self::ExclEq => "inequality operator", - Self::Lt => "less-than operator", - Self::LtEq => "less-than or equal operator", - Self::Gt => "greater-than operator", - Self::GtEq => "greater-than or equal operator", - Self::PlusEq => "add-assign operator", - Self::HyphEq => "subtract-assign operator", - Self::StarEq => "multiply-assign operator", - Self::SlashEq => "divide-assign operator", - Self::Dots => "dots", - Self::Arrow => "arrow", - - Self::Not => "operator `not`", - Self::And => "operator `and`", - Self::Or => "operator `or`", - Self::None => "`none`", - Self::Auto => "`auto`", - Self::Let => "keyword `let`", - Self::Set => "keyword `set`", - Self::Show => "keyword `show`", - Self::Wrap => "keyword `wrap`", - Self::If => "keyword `if`", - Self::Else => "keyword `else`", - Self::For => "keyword `for`", - Self::In => "keyword `in`", - Self::While => "keyword `while`", - Self::Break => "keyword `break`", - Self::Continue => "keyword `continue`", - Self::Return => "keyword `return`", - Self::Import => "keyword `import`", - Self::Include => "keyword `include`", - Self::From => "keyword `from`", - Self::As => "keyword `as`", - - Self::Markup { .. } => "markup", - Self::Linebreak => "linebreak", - Self::Text(_) => "text", - Self::Escape(_) => "escape sequence", - Self::Strong => "strong content", - Self::Emph => "emphasized content", - Self::Link(_) => "link", - Self::Raw(_) => "raw block", - Self::Math => "math formula", - Self::Heading => "heading", - Self::List => "list item", - Self::Enum => "enumeration item", - Self::EnumNumbering(_) => "enumeration item numbering", - Self::Desc => "description list item", - Self::Label(_) => "label", - Self::Ref(_) => "reference", - - Self::Atom(_) => "math atom", - Self::Script => "script", - Self::Frac => "fraction", - Self::Align => "alignment indicator", - - Self::Ident(_) => "identifier", - Self::Bool(_) => "boolean", - Self::Int(_) => "integer", - Self::Float(_) => "float", - Self::Numeric(_, _) => "numeric value", - Self::Str(_) => "string", - Self::CodeBlock => "code block", - Self::ContentBlock => "content block", - Self::GroupExpr => "group", - Self::ArrayExpr => "array", - Self::DictExpr => "dictionary", - Self::Named => "named pair", - Self::Keyed => "keyed pair", - Self::UnaryExpr => "unary expression", - Self::BinaryExpr => "binary expression", - Self::FieldAccess => "field access", - Self::FuncCall => "function call", - Self::MethodCall => "method call", - Self::CallArgs => "call arguments", - Self::Spread => "spread", - Self::ClosureExpr => "closure", - Self::ClosureParams => "closure parameters", - Self::LetExpr => "`let` expression", - Self::SetExpr => "`set` expression", - Self::ShowExpr => "`show` expression", - Self::WrapExpr => "`wrap` expression", - Self::IfExpr => "`if` expression", - Self::WhileExpr => "while-loop expression", - Self::ForExpr => "for-loop expression", - Self::ForPattern => "for-loop destructuring pattern", - Self::ImportExpr => "`import` expression", - Self::ImportItems => "import items", - Self::IncludeExpr => "`include` expression", - Self::BreakExpr => "`break` expression", - Self::ContinueExpr => "`continue` expression", - Self::ReturnExpr => "`return` expression", - - Self::Error(_, _) => "parse error", - Self::Unknown(text) => match text.as_str() { - "*/" => "end of block comment", - _ => "invalid token", - }, - } - } -} - -impl Display for NodeKind { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - f.pad(self.as_str()) - } -} - -impl Hash for NodeKind { - fn hash<H: Hasher>(&self, state: &mut H) { - std::mem::discriminant(self).hash(state); - match self { - Self::LineComment => {} - Self::BlockComment => {} - Self::Space { newlines } => newlines.hash(state), - - Self::LeftBrace => {} - Self::RightBrace => {} - Self::LeftBracket => {} - Self::RightBracket => {} - Self::LeftParen => {} - Self::RightParen => {} - Self::Comma => {} - Self::Semicolon => {} - Self::Colon => {} - Self::Star => {} - Self::Underscore => {} - Self::Dollar => {} - Self::Tilde => {} - Self::HyphQuest => {} - Self::Hyph2 => {} - Self::Hyph3 => {} - Self::Dot3 => {} - Self::Quote { double } => double.hash(state), - Self::Plus => {} - Self::Minus => {} - Self::Slash => {} - Self::Hat => {} - Self::Amp => {} - Self::Dot => {} - Self::Eq => {} - Self::EqEq => {} - Self::ExclEq => {} - Self::Lt => {} - Self::LtEq => {} - Self::Gt => {} - Self::GtEq => {} - Self::PlusEq => {} - Self::HyphEq => {} - Self::StarEq => {} - Self::SlashEq => {} - Self::Dots => {} - Self::Arrow => {} - - Self::Not => {} - Self::And => {} - Self::Or => {} - Self::None => {} - Self::Auto => {} - Self::Let => {} - Self::Set => {} - Self::Show => {} - Self::Wrap => {} - Self::If => {} - Self::Else => {} - Self::For => {} - Self::In => {} - Self::While => {} - Self::Break => {} - Self::Continue => {} - Self::Return => {} - Self::Import => {} - Self::Include => {} - Self::From => {} - Self::As => {} - - Self::Markup { min_indent } => min_indent.hash(state), - Self::Linebreak => {} - Self::Text(s) => s.hash(state), - Self::Escape(c) => c.hash(state), - Self::Strong => {} - Self::Emph => {} - Self::Link(link) => link.hash(state), - Self::Raw(raw) => raw.hash(state), - Self::Math => {} - Self::Heading => {} - Self::List => {} - Self::Enum => {} - Self::EnumNumbering(num) => num.hash(state), - Self::Desc => {} - Self::Label(c) => c.hash(state), - Self::Ref(c) => c.hash(state), - - Self::Atom(c) => c.hash(state), - Self::Script => {} - Self::Frac => {} - Self::Align => {} - - Self::Ident(v) => v.hash(state), - Self::Bool(v) => v.hash(state), - Self::Int(v) => v.hash(state), - Self::Float(v) => v.to_bits().hash(state), - Self::Numeric(v, u) => (v.to_bits(), u).hash(state), - Self::Str(v) => v.hash(state), - Self::CodeBlock => {} - Self::ContentBlock => {} - Self::GroupExpr => {} - Self::ArrayExpr => {} - Self::DictExpr => {} - Self::Named => {} - Self::Keyed => {} - Self::UnaryExpr => {} - Self::BinaryExpr => {} - Self::FieldAccess => {} - Self::FuncCall => {} - Self::MethodCall => {} - Self::CallArgs => {} - Self::Spread => {} - Self::ClosureExpr => {} - Self::ClosureParams => {} - Self::LetExpr => {} - Self::SetExpr => {} - Self::ShowExpr => {} - Self::WrapExpr => {} - Self::IfExpr => {} - Self::WhileExpr => {} - Self::ForExpr => {} - Self::ForPattern => {} - Self::ImportExpr => {} - Self::ImportItems => {} - Self::IncludeExpr => {} - Self::BreakExpr => {} - Self::ContinueExpr => {} - Self::ReturnExpr => {} - - Self::Error(pos, msg) => (pos, msg).hash(state), - Self::Unknown(text) => text.hash(state), - } - } -} |
