summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/eval/capture.rs18
-rw-r--r--src/eval/mod.rs46
-rw-r--r--src/eval/value.rs12
-rw-r--r--src/library/math/mod.rs2
-rw-r--r--src/library/text/mod.rs2
-rw-r--r--src/parse/incremental.rs12
-rw-r--r--src/parse/mod.rs184
-rw-r--r--src/parse/parser.rs14
-rw-r--r--src/parse/tokens.rs16
-rw-r--r--src/syntax/ast.rs120
-rw-r--r--src/syntax/highlight.rs26
-rw-r--r--src/syntax/mod.rs92
12 files changed, 267 insertions, 277 deletions
diff --git a/src/eval/capture.rs b/src/eval/capture.rs
index fd6b0101..b27aceb7 100644
--- a/src/eval/capture.rs
+++ b/src/eval/capture.rs
@@ -49,6 +49,15 @@ impl<'a> CapturesVisitor<'a> {
// through the expressions that contain them).
Some(Expr::Ident(ident)) => self.capture(ident),
+ // Blocks and templates create a scope.
+ Some(Expr::Code(_) | Expr::Template(_)) => {
+ self.internal.enter();
+ for child in node.children() {
+ self.visit(child);
+ }
+ self.internal.exit();
+ }
+
// A closure contains parameter bindings, which are bound before the
// body is evaluated. Care must be taken so that the default values
// of named parameters cannot access previous parameter bindings.
@@ -103,15 +112,6 @@ impl<'a> CapturesVisitor<'a> {
}
}
- // Blocks and templates create a scope.
- Some(Expr::Block(_) | Expr::Template(_)) => {
- self.internal.enter();
- for child in node.children() {
- self.visit(child);
- }
- self.internal.exit();
- }
-
// Everything else is traversed from left to right.
_ => {
for child in node.children() {
diff --git a/src/eval/mod.rs b/src/eval/mod.rs
index 590b8463..6a918dbd 100644
--- a/src/eval/mod.rs
+++ b/src/eval/mod.rs
@@ -202,11 +202,11 @@ impl Eval for Expr {
match self {
Self::Lit(v) => v.eval(ctx, scp),
Self::Ident(v) => v.eval(ctx, scp),
+ Self::Code(v) => v.eval(ctx, scp),
+ Self::Template(v) => v.eval(ctx, scp).map(Value::Template),
Self::Array(v) => v.eval(ctx, scp).map(Value::Array),
Self::Dict(v) => v.eval(ctx, scp).map(Value::Dict),
- Self::Template(v) => v.eval(ctx, scp).map(Value::Template),
Self::Group(v) => v.eval(ctx, scp),
- Self::Block(v) => v.eval(ctx, scp),
Self::Call(v) => v.eval(ctx, scp),
Self::Closure(v) => v.eval(ctx, scp),
Self::With(v) => v.eval(ctx, scp),
@@ -260,25 +260,23 @@ impl Eval for Ident {
}
}
-impl Eval for ArrayExpr {
- type Output = Array;
+impl Eval for CodeBlock {
+ type Output = Value;
fn eval(&self, ctx: &mut Context, scp: &mut Scopes) -> EvalResult<Self::Output> {
- self.items().map(|expr| expr.eval(ctx, scp)).collect()
- }
-}
+ scp.enter();
-impl Eval for DictExpr {
- type Output = Dict;
+ let mut output = Value::None;
+ for expr in self.exprs() {
+ output = join_result(output, expr.eval(ctx, scp), expr.span())?;
+ }
- fn eval(&self, ctx: &mut Context, scp: &mut Scopes) -> EvalResult<Self::Output> {
- self.items()
- .map(|x| Ok((x.name().take(), x.expr().eval(ctx, scp)?)))
- .collect()
+ scp.exit();
+ Ok(output)
}
}
-impl Eval for TemplateExpr {
+impl Eval for TemplateBlock {
type Output = Template;
fn eval(&self, ctx: &mut Context, scp: &mut Scopes) -> EvalResult<Self::Output> {
@@ -297,19 +295,21 @@ impl Eval for GroupExpr {
}
}
-impl Eval for BlockExpr {
- type Output = Value;
+impl Eval for ArrayExpr {
+ type Output = Array;
fn eval(&self, ctx: &mut Context, scp: &mut Scopes) -> EvalResult<Self::Output> {
- scp.enter();
+ self.items().map(|expr| expr.eval(ctx, scp)).collect()
+ }
+}
- let mut output = Value::None;
- for expr in self.exprs() {
- output = join_result(output, expr.eval(ctx, scp), expr.span())?;
- }
+impl Eval for DictExpr {
+ type Output = Dict;
- scp.exit();
- Ok(output)
+ fn eval(&self, ctx: &mut Context, scp: &mut Scopes) -> EvalResult<Self::Output> {
+ self.items()
+ .map(|x| Ok((x.name().take(), x.expr().eval(ctx, scp)?)))
+ .collect()
}
}
diff --git a/src/eval/value.rs b/src/eval/value.rs
index 009a1463..7d41bff5 100644
--- a/src/eval/value.rs
+++ b/src/eval/value.rs
@@ -5,7 +5,7 @@ use std::hash::{Hash, Hasher};
use std::sync::Arc;
use super::{ops, Args, Array, Class, Dict, Func, Layout, Template};
-use crate::diag::StrResult;
+use crate::diag::{with_alternative, StrResult};
use crate::geom::{Angle, Color, Fractional, Length, Linear, Relative, RgbaColor};
use crate::syntax::Spanned;
use crate::util::EcoString;
@@ -533,16 +533,6 @@ impl<T: Cast> Cast for Smart<T> {
}
}
-/// Transform `expected X, found Y` into `expected X or A, found Y`.
-pub fn with_alternative(msg: String, alt: &str) -> String {
- let mut parts = msg.split(", found ");
- if let (Some(a), Some(b)) = (parts.next(), parts.next()) {
- format!("{} or {}, found {}", a, alt, b)
- } else {
- msg
- }
-}
-
#[cfg(test)]
mod tests {
use super::*;
diff --git a/src/library/math/mod.rs b/src/library/math/mod.rs
index 761b4480..c5b79117 100644
--- a/src/library/math/mod.rs
+++ b/src/library/math/mod.rs
@@ -1,3 +1,5 @@
+//! Mathematical formulas.
+
use crate::library::prelude::*;
/// A mathematical formula.
diff --git a/src/library/text/mod.rs b/src/library/text/mod.rs
index 1ce3518c..197971d0 100644
--- a/src/library/text/mod.rs
+++ b/src/library/text/mod.rs
@@ -1,4 +1,4 @@
-//! Text shaping and paragraph layout.
+//! Text handling and paragraph layout.
mod deco;
mod link;
diff --git a/src/parse/incremental.rs b/src/parse/incremental.rs
index 4736845f..759b3a68 100644
--- a/src/parse/incremental.rs
+++ b/src/parse/incremental.rs
@@ -136,8 +136,8 @@ impl Reparser<'_> {
let superseded_span = pos.offset .. pos.offset + prev_len;
let func: Option<ReparseMode> = match child.kind() {
- NodeKind::Template => Some(ReparseMode::Template),
- NodeKind::Block => Some(ReparseMode::Block),
+ NodeKind::CodeBlock => Some(ReparseMode::Code),
+ NodeKind::TemplateBlock => Some(ReparseMode::Template),
_ => None,
};
@@ -211,7 +211,7 @@ impl Reparser<'_> {
}
let (newborns, terminated, amount) = match mode {
- ReparseMode::Block => reparse_block(
+ ReparseMode::Code => reparse_block(
&prefix,
&self.src[newborn_span.start ..],
newborn_span.len(),
@@ -292,9 +292,9 @@ impl SearchState {
/// Which reparse function to choose for a span of elements.
#[derive(Clone, Copy, Debug, PartialEq)]
enum ReparseMode {
- /// Reparse a code block with its braces.
- Block,
- /// Reparse a template, including its square brackets.
+ /// Reparse a code block, including its braces.
+ Code,
+ /// Reparse a template block, including its square brackets.
Template,
/// Reparse elements of the markup. The variant carries whether the node is
/// `at_start` and the minimum indent of the containing markup node.
diff --git a/src/parse/mod.rs b/src/parse/mod.rs
index 11ce872f..833a5b33 100644
--- a/src/parse/mod.rs
+++ b/src/parse/mod.rs
@@ -28,8 +28,57 @@ pub fn parse(src: &str) -> Arc<GreenNode> {
}
}
-/// Parse some markup without the topmost node. Returns `Some` if all of the
-/// input was consumed.
+/// Reparse a code block.
+///
+/// Returns `Some` if all of the input was consumed.
+pub fn reparse_block(
+ prefix: &str,
+ src: &str,
+ end_pos: usize,
+) -> Option<(Vec<Green>, bool, usize)> {
+ let mut p = Parser::with_prefix(prefix, src, TokenMode::Code);
+ if !p.at(&NodeKind::LeftBrace) {
+ return None;
+ }
+
+ block(&mut p);
+
+ let (mut green, terminated) = p.consume()?;
+ let first = green.remove(0);
+ if first.len() != end_pos {
+ return None;
+ }
+
+ Some((vec![first], terminated, 1))
+}
+
+/// Reparse a template literal.
+///
+/// Returns `Some` if all of the input was consumed.
+pub fn reparse_template(
+ prefix: &str,
+ src: &str,
+ end_pos: usize,
+) -> Option<(Vec<Green>, bool, usize)> {
+ let mut p = Parser::with_prefix(prefix, src, TokenMode::Code);
+ if !p.at(&NodeKind::LeftBracket) {
+ return None;
+ }
+
+ template(&mut p);
+
+ let (mut green, terminated) = p.consume()?;
+ let first = green.remove(0);
+ if first.len() != end_pos {
+ return None;
+ }
+
+ Some((vec![first], terminated, 1))
+}
+
+/// Reparse some markup elements without the topmost node.
+///
+/// Returns `Some` if all of the input was consumed.
pub fn reparse_markup_elements(
prefix: &str,
src: &str,
@@ -100,50 +149,6 @@ pub fn reparse_markup_elements(
Some((res, terminated, replaced))
}
-/// Parse a template literal. Returns `Some` if all of the input was consumed.
-pub fn reparse_template(
- prefix: &str,
- src: &str,
- end_pos: usize,
-) -> Option<(Vec<Green>, bool, usize)> {
- let mut p = Parser::with_prefix(prefix, src, TokenMode::Code);
- if !p.at(&NodeKind::LeftBracket) {
- return None;
- }
-
- template(&mut p);
-
- let (mut green, terminated) = p.consume()?;
- let first = green.remove(0);
- if first.len() != end_pos {
- return None;
- }
-
- Some((vec![first], terminated, 1))
-}
-
-/// Parse a code block. Returns `Some` if all of the input was consumed.
-pub fn reparse_block(
- prefix: &str,
- src: &str,
- end_pos: usize,
-) -> Option<(Vec<Green>, bool, usize)> {
- let mut p = Parser::with_prefix(prefix, src, TokenMode::Code);
- if !p.at(&NodeKind::LeftBrace) {
- return None;
- }
-
- block(&mut p);
-
- let (mut green, terminated) = p.consume()?;
- let first = green.remove(0);
- if first.len() != end_pos {
- return None;
- }
-
- Some((vec![first], terminated, 1))
-}
-
/// Parse markup.
///
/// If `at_start` is true, things like headings that may only appear at the
@@ -201,9 +206,9 @@ fn markup_node(p: &mut Parser, at_start: &mut bool) {
// Text and markup.
NodeKind::Text(_)
+ | NodeKind::NonBreakingSpace
| NodeKind::EnDash
| NodeKind::EmDash
- | NodeKind::NonBreakingSpace
| NodeKind::Linebreak
| NodeKind::Raw(_)
| NodeKind::Math(_)
@@ -350,7 +355,7 @@ fn expr_prec(p: &mut Parser, atomic: bool, min_prec: usize) -> ParseResult {
p.eat();
let prec = op.precedence();
expr_prec(p, atomic, prec)?;
- marker.end(p, NodeKind::Unary);
+ marker.end(p, NodeKind::UnaryExpr);
}
_ => primary(p, atomic)?,
};
@@ -388,7 +393,7 @@ fn expr_prec(p: &mut Parser, atomic: bool, min_prec: usize) -> ParseResult {
Associativity::Right => {}
}
- marker.perform(p, NodeKind::Binary, |p| expr_prec(p, atomic, prec))?;
+ marker.perform(p, NodeKind::BinaryExpr, |p| expr_prec(p, atomic, prec))?;
}
Ok(())
@@ -410,7 +415,7 @@ fn primary(p: &mut Parser, atomic: bool) -> ParseResult {
if !atomic && p.at(&NodeKind::Arrow) {
marker.end(p, NodeKind::ClosureParams);
p.eat_assert(&NodeKind::Arrow);
- marker.perform(p, NodeKind::Closure, expr)
+ marker.perform(p, NodeKind::ClosureExpr, expr)
} else {
Ok(())
}
@@ -418,14 +423,8 @@ fn primary(p: &mut Parser, atomic: bool) -> ParseResult {
// Structures.
Some(NodeKind::LeftParen) => parenthesized(p, atomic),
- Some(NodeKind::LeftBracket) => {
- template(p);
- Ok(())
- }
- Some(NodeKind::LeftBrace) => {
- block(p);
- Ok(())
- }
+ Some(NodeKind::LeftBrace) => Ok(block(p)),
+ Some(NodeKind::LeftBracket) => Ok(template(p)),
// Keywords.
Some(NodeKind::Let) => let_expr(p),
@@ -478,6 +477,20 @@ fn literal(p: &mut Parser) -> bool {
}
}
+/// Parse an identifier.
+fn ident(p: &mut Parser) -> ParseResult {
+ match p.peek() {
+ Some(NodeKind::Ident(_)) => {
+ p.eat();
+ Ok(())
+ }
+ _ => {
+ p.expected_found("identifier");
+ Err(ParseError)
+ }
+ }
+}
+
/// Parse something that starts with a parenthesis, which can be either of:
/// - Array literal
/// - Dictionary literal
@@ -501,12 +514,12 @@ fn parenthesized(p: &mut Parser, atomic: bool) -> ParseResult {
if !atomic && p.at(&NodeKind::Arrow) {
params(p, marker);
p.eat_assert(&NodeKind::Arrow);
- return marker.perform(p, NodeKind::Closure, expr);
+ return marker.perform(p, NodeKind::ClosureExpr, expr);
}
// Transform into the identified collection.
match kind {
- CollectionKind::Group => marker.end(p, NodeKind::Group),
+ CollectionKind::Group => marker.end(p, NodeKind::GroupExpr),
CollectionKind::Positional => array(p, marker),
CollectionKind::Named => dict(p, marker),
}
@@ -614,7 +627,7 @@ fn array(p: &mut Parser, marker: Marker) {
NodeKind::Spread => Err("spreading is not allowed here"),
_ => Ok(()),
});
- marker.end(p, NodeKind::Array);
+ marker.end(p, NodeKind::ArrayExpr);
}
/// Convert a collection into a dictionary, producing errors for anything other
@@ -626,7 +639,7 @@ fn dict(p: &mut Parser, marker: Marker) {
NodeKind::Spread => Err("spreading is not allowed here"),
_ => Err("expected named pair, found expression"),
});
- marker.end(p, NodeKind::Dict);
+ marker.end(p, NodeKind::DictExpr);
}
/// Convert a collection into a list of parameters, producing errors for
@@ -648,18 +661,9 @@ fn params(p: &mut Parser, marker: Marker) {
marker.end(p, NodeKind::ClosureParams);
}
-// Parse a template block: `[...]`.
-fn template(p: &mut Parser) {
- p.perform(NodeKind::Template, |p| {
- p.start_group(Group::Bracket);
- markup(p, true);
- p.end_group();
- });
-}
-
/// Parse a code block: `{...}`.
fn block(p: &mut Parser) {
- p.perform(NodeKind::Block, |p| {
+ p.perform(NodeKind::CodeBlock, |p| {
p.start_group(Group::Brace);
while !p.eof() {
p.start_group(Group::Expr);
@@ -675,9 +679,18 @@ fn block(p: &mut Parser) {
});
}
+// Parse a template block: `[...]`.
+fn template(p: &mut Parser) {
+ p.perform(NodeKind::TemplateBlock, |p| {
+ p.start_group(Group::Bracket);
+ markup(p, true);
+ p.end_group();
+ });
+}
+
/// Parse a function call.
fn call(p: &mut Parser, callee: Marker) -> ParseResult {
- callee.perform(p, NodeKind::Call, |p| args(p, true, true))
+ callee.perform(p, NodeKind::CallExpr, |p| args(p, true, true))
}
/// Parse the arguments to a function call.
@@ -744,7 +757,7 @@ fn let_expr(p: &mut Parser) -> ParseResult {
// Rewrite into a closure expression if it's a function definition.
if has_params {
- marker.end(p, NodeKind::Closure);
+ marker.end(p, NodeKind::ClosureExpr);
}
}
@@ -770,7 +783,7 @@ fn show_expr(p: &mut Parser) -> ParseResult {
p.expected_found("parameter list");
return Err(ParseError);
}
- p.perform(NodeKind::Closure, |p| {
+ p.perform(NodeKind::ClosureExpr, |p| {
let marker = p.marker();
p.start_group(Group::Paren);
collection(p);
@@ -906,31 +919,16 @@ fn return_expr(p: &mut Parser) -> ParseResult {
})
}
-/// Parse an identifier.
-fn ident(p: &mut Parser) -> ParseResult {
- match p.peek() {
- Some(NodeKind::Ident(_)) => {
- p.eat();
- Ok(())
- }
- _ => {
- p.expected_found("identifier");
- Err(ParseError)
- }
- }
-}
-
/// Parse a control flow body.
fn body(p: &mut Parser) -> ParseResult {
match p.peek() {
- Some(NodeKind::LeftBracket) => template(p),
- Some(NodeKind::LeftBrace) => block(p),
+ Some(NodeKind::LeftBracket) => Ok(template(p)),
+ Some(NodeKind::LeftBrace) => Ok(block(p)),
_ => {
p.expected("body");
- return Err(ParseError);
+ Err(ParseError)
}
}
- Ok(())
}
#[cfg(test)]
diff --git a/src/parse/parser.rs b/src/parse/parser.rs
index 123871a5..33cf489c 100644
--- a/src/parse/parser.rs
+++ b/src/parse/parser.rs
@@ -229,13 +229,13 @@ impl<'s> Parser<'s> {
self.groups.push(GroupEntry { kind, prev_mode: self.tokens.mode() });
self.tokens.set_mode(match kind {
Group::Bracket | Group::Strong | Group::Emph => TokenMode::Markup,
- Group::Paren | Group::Brace | Group::Expr | Group::Imports => TokenMode::Code,
+ Group::Brace | Group::Paren | Group::Expr | Group::Imports => TokenMode::Code,
});
match kind {
- Group::Paren => self.eat_assert(&NodeKind::LeftParen),
- Group::Bracket => self.eat_assert(&NodeKind::LeftBracket),
Group::Brace => self.eat_assert(&NodeKind::LeftBrace),
+ Group::Bracket => self.eat_assert(&NodeKind::LeftBracket),
+ Group::Paren => self.eat_assert(&NodeKind::LeftParen),
Group::Strong => self.eat_assert(&NodeKind::Star),
Group::Emph => self.eat_assert(&NodeKind::Underscore),
Group::Expr => self.repeek(),
@@ -321,9 +321,9 @@ impl<'s> Parser<'s> {
/// group.
fn repeek(&mut self) {
self.eof = match &self.current {
- Some(NodeKind::RightParen) => self.inside(Group::Paren),
- Some(NodeKind::RightBracket) => self.inside(Group::Bracket),
Some(NodeKind::RightBrace) => self.inside(Group::Brace),
+ Some(NodeKind::RightBracket) => self.inside(Group::Bracket),
+ Some(NodeKind::RightParen) => self.inside(Group::Paren),
Some(NodeKind::Star) => self.inside(Group::Strong),
Some(NodeKind::Underscore) => self.inside(Group::Emph),
Some(NodeKind::Semicolon) => self.inside(Group::Expr),
@@ -482,10 +482,10 @@ struct GroupEntry {
/// A group, confined by optional start and end delimiters.
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum Group {
- /// A bracketed group: `[...]`.
- Bracket,
/// A curly-braced group: `{...}`.
Brace,
+ /// A bracketed group: `[...]`.
+ Bracket,
/// A parenthesized group: `(...)`.
Paren,
/// A group surrounded with stars: `*...*`.
diff --git a/src/parse/tokens.rs b/src/parse/tokens.rs
index 91bbf9e8..752714fd 100644
--- a/src/parse/tokens.rs
+++ b/src/parse/tokens.rs
@@ -26,7 +26,7 @@ pub struct Tokens<'s> {
pub enum TokenMode {
/// Text and markup.
Markup,
- /// Blocks and expressions.
+ /// Keywords, literals and operators.
Code,
}
@@ -104,11 +104,11 @@ impl<'s> Iterator for Tokens<'s> {
let start = self.s.index();
let c = self.s.eat()?;
Some(match c {
- // Blocks and templates.
- '[' => NodeKind::LeftBracket,
- ']' => NodeKind::RightBracket,
+ // Blocks.
'{' => NodeKind::LeftBrace,
'}' => NodeKind::RightBrace,
+ '[' => NodeKind::LeftBracket,
+ ']' => NodeKind::RightBracket,
// Whitespace.
' ' if self.s.check_or(true, |c| !c.is_whitespace()) => NodeKind::Space(0),
@@ -741,18 +741,18 @@ mod tests {
#[test]
fn test_tokenize_brackets() {
// Test in markup.
- t!(Markup: "[" => LeftBracket);
- t!(Markup: "]" => RightBracket);
t!(Markup: "{" => LeftBrace);
t!(Markup: "}" => RightBrace);
+ t!(Markup: "[" => LeftBracket);
+ t!(Markup: "]" => RightBracket);
t!(Markup[" /"]: "(" => Text("("));
t!(Markup[" /"]: ")" => Text(")"));
// Test in code.
- t!(Code: "[" => LeftBracket);
- t!(Code: "]" => RightBracket);
t!(Code: "{" => LeftBrace);
t!(Code: "}" => RightBrace);
+ t!(Code: "[" => LeftBracket);
+ t!(Code: "]" => RightBracket);
t!(Code: "(" => LeftParen);
t!(Code: ")" => RightParen);
}
diff --git a/src/syntax/ast.rs b/src/syntax/ast.rs
index 10e5ec70..425af0c1 100644
--- a/src/syntax/ast.rs
+++ b/src/syntax/ast.rs
@@ -67,9 +67,9 @@ impl Markup {
Some(MarkupNode::Text(s.clone()))
}
NodeKind::Escape(c) => Some(MarkupNode::Text((*c).into())),
+ NodeKind::NonBreakingSpace => Some(MarkupNode::Text('\u{00A0}'.into())),
NodeKind::EnDash => Some(MarkupNode::Text('\u{2013}'.into())),
NodeKind::EmDash => Some(MarkupNode::Text('\u{2014}'.into())),
- NodeKind::NonBreakingSpace => Some(MarkupNode::Text('\u{00A0}'.into())),
NodeKind::Strong => node.cast().map(MarkupNode::Strong),
NodeKind::Emph => node.cast().map(MarkupNode::Emph),
NodeKind::Raw(raw) => Some(MarkupNode::Raw(raw.as_ref().clone())),
@@ -219,16 +219,16 @@ pub enum Expr {
Lit(Lit),
/// An identifier: `left`.
Ident(Ident),
+ /// A code block: `{ let x = 1; x + 2 }`.
+ Code(CodeBlock),
+ /// A template block: `[*Hi* there!]`.
+ Template(TemplateBlock),
+ /// A grouped expression: `(1 + 2)`.
+ Group(GroupExpr),
/// An array expression: `(1, "hi", 12cm)`.
Array(ArrayExpr),
/// A dictionary expression: `(thickness: 3pt, pattern: dashed)`.
Dict(DictExpr),
- /// A template expression: `[*Hi* there!]`.
- Template(TemplateExpr),
- /// A grouped expression: `(1 + 2)`.
- Group(GroupExpr),
- /// A block expression: `{ let x = 1; x + 2 }`.
- Block(BlockExpr),
/// A unary operation: `-x`.
Unary(UnaryExpr),
/// A binary operation: `a + b`.
@@ -269,15 +269,15 @@ impl TypedNode for Expr {
fn from_red(node: RedRef) -> Option<Self> {
match node.kind() {
NodeKind::Ident(_) => node.cast().map(Self::Ident),
- NodeKind::Array => node.cast().map(Self::Array),
- NodeKind::Dict => node.cast().map(Self::Dict),
- NodeKind::Template => node.cast().map(Self::Template),
- NodeKind::Group => node.cast().map(Self::Group),
- NodeKind::Block => node.cast().map(Self::Block),
- NodeKind::Unary => node.cast().map(Self::Unary),
- NodeKind::Binary => node.cast().map(Self::Binary),
- NodeKind::Call => node.cast().map(Self::Call),
- NodeKind::Closure => node.cast().map(Self::Closure),
+ NodeKind::CodeBlock => node.cast().map(Self::Code),
+ NodeKind::TemplateBlock => node.cast().map(Self::Template),
+ NodeKind::GroupExpr => node.cast().map(Self::Group),
+ NodeKind::ArrayExpr => node.cast().map(Self::Array),
+ NodeKind::DictExpr => node.cast().map(Self::Dict),
+ NodeKind::UnaryExpr => node.cast().map(Self::Unary),
+ NodeKind::BinaryExpr => node.cast().map(Self::Binary),
+ NodeKind::CallExpr => node.cast().map(Self::Call),
+ NodeKind::ClosureExpr => node.cast().map(Self::Closure),
NodeKind::WithExpr => node.cast().map(Self::With),
NodeKind::LetExpr => node.cast().map(Self::Let),
NodeKind::SetExpr => node.cast().map(Self::Set),
@@ -298,12 +298,12 @@ impl TypedNode for Expr {
fn as_red(&self) -> RedRef<'_> {
match self {
Self::Lit(v) => v.as_red(),
+ Self::Code(v) => v.as_red(),
+ Self::Template(v) => v.as_red(),
Self::Ident(v) => v.as_red(),
Self::Array(v) => v.as_red(),
Self::Dict(v) => v.as_red(),
- Self::Template(v) => v.as_red(),
Self::Group(v) => v.as_red(),
- Self::Block(v) => v.as_red(),
Self::Unary(v) => v.as_red(),
Self::Binary(v) => v.as_red(),
Self::Call(v) => v.as_red(),
@@ -407,8 +407,44 @@ pub enum LitKind {
}
node! {
+ /// A code block: `{ let x = 1; x + 2 }`.
+ CodeBlock: CodeBlock
+}
+
+impl CodeBlock {
+ /// The list of expressions contained in the block.
+ pub fn exprs(&self) -> impl Iterator<Item = Expr> + '_ {
+ self.0.children().filter_map(RedRef::cast)
+ }
+}
+
+node! {
+ /// A template block: `[*Hi* there!]`.
+ TemplateBlock: TemplateBlock
+}
+
+impl TemplateBlock {
+ /// The contents of the template.
+ pub fn body(&self) -> Markup {
+ self.0.cast_first_child().expect("template is missing body")
+ }
+}
+
+node! {
+ /// A grouped expression: `(1 + 2)`.
+ GroupExpr: GroupExpr
+}
+
+impl GroupExpr {
+ /// The wrapped expression.
+ pub fn expr(&self) -> Expr {
+ self.0.cast_first_child().expect("group is missing expression")
+ }
+}
+
+node! {
/// An array expression: `(1, "hi", 12cm)`.
- ArrayExpr: Array
+ ArrayExpr: ArrayExpr
}
impl ArrayExpr {
@@ -420,7 +456,7 @@ impl ArrayExpr {
node! {
/// A dictionary expression: `(thickness: 3pt, pattern: dashed)`.
- DictExpr: Dict
+ DictExpr: DictExpr
}
impl DictExpr {
@@ -448,44 +484,8 @@ impl Named {
}
node! {
- /// A template expression: `[*Hi* there!]`.
- TemplateExpr: Template
-}
-
-impl TemplateExpr {
- /// The contents of the template.
- pub fn body(&self) -> Markup {
- self.0.cast_first_child().expect("template is missing body")
- }
-}
-
-node! {
- /// A grouped expression: `(1 + 2)`.
- GroupExpr: Group
-}
-
-impl GroupExpr {
- /// The wrapped expression.
- pub fn expr(&self) -> Expr {
- self.0.cast_first_child().expect("group is missing expression")
- }
-}
-
-node! {
- /// A block expression: `{ let x = 1; x + 2 }`.
- BlockExpr: Block
-}
-
-impl BlockExpr {
- /// The list of expressions contained in the block.
- pub fn exprs(&self) -> impl Iterator<Item = Expr> + '_ {
- self.0.children().filter_map(RedRef::cast)
- }
-}
-
-node! {
/// A unary operation: `-x`.
- UnaryExpr: Unary
+ UnaryExpr: UnaryExpr
}
impl UnaryExpr {
@@ -545,7 +545,7 @@ impl UnOp {
node! {
/// A binary operation: `a + b`.
- BinaryExpr: Binary
+ BinaryExpr: BinaryExpr
}
impl BinaryExpr {
@@ -717,7 +717,7 @@ pub enum Associativity {
node! {
/// An invocation of a function: `foo(...)`.
- CallExpr: Call
+ CallExpr: CallExpr
}
impl CallExpr {
@@ -786,7 +786,7 @@ impl CallArg {
node! {
/// A closure expression: `(x, y) => z`.
- ClosureExpr: Closure
+ ClosureExpr: ClosureExpr
}
impl ClosureExpr {
diff --git a/src/syntax/highlight.rs b/src/syntax/highlight.rs
index 82f1ea0e..20ea4039 100644
--- a/src/syntax/highlight.rs
+++ b/src/syntax/highlight.rs
@@ -104,10 +104,10 @@ impl Category {
/// Determine the highlighting category of a node given its parent.
pub fn determine(child: RedRef, parent: RedRef) -> Option<Category> {
match child.kind() {
- NodeKind::LeftBracket => Some(Category::Bracket),
- NodeKind::RightBracket => Some(Category::Bracket),
NodeKind::LeftBrace => Some(Category::Bracket),
NodeKind::RightBrace => Some(Category::Bracket),
+ NodeKind::LeftBracket => Some(Category::Bracket),
+ NodeKind::RightBracket => Some(Category::Bracket),
NodeKind::LeftParen => Some(Category::Bracket),
NodeKind::RightParen => Some(Category::Bracket),
NodeKind::Comma => Some(Category::Punctuation),
@@ -176,13 +176,13 @@ impl Category {
NodeKind::Auto => Some(Category::Auto),
NodeKind::Ident(_) => match parent.kind() {
NodeKind::Named => None,
- NodeKind::Closure if child.span().start == parent.span().start => {
+ NodeKind::ClosureExpr if child.span().start == parent.span().start => {
Some(Category::Function)
}
NodeKind::WithExpr => Some(Category::Function),
NodeKind::SetExpr => Some(Category::Function),
NodeKind::ShowExpr => Some(Category::Function),
- NodeKind::Call => Some(Category::Function),
+ NodeKind::CallExpr => Some(Category::Function),
_ => Some(Category::Variable),
},
NodeKind::Bool(_) => Some(Category::Bool),
@@ -202,18 +202,18 @@ impl Category {
NodeKind::TextInLine(_) => None,
NodeKind::List => None,
NodeKind::Enum => None,
- NodeKind::Array => None,
- NodeKind::Dict => None,
+ NodeKind::CodeBlock => None,
+ NodeKind::TemplateBlock => None,
+ NodeKind::GroupExpr => None,
+ NodeKind::ArrayExpr => None,
+ NodeKind::DictExpr => None,
NodeKind::Named => None,
- NodeKind::Template => None,
- NodeKind::Group => None,
- NodeKind::Block => None,
- NodeKind::Unary => None,
- NodeKind::Binary => None,
- NodeKind::Call => None,
+ NodeKind::UnaryExpr => None,
+ NodeKind::BinaryExpr => None,
+ NodeKind::CallExpr => None,
NodeKind::CallArgs => None,
NodeKind::Spread => None,
- NodeKind::Closure => None,
+ NodeKind::ClosureExpr => None,
NodeKind::ClosureParams => None,
NodeKind::WithExpr => None,
NodeKind::LetExpr => None,
diff --git a/src/syntax/mod.rs b/src/syntax/mod.rs
index 85f2013c..a3393eda 100644
--- a/src/syntax/mod.rs
+++ b/src/syntax/mod.rs
@@ -481,14 +481,14 @@ impl ExactSizeIterator for Children<'_> {}
/// the parser.
#[derive(Debug, Clone, PartialEq)]
pub enum NodeKind {
- /// A left square bracket: `[`.
- LeftBracket,
- /// A right square bracket: `]`.
- RightBracket,
/// A left curly brace: `{`.
LeftBrace,
/// A right curly brace: `}`.
RightBrace,
+ /// A left square bracket: `[`.
+ LeftBracket,
+ /// A right square bracket: `]`.
+ RightBracket,
/// A left round parenthesis: `(`.
LeftParen,
/// A right round parenthesis: `)`.
@@ -642,30 +642,30 @@ pub enum NodeKind {
Fraction(f64),
/// A quoted string: `"..."`.
Str(EcoString),
+ /// A code block: `{ let x = 1; x + 2 }`.
+ CodeBlock,
+ /// A template block: `[*Hi* there!]`.
+ TemplateBlock,
+ /// A grouped expression: `(1 + 2)`.
+ GroupExpr,
/// An array expression: `(1, "hi", 12cm)`.
- Array,
+ ArrayExpr,
/// A dictionary expression: `(thickness: 3pt, pattern: dashed)`.
- Dict,
+ DictExpr,
/// A named pair: `thickness: 3pt`.
Named,
- /// A template expression: `[*Hi* there!]`.
- Template,
- /// A grouped expression: `(1 + 2)`.
- Group,
- /// A block expression: `{ let x = 1; x + 2 }`.
- Block,
/// A unary operation: `-x`.
- Unary,
+ UnaryExpr,
/// A binary operation: `a + b`.
- Binary,
+ BinaryExpr,
/// An invocation of a function: `f(x, y)`.
- Call,
+ CallExpr,
/// A function call's argument list: `(x, y)`.
CallArgs,
/// Spreaded arguments or a parameter sink: `..x`.
Spread,
/// A closure expression: `(x, y) => z`.
- Closure,
+ ClosureExpr,
/// A closure's parameters: `(x, y)`.
ClosureParams,
/// A with expression: `f with (x, y: 1)`.
@@ -724,16 +724,16 @@ pub enum ErrorPos {
}
impl NodeKind {
- /// Whether this is some kind of bracket.
- pub fn is_bracket(&self) -> bool {
- matches!(self, Self::LeftBracket | Self::RightBracket)
- }
-
/// Whether this is some kind of brace.
pub fn is_brace(&self) -> bool {
matches!(self, Self::LeftBrace | Self::RightBrace)
}
+ /// Whether this is some kind of bracket.
+ pub fn is_bracket(&self) -> bool {
+ matches!(self, Self::LeftBracket | Self::RightBracket)
+ }
+
/// Whether this is some kind of parenthesis.
pub fn is_paren(&self) -> bool {
matches!(self, Self::LeftParen | Self::RightParen)
@@ -782,10 +782,10 @@ impl NodeKind {
| Self::List
| Self::Raw(_)
| Self::Math(_) => Some(TokenMode::Markup),
- Self::Template
+ Self::TemplateBlock
| Self::Space(_)
- | Self::Block
| Self::Ident(_)
+ | Self::CodeBlock
| Self::LetExpr
| Self::SetExpr
| Self::ShowExpr
@@ -794,7 +794,7 @@ impl NodeKind {
| Self::WhileExpr
| Self::ForExpr
| Self::ImportExpr
- | Self::Call
+ | Self::CallExpr
| Self::IncludeExpr
| Self::LineComment
| Self::BlockComment
@@ -808,10 +808,10 @@ impl NodeKind {
/// A human-readable name for the kind.
pub fn as_str(&self) -> &'static str {
match self {
- Self::LeftBracket => "opening bracket",
- Self::RightBracket => "closing bracket",
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::Star => "star",
@@ -883,18 +883,18 @@ impl NodeKind {
Self::Percentage(_) => "percentage",
Self::Fraction(_) => "`fr` value",
Self::Str(_) => "string",
- Self::Array => "array",
- Self::Dict => "dictionary",
+ Self::CodeBlock => "code block",
+ Self::TemplateBlock => "template block",
+ Self::GroupExpr => "group",
+ Self::ArrayExpr => "array",
+ Self::DictExpr => "dictionary",
Self::Named => "named argument",
- Self::Template => "template",
- Self::Group => "group",
- Self::Block => "block",
- Self::Unary => "unary expression",
- Self::Binary => "binary expression",
- Self::Call => "call",
+ Self::UnaryExpr => "unary expression",
+ Self::BinaryExpr => "binary expression",
+ Self::CallExpr => "call",
Self::CallArgs => "call arguments",
Self::Spread => "parameter sink",
- Self::Closure => "closure",
+ Self::ClosureExpr => "closure",
Self::ClosureParams => "closure parameters",
Self::WithExpr => "`with` expression",
Self::LetExpr => "`let` expression",
@@ -932,10 +932,10 @@ impl Hash for NodeKind {
fn hash<H: Hasher>(&self, state: &mut H) {
std::mem::discriminant(self).hash(state);
match self {
- Self::LeftBracket => {}
- Self::RightBracket => {}
Self::LeftBrace => {}
Self::RightBrace => {}
+ Self::LeftBracket => {}
+ Self::RightBracket => {}
Self::LeftParen => {}
Self::RightParen => {}
Self::Star => {}
@@ -1007,18 +1007,18 @@ impl Hash for NodeKind {
Self::Percentage(v) => v.to_bits().hash(state),
Self::Fraction(v) => v.to_bits().hash(state),
Self::Str(v) => v.hash(state),
- Self::Array => {}
- Self::Dict => {}
+ Self::CodeBlock => {}
+ Self::TemplateBlock => {}
+ Self::GroupExpr => {}
+ Self::ArrayExpr => {}
+ Self::DictExpr => {}
Self::Named => {}
- Self::Template => {}
- Self::Group => {}
- Self::Block => {}
- Self::Unary => {}
- Self::Binary => {}
- Self::Call => {}
+ Self::UnaryExpr => {}
+ Self::BinaryExpr => {}
+ Self::CallExpr => {}
Self::CallArgs => {}
Self::Spread => {}
- Self::Closure => {}
+ Self::ClosureExpr => {}
Self::ClosureParams => {}
Self::WithExpr => {}
Self::LetExpr => {}