diff options
| author | Laurenz <laurmaedje@gmail.com> | 2020-08-02 16:31:34 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2020-08-02 16:31:34 +0200 |
| commit | 533374db14087ac54fdc86afa5f009487ac1b850 (patch) | |
| tree | 0970eb1ca893fe45369d622b5bc1f226f0f66004 /src/syntax/mod.rs | |
| parent | 2188ef6b899cc10c84ed985e9ad9049fcc3eb662 (diff) | |
Refactor argument parsing 🔬
Diffstat (limited to 'src/syntax/mod.rs')
| -rw-r--r-- | src/syntax/mod.rs | 181 |
1 files changed, 6 insertions, 175 deletions
diff --git a/src/syntax/mod.rs b/src/syntax/mod.rs index b67d8cd7..e844fdf1 100644 --- a/src/syntax/mod.rs +++ b/src/syntax/mod.rs @@ -1,183 +1,14 @@ //! Syntax models, parsing and tokenization. -use std::any::Any; -use std::fmt::Debug; -use async_trait::async_trait; -use serde::Serialize; - -use crate::{Pass, Feedback}; -use crate::layout::{LayoutContext, Commands, Command}; -use self::span::{Spanned, SpanVec}; - #[cfg(test)] #[macro_use] mod test; +pub mod decoration; pub mod expr; -pub mod func; +pub mod model; +pub mod parsing; pub mod span; -pub_use_mod!(scope); -pub_use_mod!(parsing); -pub_use_mod!(tokens); - -/// Represents a parsed piece of source that can be layouted and in the future -/// also be queried for information used for refactorings, autocomplete, etc. -#[async_trait(?Send)] -pub trait Model: Debug + ModelBounds { - /// Layout the model into a sequence of commands processed by a - /// [`ModelLayouter`](crate::layout::ModelLayouter). - async fn layout<'a>(&'a self, ctx: LayoutContext<'_>) -> Pass<Commands<'a>>; -} - -/// A tree representation of source code. -#[derive(Debug, Default, Clone, PartialEq)] -pub struct SyntaxModel { - /// The syntactical elements making up this model. - pub nodes: SpanVec<Node>, -} - -impl SyntaxModel { - /// Create an empty syntax model. - pub fn new() -> SyntaxModel { - SyntaxModel { nodes: vec![] } - } - - /// Add a node to the model. - pub fn add(&mut self, node: Spanned<Node>) { - self.nodes.push(node); - } -} - -#[async_trait(?Send)] -impl Model for SyntaxModel { - async fn layout<'a>(&'a self, _: LayoutContext<'_>) -> Pass<Commands<'a>> { - Pass::new(vec![Command::LayoutSyntaxModel(self)], Feedback::new()) - } -} - -/// A node in the [syntax model](SyntaxModel). -#[derive(Debug, Clone)] -pub enum Node { - /// Whitespace containing less than two newlines. - Space, - /// Whitespace with more than two newlines. - Parbreak, - /// A forced line break. - Linebreak, - /// Plain text. - Text(String), - /// Lines of raw text. - Raw(Vec<String>), - /// Italics were enabled / disabled. - ToggleItalic, - /// Bolder was enabled / disabled. - ToggleBolder, - /// A submodel, typically a function invocation. - Model(Box<dyn Model>), -} - -impl PartialEq for Node { - fn eq(&self, other: &Node) -> bool { - use Node::*; - match (self, other) { - (Space, Space) => true, - (Parbreak, Parbreak) => true, - (Linebreak, Linebreak) => true, - (Text(a), Text(b)) => a == b, - (Raw(a), Raw(b)) => a == b, - (ToggleItalic, ToggleItalic) => true, - (ToggleBolder, ToggleBolder) => true, - (Model(a), Model(b)) => a == b, - _ => false, - } - } -} - -/// A list of spanned decorations. -pub type Decorations = SpanVec<Decoration>; - -/// Decorations for semantic syntax highlighting. -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Serialize)] -#[serde(rename_all = "camelCase")] -pub enum Decoration { - /// A valid function name: - /// ```typst - /// [box] - /// ^^^ - /// ``` - ValidFuncName, - /// An invalid function name: - /// ```typst - /// [blabla] - /// ^^^^^^ - /// ``` - InvalidFuncName, - /// A key of a keyword argument: - /// ```typst - /// [box: width=5cm] - /// ^^^^^ - /// ``` - ArgumentKey, - /// A key in an object. - /// ```typst - /// [box: padding={ left: 1cm, right: 2cm}] - /// ^^^^ ^^^^^ - /// ``` - ObjectKey, - /// An italic word. - Italic, - /// A bold word. - Bold, -} - -impl dyn Model { - /// Downcast this model to a concrete type implementing [`Model`]. - pub fn downcast<T>(&self) -> Option<&T> where T: Model + 'static { - self.as_any().downcast_ref::<T>() - } -} - -impl PartialEq for dyn Model { - fn eq(&self, other: &dyn Model) -> bool { - self.bound_eq(other) - } -} - -impl Clone for Box<dyn Model> { - fn clone(&self) -> Self { - self.bound_clone() - } -} - -/// This trait describes bounds necessary for types implementing [`Model`]. It is -/// automatically implemented for all types that are [`Model`], [`PartialEq`], -/// [`Clone`] and `'static`. -/// -/// It is necessary to make models comparable and clonable. -pub trait ModelBounds { - /// Convert into a `dyn Any`. - fn as_any(&self) -> &dyn Any; - - /// Check for equality with another model. - fn bound_eq(&self, other: &dyn Model) -> bool; - - /// Clone into a boxed model trait object. - fn bound_clone(&self) -> Box<dyn Model>; -} - -impl<T> ModelBounds for T where T: Model + PartialEq + Clone + 'static { - fn as_any(&self) -> &dyn Any { - self - } - - fn bound_eq(&self, other: &dyn Model) -> bool { - match other.as_any().downcast_ref::<Self>() { - Some(other) => self == other, - None => false, - } - } - - fn bound_clone(&self) -> Box<dyn Model> { - Box::new(self.clone()) - } -} +pub mod scope; +pub mod tokens; +pub mod value; |
