summaryrefslogtreecommitdiff
path: root/src/syntax
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2022-11-07 12:21:12 +0100
committerLaurenz <laurmaedje@gmail.com>2022-11-07 12:46:05 +0100
commitefd1853d069fbd1476e82d015da4d0d04cfaccc0 (patch)
tree842b745c134306539d10c61be9485794fe8dc7dc /src/syntax
parenteb951c008beea502042db4a3a0e8d1f8b51f6f52 (diff)
Show it!
- New show rule syntax - Set if syntax - Removed wrap syntax
Diffstat (limited to 'src/syntax')
-rw-r--r--src/syntax/ast.rs135
-rw-r--r--src/syntax/highlight.rs12
-rw-r--r--src/syntax/kind.rs70
-rw-r--r--src/syntax/parsing.rs145
-rw-r--r--src/syntax/tokens.rs2
5 files changed, 133 insertions, 231 deletions
diff --git a/src/syntax/ast.rs b/src/syntax/ast.rs
index 61b8f0e6..1b0e8985 100644
--- a/src/syntax/ast.rs
+++ b/src/syntax/ast.rs
@@ -63,11 +63,11 @@ impl Markup {
/// A single piece of markup.
#[derive(Debug, Clone, PartialEq)]
pub enum MarkupNode {
- /// Whitespace containing less than two newlines.
+ /// Whitespace.
Space(Space),
- /// A forced line break.
+ /// A forced line break: `\`.
Linebreak(Linebreak),
- /// Plain text.
+ /// Plain text without markup.
Text(Text),
/// An escape sequence: `\#`, `\u{1F5FA}`.
Escape(Escape),
@@ -76,9 +76,9 @@ pub enum MarkupNode {
Shorthand(Shorthand),
/// A smart quote: `'` or `"`.
SmartQuote(SmartQuote),
- /// Strong markup: `*Strong*`.
+ /// Strong content: `*Strong*`.
Strong(Strong),
- /// Emphasized markup: `_Emphasized_`.
+ /// Emphasized content: `_Emphasized_`.
Emph(Emph),
/// A raw block with optional syntax highlighting: `` `...` ``.
Raw(Raw),
@@ -171,7 +171,7 @@ node! {
}
node! {
- /// Plain text.
+ /// Plain text without markup.
Text
}
@@ -367,12 +367,12 @@ impl ListItem {
}
node! {
- /// An item in an enumeration (ordered list): `1. ...`.
+ /// An item in an enumeration (ordered list): `+ ...` or `1. ...`.
EnumItem
}
impl EnumItem {
- /// The number, if any.
+ /// The explicit numbering, if any: `23.`.
pub fn number(&self) -> Option<usize> {
self.0.children().find_map(|node| match node.kind() {
NodeKind::EnumNumbering(num) => Some(*num),
@@ -434,9 +434,9 @@ pub enum MathNode {
Linebreak(Linebreak),
/// An escape sequence: `\#`, `\u{1F5FA}`.
Escape(Escape),
- /// A atom: `x`, `+`, `12`.
+ /// An atom: `x`, `+`, `12`.
Atom(Atom),
- /// A base with an optional sub- and superscript: `a_1^2`.
+ /// A base with optional sub- and superscripts: `a_1^2`.
Script(Script),
/// A fraction: `x/2`.
Frac(Frac),
@@ -565,9 +565,9 @@ pub enum Expr {
Content(ContentBlock),
/// A grouped expression: `(1 + 2)`.
Parenthesized(Parenthesized),
- /// An array expression: `(1, "hi", 12cm)`.
+ /// An array: `(1, "hi", 12cm)`.
Array(Array),
- /// A dictionary expression: `(thickness: 3pt, pattern: dashed)`.
+ /// A dictionary: `(thickness: 3pt, pattern: dashed)`.
Dict(Dict),
/// A unary operation: `-x`.
Unary(Unary),
@@ -579,16 +579,14 @@ pub enum Expr {
FuncCall(FuncCall),
/// An invocation of a method: `array.push(v)`.
MethodCall(MethodCall),
- /// A closure expression: `(x, y) => z`.
+ /// A closure: `(x, y) => z`.
Closure(Closure),
/// A let binding: `let x = 1`.
Let(LetBinding),
/// A set rule: `set text(...)`.
Set(SetRule),
- /// A show rule: `show node: heading as [*{nody.body}*]`.
+ /// A show rule: `show heading: it => [*{it.body}*]`.
Show(ShowRule),
- /// A wrap rule: `wrap body in columns(2, body)`.
- Wrap(WrapRule),
/// An if-else conditional: `if x { y } else { z }`.
Conditional(Conditional),
/// A while loop: `while x { y }`.
@@ -599,12 +597,12 @@ pub enum Expr {
Import(ModuleImport),
/// A module include: `include "chapter1.typ"`.
Include(ModuleInclude),
- /// A break statement: `break`.
- Break(BreakStmt),
- /// A continue statement: `continue`.
- Continue(ContinueStmt),
- /// A return statement: `return`, `return x + 1`.
- Return(ReturnStmt),
+ /// A break from a loop: `break`.
+ Break(LoopBreak),
+ /// A continue in a loop: `continue`.
+ Continue(LoopContinue),
+ /// A return from a function: `return`, `return x + 1`.
+ Return(FuncReturn),
}
impl TypedNode for Expr {
@@ -625,15 +623,14 @@ impl TypedNode for Expr {
NodeKind::LetBinding => node.cast().map(Self::Let),
NodeKind::SetRule => node.cast().map(Self::Set),
NodeKind::ShowRule => node.cast().map(Self::Show),
- NodeKind::WrapRule => node.cast().map(Self::Wrap),
NodeKind::Conditional => node.cast().map(Self::Conditional),
NodeKind::WhileLoop => node.cast().map(Self::While),
NodeKind::ForLoop => node.cast().map(Self::For),
NodeKind::ModuleImport => node.cast().map(Self::Import),
NodeKind::ModuleInclude => node.cast().map(Self::Include),
- NodeKind::BreakStmt => node.cast().map(Self::Break),
- NodeKind::ContinueStmt => node.cast().map(Self::Continue),
- NodeKind::ReturnStmt => node.cast().map(Self::Return),
+ NodeKind::LoopBreak => node.cast().map(Self::Break),
+ NodeKind::LoopContinue => node.cast().map(Self::Continue),
+ NodeKind::FuncReturn => node.cast().map(Self::Return),
_ => node.cast().map(Self::Lit),
}
}
@@ -656,7 +653,6 @@ impl TypedNode for Expr {
Self::Let(v) => v.as_untyped(),
Self::Set(v) => v.as_untyped(),
Self::Show(v) => v.as_untyped(),
- Self::Wrap(v) => v.as_untyped(),
Self::Conditional(v) => v.as_untyped(),
Self::While(v) => v.as_untyped(),
Self::For(v) => v.as_untyped(),
@@ -679,7 +675,6 @@ impl Expr {
| Self::Let(_)
| Self::Set(_)
| Self::Show(_)
- | Self::Wrap(_)
| Self::Conditional(_)
| Self::While(_)
| Self::For(_)
@@ -723,15 +718,15 @@ pub enum LitKind {
None,
/// The auto literal: `auto`.
Auto,
- /// A boolean literal: `true`, `false`.
+ /// A boolean: `true`, `false`.
Bool(bool),
- /// An integer literal: `120`.
+ /// An integer: `120`.
Int(i64),
- /// A floating-point literal: `1.2`, `10e-4`.
+ /// A floating-point number: `1.2`, `10e-4`.
Float(f64),
- /// A numeric literal with a unit: `12pt`, `3cm`, `2em`, `90deg`, `50%`.
+ /// A numeric value with a unit: `12pt`, `3cm`, `2em`, `90deg`, `50%`.
Numeric(f64, Unit),
- /// A string literal: `"hello!"`.
+ /// A quoted string: `"..."`.
Str(EcoString),
}
@@ -760,7 +755,7 @@ impl ContentBlock {
}
node! {
- /// A parenthesized expression: `(1 + 2)`.
+ /// A grouped expression: `(1 + 2)`.
Parenthesized
}
@@ -853,7 +848,7 @@ impl TypedNode for DictItem {
}
node! {
- /// A pair of a name and an expression: `thickness: 3pt`.
+ /// A named pair: `thickness: 3pt`.
Named
}
@@ -870,7 +865,7 @@ impl Named {
}
node! {
- /// A pair of a string key and an expression: `"spacy key": true`.
+ /// A keyed pair: `"spacy key": true`.
Keyed
}
@@ -1204,7 +1199,7 @@ impl MethodCall {
}
node! {
- /// The arguments to a function: `12, draw: false`.
+ /// A function call's argument list: `(12pt, y)`.
Args
}
@@ -1245,7 +1240,7 @@ impl TypedNode for Arg {
}
node! {
- /// A closure expression: `(x, y) => z`.
+ /// A closure: `(x, y) => z`.
Closure
}
@@ -1347,52 +1342,34 @@ impl SetRule {
pub fn args(&self) -> Args {
self.0.cast_last_child().expect("set rule is missing argument list")
}
+
+ /// A condition under which the set rule applies.
+ pub fn condition(&self) -> Option<Expr> {
+ self.0
+ .children()
+ .skip_while(|child| child.kind() != &NodeKind::If)
+ .find_map(SyntaxNode::cast)
+ }
}
node! {
- /// A show rule: `show node: heading as [*{nody.body}*]`.
+ /// A show rule: `show heading: it => [*{it.body}*]`.
ShowRule
}
impl ShowRule {
- /// The binding to assign to.
- pub fn binding(&self) -> Option<Ident> {
- let mut children = self.0.children();
- children
- .find_map(SyntaxNode::cast)
- .filter(|_| children.any(|child| child.kind() == &NodeKind::Colon))
- }
-
/// The pattern that this rule matches.
- pub fn pattern(&self) -> Expr {
+ pub fn pattern(&self) -> Option<Expr> {
self.0
.children()
.rev()
- .skip_while(|child| child.kind() != &NodeKind::As)
+ .skip_while(|child| child.kind() != &NodeKind::Colon)
.find_map(SyntaxNode::cast)
- .expect("show rule is missing pattern")
}
- /// The expression that realizes the node.
- pub fn body(&self) -> Expr {
- self.0.cast_last_child().expect("show rule is missing body")
- }
-}
-
-node! {
- /// A wrap rule: `wrap body in columns(2, body)`.
- WrapRule
-}
-
-impl WrapRule {
- /// The binding to assign the remaining markup to.
- pub fn binding(&self) -> Ident {
- self.0.cast_first_child().expect("wrap rule is missing binding")
- }
-
- /// The expression to evaluate.
- pub fn body(&self) -> Expr {
- self.0.cast_last_child().expect("wrap rule is missing body")
+ /// The transformation recipe.
+ pub fn transform(&self) -> Expr {
+ self.0.cast_last_child().expect("show rule is missing transform")
}
}
@@ -1462,7 +1439,7 @@ impl ForLoop {
}
node! {
- /// A for-in loop: `for x in y { z }`.
+ /// A for loop's destructuring pattern: `x` or `x, y`.
ForPattern
}
@@ -1533,21 +1510,21 @@ impl ModuleInclude {
}
node! {
- /// A break expression: `break`.
- BreakStmt
+ /// A break from a loop: `break`.
+ LoopBreak
}
node! {
- /// A continue expression: `continue`.
- ContinueStmt
+ /// A continue in a loop: `continue`.
+ LoopContinue
}
node! {
- /// A return expression: `return`, `return x + 1`.
- ReturnStmt
+ /// A return from a function: `return`, `return x + 1`.
+ FuncReturn
}
-impl ReturnStmt {
+impl FuncReturn {
/// The expression to return.
pub fn body(&self) -> Option<Expr> {
self.0.cast_last_child()
@@ -1555,7 +1532,7 @@ impl ReturnStmt {
}
node! {
- /// An identifier.
+ /// An identifier: `it`.
Ident
}
diff --git a/src/syntax/highlight.rs b/src/syntax/highlight.rs
index d5345fab..34cce4c0 100644
--- a/src/syntax/highlight.rs
+++ b/src/syntax/highlight.rs
@@ -257,7 +257,6 @@ impl Category {
NodeKind::Let => Some(Category::Keyword),
NodeKind::Set => Some(Category::Keyword),
NodeKind::Show => Some(Category::Keyword),
- NodeKind::Wrap => Some(Category::Keyword),
NodeKind::If => Some(Category::Keyword),
NodeKind::Else => Some(Category::Keyword),
NodeKind::For => Some(Category::Keyword),
@@ -269,7 +268,6 @@ impl Category {
NodeKind::Import => Some(Category::Keyword),
NodeKind::Include => Some(Category::Keyword),
NodeKind::From => Some(Category::Keyword),
- NodeKind::As => Some(Category::Keyword),
NodeKind::Markup { .. } => match parent.kind() {
NodeKind::DescItem
@@ -316,8 +314,7 @@ impl Category {
if parent
.children()
.rev()
- .skip_while(|child| child.kind() != &NodeKind::As)
- .take_while(|child| child.kind() != &NodeKind::Colon)
+ .skip_while(|child| child.kind() != &NodeKind::Colon)
.find(|c| matches!(c.kind(), NodeKind::Ident(_)))
.map_or(false, |ident| std::ptr::eq(ident, child)) =>
{
@@ -349,7 +346,6 @@ impl Category {
NodeKind::LetBinding => None,
NodeKind::SetRule => None,
NodeKind::ShowRule => None,
- NodeKind::WrapRule => None,
NodeKind::Conditional => None,
NodeKind::WhileLoop => None,
NodeKind::ForLoop => None,
@@ -357,9 +353,9 @@ impl Category {
NodeKind::ModuleImport => None,
NodeKind::ImportItems => None,
NodeKind::ModuleInclude => None,
- NodeKind::BreakStmt => None,
- NodeKind::ContinueStmt => None,
- NodeKind::ReturnStmt => None,
+ NodeKind::LoopBreak => None,
+ NodeKind::LoopContinue => None,
+ NodeKind::FuncReturn => None,
NodeKind::Error(_, _) => Some(Category::Error),
}
diff --git a/src/syntax/kind.rs b/src/syntax/kind.rs
index 1568693b..1282b592 100644
--- a/src/syntax/kind.rs
+++ b/src/syntax/kind.rs
@@ -106,8 +106,6 @@ pub enum NodeKind {
Set,
/// The `show` keyword.
Show,
- /// The `wrap` keyword.
- Wrap,
/// The `if` keyword.
If,
/// The `else` keyword.
@@ -130,8 +128,6 @@ pub enum NodeKind {
Include,
/// The `from` keyword.
From,
- /// The `as` keyword.
- As,
/// Markup of which all lines must have a minimal indentation.
///
@@ -139,7 +135,7 @@ pub enum NodeKind {
/// started, but to the right of which column all markup elements must be,
/// so it is zero except inside indent-aware constructs like lists.
Markup { min_indent: usize },
- /// Consecutive text without markup.
+ /// Plain text without markup.
Text(EcoString),
/// A forced line break: `\`.
Linebreak,
@@ -150,9 +146,9 @@ pub enum NodeKind {
Shorthand(char),
/// A smart quote: `'` or `"`.
SmartQuote { double: bool },
- /// Strong markup: `*Strong*`.
+ /// Strong content: `*Strong*`.
Strong,
- /// Emphasized markup: `_Emphasized_`.
+ /// Emphasized content: `_Emphasized_`.
Emph,
/// A raw block with optional syntax highlighting: `` `...` ``.
Raw(Arc<RawKind>),
@@ -164,26 +160,26 @@ pub enum NodeKind {
Ref(EcoString),
/// A section heading: `= Introduction`.
Heading,
- /// An item of an unordered list: `- ...`.
+ /// An item in an unordered list: `- ...`.
ListItem,
- /// An item of an enumeration (ordered list): `+ ...` or `1. ...`.
+ /// An item in an enumeration (ordered list): `+ ...` or `1. ...`.
EnumItem,
/// An explicit enumeration numbering: `23.`.
EnumNumbering(usize),
- /// An item of a description list: `/ Term: Details.
+ /// An item in a description list: `/ Term: Details`.
DescItem,
- /// A math formula: `$x$`, `$ x^2 $`.
+ /// A mathematical formula: `$x$`, `$ x^2 $`.
Math,
- /// An atom in a math formula: `x`, `+`, `12`.
+ /// An atom in a formula: `x`, `+`, `12`.
Atom(EcoString),
- /// A base with optional sub- and superscript in a math formula: `a_1^2`.
+ /// A base with optional sub- and superscripts in a formula: `a_1^2`.
Script,
- /// A fraction in a math formula: `x/2`.
+ /// A fraction in a formula: `x/2`.
Frac,
- /// An alignment indicator in a math formula: `&`, `&&`.
+ /// An alignment indicator in a formula: `&`, `&&`.
Align,
- /// An identifier: `center`.
+ /// An identifier: `it`.
Ident(EcoString),
/// A boolean: `true`, `false`.
Bool(bool),
@@ -219,9 +215,9 @@ pub enum NodeKind {
FuncCall,
/// An invocation of a method: `array.push(v)`.
MethodCall,
- /// A function call's argument list: `(x, y)`.
+ /// A function call's argument list: `(12pt, y)`.
Args,
- /// Spreaded arguments or a argument sink: `..x`.
+ /// Spreaded arguments or an argument sink: `..x`.
Spread,
/// A closure: `(x, y) => z`.
Closure,
@@ -231,15 +227,13 @@ pub enum NodeKind {
LetBinding,
/// A set rule: `set text(...)`.
SetRule,
- /// A show rule: `show node: heading as [*{nody.body}*]`.
+ /// A show rule: `show heading: it => [*{it.body}*]`.
ShowRule,
- /// A wrap rule: `wrap body in columns(2, body)`.
- WrapRule,
/// An if-else conditional: `if x { y } else { z }`.
Conditional,
- /// A while loop: `while x { ... }`.
+ /// A while loop: `while x { y }`.
WhileLoop,
- /// A for loop: `for x in y { ... }`.
+ /// A for loop: `for x in y { z }`.
ForLoop,
/// A for loop's destructuring pattern: `x` or `x, y`.
ForPattern,
@@ -249,12 +243,12 @@ pub enum NodeKind {
ImportItems,
/// A module include: `include "chapter1.typ"`.
ModuleInclude,
- /// A break statement: `break`.
- BreakStmt,
- /// A continue statement: `continue`.
- ContinueStmt,
- /// A return statement: `return x + 1`.
- ReturnStmt,
+ /// A break from a loop: `break`.
+ LoopBreak,
+ /// A continue in a loop: `continue`.
+ LoopContinue,
+ /// A return from a function: `return`, `return x + 1`.
+ FuncReturn,
/// An invalid sequence of characters.
Error(ErrorPos, EcoString),
@@ -367,7 +361,6 @@ impl NodeKind {
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`",
@@ -379,7 +372,6 @@ impl NodeKind {
Self::Import => "keyword `import`",
Self::Include => "keyword `include`",
Self::From => "keyword `from`",
- Self::As => "keyword `as`",
Self::Markup { .. } => "markup",
Self::Text(_) => "text",
Self::Linebreak => "linebreak",
@@ -426,7 +418,6 @@ impl NodeKind {
Self::LetBinding => "`let` expression",
Self::SetRule => "`set` expression",
Self::ShowRule => "`show` expression",
- Self::WrapRule => "`wrap` expression",
Self::Conditional => "`if` expression",
Self::WhileLoop => "while-loop expression",
Self::ForLoop => "for-loop expression",
@@ -434,9 +425,9 @@ impl NodeKind {
Self::ModuleImport => "`import` expression",
Self::ImportItems => "import items",
Self::ModuleInclude => "`include` expression",
- Self::BreakStmt => "`break` expression",
- Self::ContinueStmt => "`continue` expression",
- Self::ReturnStmt => "`return` expression",
+ Self::LoopBreak => "`break` expression",
+ Self::LoopContinue => "`continue` expression",
+ Self::FuncReturn => "`return` expression",
Self::Error(_, _) => "syntax error",
}
}
@@ -488,7 +479,6 @@ impl Hash for NodeKind {
Self::Let => {}
Self::Set => {}
Self::Show => {}
- Self::Wrap => {}
Self::If => {}
Self::Else => {}
Self::For => {}
@@ -500,7 +490,6 @@ impl Hash for NodeKind {
Self::Import => {}
Self::Include => {}
Self::From => {}
- Self::As => {}
Self::Markup { min_indent } => min_indent.hash(state),
Self::Text(s) => s.hash(state),
Self::Linebreak => {}
@@ -548,7 +537,6 @@ impl Hash for NodeKind {
Self::LetBinding => {}
Self::SetRule => {}
Self::ShowRule => {}
- Self::WrapRule => {}
Self::Conditional => {}
Self::WhileLoop => {}
Self::ForLoop => {}
@@ -556,9 +544,9 @@ impl Hash for NodeKind {
Self::ModuleImport => {}
Self::ImportItems => {}
Self::ModuleInclude => {}
- Self::BreakStmt => {}
- Self::ContinueStmt => {}
- Self::ReturnStmt => {}
+ Self::LoopBreak => {}
+ Self::LoopContinue => {}
+ Self::FuncReturn => {}
Self::Error(pos, msg) => (pos, msg).hash(state),
}
}
diff --git a/src/syntax/parsing.rs b/src/syntax/parsing.rs
index fecc527c..acf76b7e 100644
--- a/src/syntax/parsing.rs
+++ b/src/syntax/parsing.rs
@@ -208,7 +208,6 @@ where
});
}
-/// Parse a markup node.
fn markup_node(p: &mut Parser, at_start: &mut bool) {
let Some(token) = p.peek() else { return };
match token {
@@ -245,10 +244,10 @@ fn markup_node(p: &mut Parser, at_start: &mut bool) {
NodeKind::Eq => heading(p, *at_start),
// Lists.
- NodeKind::Minus => list_node(p, *at_start),
- NodeKind::Plus | NodeKind::EnumNumbering(_) => enum_node(p, *at_start),
+ NodeKind::Minus => list_item(p, *at_start),
+ NodeKind::Plus | NodeKind::EnumNumbering(_) => enum_item(p, *at_start),
NodeKind::Slash => {
- desc_node(p, *at_start).ok();
+ desc_item(p, *at_start).ok();
}
NodeKind::Colon => {
let marker = p.marker();
@@ -261,7 +260,6 @@ fn markup_node(p: &mut Parser, at_start: &mut bool) {
| NodeKind::Let
| NodeKind::Set
| NodeKind::Show
- | NodeKind::Wrap
| NodeKind::If
| NodeKind::While
| NodeKind::For
@@ -282,7 +280,6 @@ fn markup_node(p: &mut Parser, at_start: &mut bool) {
*at_start = false;
}
-/// Parse strong content.
fn strong(p: &mut Parser) {
p.perform(NodeKind::Strong, |p| {
p.start_group(Group::Strong);
@@ -291,7 +288,6 @@ fn strong(p: &mut Parser) {
})
}
-/// Parse emphasized content.
fn emph(p: &mut Parser) {
p.perform(NodeKind::Emph, |p| {
p.start_group(Group::Emph);
@@ -300,7 +296,6 @@ fn emph(p: &mut Parser) {
})
}
-/// Parse a heading.
fn heading(p: &mut Parser, at_start: bool) {
let marker = p.marker();
let current_start = p.current_start();
@@ -317,8 +312,7 @@ fn heading(p: &mut Parser, at_start: bool) {
}
}
-/// Parse a single list item.
-fn list_node(p: &mut Parser, at_start: bool) {
+fn list_item(p: &mut Parser, at_start: bool) {
let marker = p.marker();
let text: EcoString = p.peek_src().into();
p.assert(NodeKind::Minus);
@@ -332,8 +326,7 @@ fn list_node(p: &mut Parser, at_start: bool) {
}
}
-/// Parse a single enum item.
-fn enum_node(p: &mut Parser, at_start: bool) {
+fn enum_item(p: &mut Parser, at_start: bool) {
let marker = p.marker();
let text: EcoString = p.peek_src().into();
p.eat();
@@ -347,8 +340,7 @@ fn enum_node(p: &mut Parser, at_start: bool) {
}
}
-/// Parse a single description list item.
-fn desc_node(p: &mut Parser, at_start: bool) -> ParseResult {
+fn desc_item(p: &mut Parser, at_start: bool) -> ParseResult {
let marker = p.marker();
let text: EcoString = p.peek_src().into();
p.eat();
@@ -366,7 +358,6 @@ fn desc_node(p: &mut Parser, at_start: bool) -> ParseResult {
Ok(())
}
-/// Parse an expression within a markup mode.
fn markup_expr(p: &mut Parser) {
// Does the expression need termination or can content follow directly?
let stmt = matches!(
@@ -375,7 +366,6 @@ fn markup_expr(p: &mut Parser) {
NodeKind::Let
| NodeKind::Set
| NodeKind::Show
- | NodeKind::Wrap
| NodeKind::Import
| NodeKind::Include
)
@@ -389,7 +379,6 @@ fn markup_expr(p: &mut Parser) {
p.end_group();
}
-/// Parse math.
fn math(p: &mut Parser) {
p.perform(NodeKind::Math, |p| {
p.start_group(Group::Math);
@@ -400,12 +389,10 @@ fn math(p: &mut Parser) {
});
}
-/// Parse a math node.
fn math_node(p: &mut Parser) {
math_node_prec(p, 0, None)
}
-/// Parse a math node with operators having at least the minimum precedence.
fn math_node_prec(p: &mut Parser, min_prec: usize, stop: Option<NodeKind>) {
let marker = p.marker();
math_primary(p);
@@ -457,19 +444,18 @@ fn math_primary(p: &mut Parser) {
| NodeKind::Ident(_) => p.eat(),
// Groups.
- NodeKind::LeftParen => group(p, Group::Paren, '(', ')'),
- NodeKind::LeftBracket => group(p, Group::Bracket, '[', ']'),
- NodeKind::LeftBrace => group(p, Group::Brace, '{', '}'),
+ NodeKind::LeftParen => math_group(p, Group::Paren, '(', ')'),
+ NodeKind::LeftBracket => math_group(p, Group::Bracket, '[', ']'),
+ NodeKind::LeftBrace => math_group(p, Group::Brace, '{', '}'),
// Alignment indactor.
- NodeKind::Amp => align(p),
+ NodeKind::Amp => math_align(p),
_ => p.unexpected(),
}
}
-/// Parse grouped math.
-fn group(p: &mut Parser, group: Group, l: char, r: char) {
+fn math_group(p: &mut Parser, group: Group, l: char, r: char) {
p.perform(NodeKind::Math, |p| {
let marker = p.marker();
p.start_group(group);
@@ -483,15 +469,13 @@ fn group(p: &mut Parser, group: Group, l: char, r: char) {
})
}
-/// Parse an alignment indicator.
-fn align(p: &mut Parser) {
+fn math_align(p: &mut Parser) {
p.perform(NodeKind::Align, |p| {
p.assert(NodeKind::Amp);
while p.eat_if(NodeKind::Amp) {}
})
}
-/// Parse an expression.
fn expr(p: &mut Parser) -> ParseResult {
expr_prec(p, false, 0)
}
@@ -571,7 +555,6 @@ fn expr_prec(p: &mut Parser, atomic: bool, min_prec: usize) -> ParseResult {
Ok(())
}
-/// Parse a primary expression.
fn primary(p: &mut Parser, atomic: bool) -> ParseResult {
if literal(p) {
return Ok(());
@@ -599,18 +582,17 @@ fn primary(p: &mut Parser, atomic: bool) -> ParseResult {
Some(NodeKind::LeftBracket) => Ok(content_block(p)),
// Keywords.
- Some(NodeKind::Let) => let_expr(p),
- Some(NodeKind::Set) => set_expr(p),
- Some(NodeKind::Show) => show_expr(p),
- Some(NodeKind::Wrap) => wrap_expr(p),
- Some(NodeKind::If) => if_expr(p),
- Some(NodeKind::While) => while_expr(p),
- Some(NodeKind::For) => for_expr(p),
- Some(NodeKind::Import) => import_expr(p),
- Some(NodeKind::Include) => include_expr(p),
- Some(NodeKind::Break) => break_expr(p),
- Some(NodeKind::Continue) => continue_expr(p),
- Some(NodeKind::Return) => return_expr(p),
+ Some(NodeKind::Let) => let_binding(p),
+ Some(NodeKind::Set) => set_rule(p),
+ Some(NodeKind::Show) => show_rule(p),
+ Some(NodeKind::If) => conditional(p),
+ Some(NodeKind::While) => while_loop(p),
+ Some(NodeKind::For) => for_loop(p),
+ Some(NodeKind::Import) => module_import(p),
+ Some(NodeKind::Include) => module_include(p),
+ Some(NodeKind::Break) => break_stmt(p),
+ Some(NodeKind::Continue) => continue_stmt(p),
+ Some(NodeKind::Return) => return_stmt(p),
Some(NodeKind::Error(_, _)) => {
p.eat();
@@ -625,10 +607,8 @@ fn primary(p: &mut Parser, atomic: bool) -> ParseResult {
}
}
-/// Parse a literal.
fn literal(p: &mut Parser) -> bool {
match p.peek() {
- // Basic values.
Some(
NodeKind::None
| NodeKind::Auto
@@ -645,7 +625,6 @@ fn literal(p: &mut Parser) -> bool {
}
}
-/// Parse an identifier.
fn ident(p: &mut Parser) -> ParseResult {
match p.peek() {
Some(NodeKind::Ident(_)) => {
@@ -762,8 +741,6 @@ fn collection(p: &mut Parser, keyed: bool) -> (CollectionKind, usize) {
(kind, items)
}
-/// Parse an expression or a named pair, returning whether it's a spread or a
-/// named pair.
fn item(p: &mut Parser, keyed: bool) -> ParseResult<NodeKind> {
let marker = p.marker();
if p.eat_if(NodeKind::Dots) {
@@ -806,8 +783,6 @@ fn item(p: &mut Parser, keyed: bool) -> ParseResult<NodeKind> {
}
}
-/// Convert a collection into an array, producing errors for anything other than
-/// expressions.
fn array(p: &mut Parser, marker: Marker) {
marker.filter_children(p, |x| match x.kind() {
NodeKind::Named | NodeKind::Keyed => Err("expected expression"),
@@ -816,8 +791,6 @@ fn array(p: &mut Parser, marker: Marker) {
marker.end(p, NodeKind::Array);
}
-/// Convert a collection into a dictionary, producing errors for anything other
-/// than named and keyed pairs.
fn dict(p: &mut Parser, marker: Marker) {
let mut used = HashSet::new();
marker.filter_children(p, |x| match x.kind() {
@@ -838,8 +811,6 @@ fn dict(p: &mut Parser, marker: Marker) {
marker.end(p, NodeKind::Dict);
}
-/// Convert a collection into a list of parameters, producing errors for
-/// anything other than identifiers, spread operations and named pairs.
fn params(p: &mut Parser, marker: Marker) {
marker.filter_children(p, |x| match x.kind() {
kind if kind.is_paren() => Ok(()),
@@ -866,7 +837,6 @@ fn code_block(p: &mut Parser) {
});
}
-/// Parse expressions.
fn code(p: &mut Parser) {
while !p.eof() {
p.start_group(Group::Expr);
@@ -880,7 +850,6 @@ fn code(p: &mut Parser) {
}
}
-/// Parse a content block: `[...]`.
fn content_block(p: &mut Parser) {
p.perform(NodeKind::ContentBlock, |p| {
p.start_group(Group::Bracket);
@@ -889,7 +858,6 @@ fn content_block(p: &mut Parser) {
});
}
-/// Parse the arguments to a function call.
fn args(p: &mut Parser) -> ParseResult {
match p.peek_direct() {
Some(NodeKind::LeftParen) => {}
@@ -931,8 +899,7 @@ fn args(p: &mut Parser) -> ParseResult {
Ok(())
}
-/// Parse a let expression.
-fn let_expr(p: &mut Parser) -> ParseResult {
+fn let_binding(p: &mut Parser) -> ParseResult {
p.perform(NodeKind::LetBinding, |p| {
p.assert(NodeKind::Let);
@@ -965,45 +932,30 @@ fn let_expr(p: &mut Parser) -> ParseResult {
})
}
-/// Parse a set expression.
-fn set_expr(p: &mut Parser) -> ParseResult {
+fn set_rule(p: &mut Parser) -> ParseResult {
p.perform(NodeKind::SetRule, |p| {
p.assert(NodeKind::Set);
ident(p)?;
- args(p)
+ args(p)?;
+ if p.eat_if(NodeKind::If) {
+ expr(p)?;
+ }
+ Ok(())
})
}
-/// Parse a show expression.
-fn show_expr(p: &mut Parser) -> ParseResult {
+fn show_rule(p: &mut Parser) -> ParseResult {
p.perform(NodeKind::ShowRule, |p| {
p.assert(NodeKind::Show);
- let marker = p.marker();
expr(p)?;
if p.eat_if(NodeKind::Colon) {
- marker.filter_children(p, |child| match child.kind() {
- NodeKind::Ident(_) | NodeKind::Colon => Ok(()),
- _ => Err("expected identifier"),
- });
expr(p)?;
}
- p.expect(NodeKind::As)?;
- expr(p)
- })
-}
-
-/// Parse a wrap expression.
-fn wrap_expr(p: &mut Parser) -> ParseResult {
- p.perform(NodeKind::WrapRule, |p| {
- p.assert(NodeKind::Wrap);
- ident(p)?;
- p.expect(NodeKind::In)?;
- expr(p)
+ Ok(())
})
}
-/// Parse an if-else expresion.
-fn if_expr(p: &mut Parser) -> ParseResult {
+fn conditional(p: &mut Parser) -> ParseResult {
p.perform(NodeKind::Conditional, |p| {
p.assert(NodeKind::If);
@@ -1012,7 +964,7 @@ fn if_expr(p: &mut Parser) -> ParseResult {
if p.eat_if(NodeKind::Else) {
if p.at(NodeKind::If) {
- if_expr(p)?;
+ conditional(p)?;
} else {
body(p)?;
}
@@ -1022,8 +974,7 @@ fn if_expr(p: &mut Parser) -> ParseResult {
})
}
-/// Parse a while expresion.
-fn while_expr(p: &mut Parser) -> ParseResult {
+fn while_loop(p: &mut Parser) -> ParseResult {
p.perform(NodeKind::WhileLoop, |p| {
p.assert(NodeKind::While);
expr(p)?;
@@ -1031,8 +982,7 @@ fn while_expr(p: &mut Parser) -> ParseResult {
})
}
-/// Parse a for-in expression.
-fn for_expr(p: &mut Parser) -> ParseResult {
+fn for_loop(p: &mut Parser) -> ParseResult {
p.perform(NodeKind::ForLoop, |p| {
p.assert(NodeKind::For);
for_pattern(p)?;
@@ -1042,7 +992,6 @@ fn for_expr(p: &mut Parser) -> ParseResult {
})
}
-/// Parse a for loop pattern.
fn for_pattern(p: &mut Parser) -> ParseResult {
p.perform(NodeKind::ForPattern, |p| {
ident(p)?;
@@ -1053,8 +1002,7 @@ fn for_pattern(p: &mut Parser) -> ParseResult {
})
}
-/// Parse an import expression.
-fn import_expr(p: &mut Parser) -> ParseResult {
+fn module_import(p: &mut Parser) -> ParseResult {
p.perform(NodeKind::ModuleImport, |p| {
p.assert(NodeKind::Import);
@@ -1081,33 +1029,29 @@ fn import_expr(p: &mut Parser) -> ParseResult {
})
}
-/// Parse an include expression.
-fn include_expr(p: &mut Parser) -> ParseResult {
+fn module_include(p: &mut Parser) -> ParseResult {
p.perform(NodeKind::ModuleInclude, |p| {
p.assert(NodeKind::Include);
expr(p)
})
}
-/// Parse a break expression.
-fn break_expr(p: &mut Parser) -> ParseResult {
- p.perform(NodeKind::BreakStmt, |p| {
+fn break_stmt(p: &mut Parser) -> ParseResult {
+ p.perform(NodeKind::LoopBreak, |p| {
p.assert(NodeKind::Break);
Ok(())
})
}
-/// Parse a continue expression.
-fn continue_expr(p: &mut Parser) -> ParseResult {
- p.perform(NodeKind::ContinueStmt, |p| {
+fn continue_stmt(p: &mut Parser) -> ParseResult {
+ p.perform(NodeKind::LoopContinue, |p| {
p.assert(NodeKind::Continue);
Ok(())
})
}
-/// Parse a return expression.
-fn return_expr(p: &mut Parser) -> ParseResult {
- p.perform(NodeKind::ReturnStmt, |p| {
+fn return_stmt(p: &mut Parser) -> ParseResult {
+ p.perform(NodeKind::FuncReturn, |p| {
p.assert(NodeKind::Return);
if !p.at(NodeKind::Comma) && !p.eof() {
expr(p)?;
@@ -1116,7 +1060,6 @@ fn return_expr(p: &mut Parser) -> ParseResult {
})
}
-/// Parse a control flow body.
fn body(p: &mut Parser) -> ParseResult {
match p.peek() {
Some(NodeKind::LeftBracket) => Ok(content_block(p)),
diff --git a/src/syntax/tokens.rs b/src/syntax/tokens.rs
index f18bb780..b27832c5 100644
--- a/src/syntax/tokens.rs
+++ b/src/syntax/tokens.rs
@@ -613,12 +613,10 @@ fn keyword(ident: &str) -> Option<NodeKind> {
"let" => NodeKind::Let,
"set" => NodeKind::Set,
"show" => NodeKind::Show,
- "wrap" => NodeKind::Wrap,
"if" => NodeKind::If,
"else" => NodeKind::Else,
"for" => NodeKind::For,
"in" => NodeKind::In,
- "as" => NodeKind::As,
"while" => NodeKind::While,
"break" => NodeKind::Break,
"continue" => NodeKind::Continue,