From c216a4fc26c72938ddad60bc5fe4fa9e45263b30 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Sat, 10 Oct 2020 22:41:56 +0200 Subject: =?UTF-8?q?Flatten=20ast=20module=20back=20into=20syntax=20module?= =?UTF-8?q?=20=F0=9F=8C=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/parse/tokens.rs | 3 +- src/syntax/ast/expr.rs | 68 ---------------------------- src/syntax/ast/lit.rs | 56 ----------------------- src/syntax/ast/mod.rs | 14 ------ src/syntax/ast/node.rs | 118 ------------------------------------------------- src/syntax/expr.rs | 68 ++++++++++++++++++++++++++++ src/syntax/lit.rs | 56 +++++++++++++++++++++++ src/syntax/mod.rs | 14 ++++-- src/syntax/node.rs | 118 +++++++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 253 insertions(+), 262 deletions(-) delete mode 100644 src/syntax/ast/expr.rs delete mode 100644 src/syntax/ast/lit.rs delete mode 100644 src/syntax/ast/mod.rs delete mode 100644 src/syntax/ast/node.rs create mode 100644 src/syntax/expr.rs create mode 100644 src/syntax/lit.rs create mode 100644 src/syntax/node.rs diff --git a/src/parse/tokens.rs b/src/parse/tokens.rs index f53ab586..3a90e114 100644 --- a/src/parse/tokens.rs +++ b/src/parse/tokens.rs @@ -4,8 +4,7 @@ use std::fmt::{self, Debug, Formatter}; use super::{is_newline, Scanner}; use crate::geom::Unit; -use crate::syntax::token::*; -use crate::syntax::{is_ident, Pos}; +use crate::syntax::*; use TokenMode::*; diff --git a/src/syntax/ast/expr.rs b/src/syntax/ast/expr.rs deleted file mode 100644 index 09729f52..00000000 --- a/src/syntax/ast/expr.rs +++ /dev/null @@ -1,68 +0,0 @@ -//! Expressions. - -use super::*; - -/// An expression. -#[derive(Debug, Clone, PartialEq)] -pub enum Expr { - /// A literal: `true`, `1cm`, `"hi"`, `{_Hey!_}`. - Lit(Lit), - /// An invocation of a function: `[foo: ...]`, `foo(...)`. - Call(ExprCall), - /// A unary operation: `-x`. - Unary(ExprUnary), - /// A binary operation: `a + b`, `a / b`. - Binary(ExprBinary), -} - -/// An invocation of a function: `[foo: ...]`, `foo(...)`. -#[derive(Debug, Clone, PartialEq)] -pub struct ExprCall { - /// The name of the function. - pub name: Spanned, - /// The arguments to the function. - /// - /// In case of a bracketed invocation with a body, the body is _not_ - /// included in the span for the sake of clearer error messages. - pub args: Spanned, -} - -/// A unary operation: `-x`. -#[derive(Debug, Clone, PartialEq)] -pub struct ExprUnary { - /// The operator: `-`. - pub op: Spanned, - /// The expression to operator on: `x`. - pub expr: Spanned>, -} - -/// A unary operator. -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -pub enum UnOp { - /// The negation operator: `-`. - Neg, -} - -/// A binary operation: `a + b`, `a / b`. -#[derive(Debug, Clone, PartialEq)] -pub struct ExprBinary { - /// The left-hand side of the operation: `a`. - pub lhs: Spanned>, - /// The operator: `+`. - pub op: Spanned, - /// The right-hand side of the operation: `b`. - pub rhs: Spanned>, -} - -/// A binary operator. -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -pub enum BinOp { - /// The addition operator: `+`. - Add, - /// The subtraction operator: `-`. - Sub, - /// The multiplication operator: `*`. - Mul, - /// The division operator: `/`. - Div, -} diff --git a/src/syntax/ast/lit.rs b/src/syntax/ast/lit.rs deleted file mode 100644 index 40b360da..00000000 --- a/src/syntax/ast/lit.rs +++ /dev/null @@ -1,56 +0,0 @@ -//! Literals. - -use super::*; -use crate::color::RgbaColor; -use crate::eval::DictKey; -use crate::geom::Unit; - -/// A literal. -#[derive(Debug, Clone, PartialEq)] -pub enum Lit { - /// A identifier literal: `left`. - Ident(Ident), - /// A boolean literal: `true`, `false`. - Bool(bool), - /// An integer literal: `120`. - Int(i64), - /// A floating-point literal: `1.2`, `10e-4`. - Float(f64), - /// A length literal: `12pt`, `3cm`. - Length(f64, Unit), - /// A percent literal: `50%`. - /// - /// _Note_: `50%` is stored as `50.0` here, but as `0.5` in the - /// corresponding [value]. - /// - /// [value]: ../../geom/struct.Relative.html - Percent(f64), - /// A color literal: `#ffccee`. - Color(RgbaColor), - /// A string literal: `"hello!"`. - Str(String), - /// A dictionary literal: `(false, 12cm, greeting = "hi")`. - Dict(LitDict), - /// A content literal: `{*Hello* there!}`. - Content(SynTree), -} - -/// A dictionary literal: `(false, 12cm, greeting = "hi")`. -#[derive(Debug, Default, Clone, PartialEq)] -pub struct LitDict(pub Vec); - -/// An entry in a dictionary literal: `false` or `greeting = "hi"`. -#[derive(Debug, Clone, PartialEq)] -pub struct LitDictEntry { - /// The key of the entry if there was one: `greeting`. - pub key: Option>, - /// The value of the entry: `"hi"`. - pub expr: Spanned, -} - -impl LitDict { - /// Create an empty dict literal. - pub fn new() -> Self { - Self::default() - } -} diff --git a/src/syntax/ast/mod.rs b/src/syntax/ast/mod.rs deleted file mode 100644 index 60a958a4..00000000 --- a/src/syntax/ast/mod.rs +++ /dev/null @@ -1,14 +0,0 @@ -//! Abstract syntax tree definition. - -mod expr; -mod lit; -mod node; - -pub use expr::*; -pub use lit::*; -pub use node::*; - -use super::{Ident, SpanVec, Spanned}; - -/// A collection of nodes which form a tree together with the nodes' children. -pub type SynTree = SpanVec; diff --git a/src/syntax/ast/node.rs b/src/syntax/ast/node.rs deleted file mode 100644 index 102ef3b5..00000000 --- a/src/syntax/ast/node.rs +++ /dev/null @@ -1,118 +0,0 @@ -//! Syntax tree nodes. - -use super::*; - -/// A syntax node, which encompasses a single logical entity of parsed source -/// code. -#[derive(Debug, Clone, PartialEq)] -pub enum SynNode { - /// Whitespace containing less than two newlines. - Space, - /// Plain text. - Text(String), - - /// A forced line break. - Linebreak, - /// A paragraph break. - Parbreak, - /// Emphasized text was enabled / disabled. - Emph, - /// Strong text was enabled / disabled. - Strong, - - /// A section heading. - Heading(NodeHeading), - /// An optionally syntax-highlighted raw block. - Raw(NodeRaw), - - /// An expression. - Expr(Expr), -} - -/// A section heading. -#[derive(Debug, Clone, PartialEq)] -pub struct NodeHeading { - /// The section depth (how many hashtags minus 1). - pub level: Spanned, - /// The contents of the heading. - pub contents: SynTree, -} - -/// A raw block, rendered in monospace with optional syntax highlighting. -/// -/// Raw blocks start with an arbitrary number of backticks and end with the same -/// number of backticks. If you want to include a sequence of backticks in a raw -/// block, simply surround the block with more backticks. -/// -/// When using at least two backticks, an optional language tag may follow -/// directly after the backticks. This tag defines which language to -/// syntax-highlight the text in. Apart from the language tag and some -/// whitespace trimming discussed below, everything inside a raw block is -/// rendered verbatim, in particular, there are no escape sequences. -/// -/// # Examples -/// - Raw text is surrounded by backticks. -/// ```typst -/// `raw` -/// ``` -/// - An optional language tag may follow directly at the start when the block -/// is surrounded by at least two backticks. -/// ```typst -/// ``rust println!("hello!")``; -/// ``` -/// - Blocks can span multiple lines. Two backticks suffice to be able to -/// specify the language tag, but three are fine, too. -/// ```typst -/// ``rust -/// loop { -/// find_yak().shave(); -/// } -/// `` -/// ``` -/// - Start with a space to omit the language tag (the space will be trimmed -/// from the output) and use more backticks to allow backticks in the raw -/// text. -/// `````typst -/// ```` This contains ```backticks``` and has no leading & trailing spaces. ```` -/// ````` -/// -/// # Trimming -/// If we would always render the raw text between the backticks exactly as -/// given, a few things would become problematic or even impossible: -/// - Typical multiline code blocks (like in the example above) would have an -/// additional newline before and after the code. -/// - Raw text wrapped in more than one backtick could not exist without -/// leading whitespace since the first word would be interpreted as a -/// language tag. -/// - A single backtick without surrounding spaces could not exist as raw text -/// since it would be interpreted as belonging to the opening or closing -/// backticks. -/// -/// To fix these problems, we trim text in multi-backtick blocks as follows: -/// - We trim a single space or a sequence of whitespace followed by a newline -/// at the start. -/// - We trim a single space or a newline followed by a sequence of whitespace -/// at the end. -/// -/// With these rules, a single raw backtick can be produced by the sequence -/// ``` `` ` `` ```, ``` `` unhighlighted text `` ``` has no surrounding -/// spaces and multiline code blocks don't have extra empty lines. Note that -/// you can always force leading or trailing whitespace simply by adding more -/// spaces. -#[derive(Debug, Clone, PartialEq)] -pub struct NodeRaw { - /// An optional identifier specifying the language to syntax-highlight in. - pub lang: Option, - /// The lines of raw text, determined as the raw string between the - /// backticks trimmed according to the above rules and split at newlines. - pub lines: Vec, - /// Whether the element can be layouted inline. - /// - /// - When true, it will be layouted integrated within the surrounding - /// paragraph. - /// - When false, it will be separated into its own paragraph. - /// - /// Single-backtick blocks are always inline-level. Multi-backtick blocks - /// are inline-level when they contain no newlines. - pub inline: bool, -} diff --git a/src/syntax/expr.rs b/src/syntax/expr.rs new file mode 100644 index 00000000..09729f52 --- /dev/null +++ b/src/syntax/expr.rs @@ -0,0 +1,68 @@ +//! Expressions. + +use super::*; + +/// An expression. +#[derive(Debug, Clone, PartialEq)] +pub enum Expr { + /// A literal: `true`, `1cm`, `"hi"`, `{_Hey!_}`. + Lit(Lit), + /// An invocation of a function: `[foo: ...]`, `foo(...)`. + Call(ExprCall), + /// A unary operation: `-x`. + Unary(ExprUnary), + /// A binary operation: `a + b`, `a / b`. + Binary(ExprBinary), +} + +/// An invocation of a function: `[foo: ...]`, `foo(...)`. +#[derive(Debug, Clone, PartialEq)] +pub struct ExprCall { + /// The name of the function. + pub name: Spanned, + /// The arguments to the function. + /// + /// In case of a bracketed invocation with a body, the body is _not_ + /// included in the span for the sake of clearer error messages. + pub args: Spanned, +} + +/// A unary operation: `-x`. +#[derive(Debug, Clone, PartialEq)] +pub struct ExprUnary { + /// The operator: `-`. + pub op: Spanned, + /// The expression to operator on: `x`. + pub expr: Spanned>, +} + +/// A unary operator. +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +pub enum UnOp { + /// The negation operator: `-`. + Neg, +} + +/// A binary operation: `a + b`, `a / b`. +#[derive(Debug, Clone, PartialEq)] +pub struct ExprBinary { + /// The left-hand side of the operation: `a`. + pub lhs: Spanned>, + /// The operator: `+`. + pub op: Spanned, + /// The right-hand side of the operation: `b`. + pub rhs: Spanned>, +} + +/// A binary operator. +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +pub enum BinOp { + /// The addition operator: `+`. + Add, + /// The subtraction operator: `-`. + Sub, + /// The multiplication operator: `*`. + Mul, + /// The division operator: `/`. + Div, +} diff --git a/src/syntax/lit.rs b/src/syntax/lit.rs new file mode 100644 index 00000000..40b360da --- /dev/null +++ b/src/syntax/lit.rs @@ -0,0 +1,56 @@ +//! Literals. + +use super::*; +use crate::color::RgbaColor; +use crate::eval::DictKey; +use crate::geom::Unit; + +/// A literal. +#[derive(Debug, Clone, PartialEq)] +pub enum Lit { + /// A identifier literal: `left`. + Ident(Ident), + /// A boolean literal: `true`, `false`. + Bool(bool), + /// An integer literal: `120`. + Int(i64), + /// A floating-point literal: `1.2`, `10e-4`. + Float(f64), + /// A length literal: `12pt`, `3cm`. + Length(f64, Unit), + /// A percent literal: `50%`. + /// + /// _Note_: `50%` is stored as `50.0` here, but as `0.5` in the + /// corresponding [value]. + /// + /// [value]: ../../geom/struct.Relative.html + Percent(f64), + /// A color literal: `#ffccee`. + Color(RgbaColor), + /// A string literal: `"hello!"`. + Str(String), + /// A dictionary literal: `(false, 12cm, greeting = "hi")`. + Dict(LitDict), + /// A content literal: `{*Hello* there!}`. + Content(SynTree), +} + +/// A dictionary literal: `(false, 12cm, greeting = "hi")`. +#[derive(Debug, Default, Clone, PartialEq)] +pub struct LitDict(pub Vec); + +/// An entry in a dictionary literal: `false` or `greeting = "hi"`. +#[derive(Debug, Clone, PartialEq)] +pub struct LitDictEntry { + /// The key of the entry if there was one: `greeting`. + pub key: Option>, + /// The value of the entry: `"hi"`. + pub expr: Spanned, +} + +impl LitDict { + /// Create an empty dict literal. + pub fn new() -> Self { + Self::default() + } +} diff --git a/src/syntax/mod.rs b/src/syntax/mod.rs index 8b716da4..81702201 100644 --- a/src/syntax/mod.rs +++ b/src/syntax/mod.rs @@ -1,12 +1,18 @@ //! Syntax types. -pub mod ast; -pub mod token; - +mod expr; mod ident; +mod lit; +mod node; mod span; +mod token; -pub use ast::*; +pub use expr::*; pub use ident::*; +pub use lit::*; +pub use node::*; pub use span::*; pub use token::*; + +/// A collection of nodes which form a tree together with the nodes' children. +pub type SynTree = SpanVec; diff --git a/src/syntax/node.rs b/src/syntax/node.rs new file mode 100644 index 00000000..102ef3b5 --- /dev/null +++ b/src/syntax/node.rs @@ -0,0 +1,118 @@ +//! Syntax tree nodes. + +use super::*; + +/// A syntax node, which encompasses a single logical entity of parsed source +/// code. +#[derive(Debug, Clone, PartialEq)] +pub enum SynNode { + /// Whitespace containing less than two newlines. + Space, + /// Plain text. + Text(String), + + /// A forced line break. + Linebreak, + /// A paragraph break. + Parbreak, + /// Emphasized text was enabled / disabled. + Emph, + /// Strong text was enabled / disabled. + Strong, + + /// A section heading. + Heading(NodeHeading), + /// An optionally syntax-highlighted raw block. + Raw(NodeRaw), + + /// An expression. + Expr(Expr), +} + +/// A section heading. +#[derive(Debug, Clone, PartialEq)] +pub struct NodeHeading { + /// The section depth (how many hashtags minus 1). + pub level: Spanned, + /// The contents of the heading. + pub contents: SynTree, +} + +/// A raw block, rendered in monospace with optional syntax highlighting. +/// +/// Raw blocks start with an arbitrary number of backticks and end with the same +/// number of backticks. If you want to include a sequence of backticks in a raw +/// block, simply surround the block with more backticks. +/// +/// When using at least two backticks, an optional language tag may follow +/// directly after the backticks. This tag defines which language to +/// syntax-highlight the text in. Apart from the language tag and some +/// whitespace trimming discussed below, everything inside a raw block is +/// rendered verbatim, in particular, there are no escape sequences. +/// +/// # Examples +/// - Raw text is surrounded by backticks. +/// ```typst +/// `raw` +/// ``` +/// - An optional language tag may follow directly at the start when the block +/// is surrounded by at least two backticks. +/// ```typst +/// ``rust println!("hello!")``; +/// ``` +/// - Blocks can span multiple lines. Two backticks suffice to be able to +/// specify the language tag, but three are fine, too. +/// ```typst +/// ``rust +/// loop { +/// find_yak().shave(); +/// } +/// `` +/// ``` +/// - Start with a space to omit the language tag (the space will be trimmed +/// from the output) and use more backticks to allow backticks in the raw +/// text. +/// `````typst +/// ```` This contains ```backticks``` and has no leading & trailing spaces. ```` +/// ````` +/// +/// # Trimming +/// If we would always render the raw text between the backticks exactly as +/// given, a few things would become problematic or even impossible: +/// - Typical multiline code blocks (like in the example above) would have an +/// additional newline before and after the code. +/// - Raw text wrapped in more than one backtick could not exist without +/// leading whitespace since the first word would be interpreted as a +/// language tag. +/// - A single backtick without surrounding spaces could not exist as raw text +/// since it would be interpreted as belonging to the opening or closing +/// backticks. +/// +/// To fix these problems, we trim text in multi-backtick blocks as follows: +/// - We trim a single space or a sequence of whitespace followed by a newline +/// at the start. +/// - We trim a single space or a newline followed by a sequence of whitespace +/// at the end. +/// +/// With these rules, a single raw backtick can be produced by the sequence +/// ``` `` ` `` ```, ``` `` unhighlighted text `` ``` has no surrounding +/// spaces and multiline code blocks don't have extra empty lines. Note that +/// you can always force leading or trailing whitespace simply by adding more +/// spaces. +#[derive(Debug, Clone, PartialEq)] +pub struct NodeRaw { + /// An optional identifier specifying the language to syntax-highlight in. + pub lang: Option, + /// The lines of raw text, determined as the raw string between the + /// backticks trimmed according to the above rules and split at newlines. + pub lines: Vec, + /// Whether the element can be layouted inline. + /// + /// - When true, it will be layouted integrated within the surrounding + /// paragraph. + /// - When false, it will be separated into its own paragraph. + /// + /// Single-backtick blocks are always inline-level. Multi-backtick blocks + /// are inline-level when they contain no newlines. + pub inline: bool, +} -- cgit v1.2.3