summaryrefslogtreecommitdiff
path: root/src/syntax
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2022-01-28 21:01:05 +0100
committerLaurenz <laurmaedje@gmail.com>2022-01-28 21:01:36 +0100
commit9c906f92c50d453822b12896d29b7883802ea567 (patch)
tree78e2465a4fa805bbddc80407b7eea585b5ebb60c /src/syntax
parent3a07603b66fab6b343b34156f4a3a6015e2d69e1 (diff)
Parse `break`, `continue` and `return` expression
Diffstat (limited to 'src/syntax')
-rw-r--r--src/syntax/ast.rs34
-rw-r--r--src/syntax/highlight.rs3
-rw-r--r--src/syntax/mod.rs14
-rw-r--r--src/syntax/pretty.rs29
4 files changed, 79 insertions, 1 deletions
diff --git a/src/syntax/ast.rs b/src/syntax/ast.rs
index 6732aa40..13c639f9 100644
--- a/src/syntax/ast.rs
+++ b/src/syntax/ast.rs
@@ -231,6 +231,12 @@ pub enum Expr {
Import(ImportExpr),
/// An include expression: `include "chapter1.typ"`.
Include(IncludeExpr),
+ /// A break expression: `break`.
+ Break(BreakExpr),
+ /// A continue expression: `continue`.
+ Continue(ContinueExpr),
+ /// A return expression: `return`.
+ Return(ReturnExpr),
}
impl TypedNode for Expr {
@@ -256,6 +262,9 @@ impl TypedNode for Expr {
NodeKind::ForExpr => node.cast().map(Self::For),
NodeKind::ImportExpr => node.cast().map(Self::Import),
NodeKind::IncludeExpr => node.cast().map(Self::Include),
+ NodeKind::BreakExpr => node.cast().map(Self::Break),
+ NodeKind::ContinueExpr => node.cast().map(Self::Continue),
+ NodeKind::ReturnExpr => node.cast().map(Self::Return),
_ => node.cast().map(Self::Lit),
}
}
@@ -283,6 +292,9 @@ impl TypedNode for Expr {
Self::For(v) => v.as_red(),
Self::Import(v) => v.as_red(),
Self::Include(v) => v.as_red(),
+ Self::Break(v) => v.as_red(),
+ Self::Continue(v) => v.as_red(),
+ Self::Return(v) => v.as_red(),
}
}
}
@@ -1042,6 +1054,28 @@ impl IncludeExpr {
}
node! {
+ /// A break expression: `break`.
+ BreakExpr
+}
+
+node! {
+ /// A continue expression: `continue`.
+ ContinueExpr
+}
+
+node! {
+ /// A return expression: `return x + 1`.
+ ReturnExpr
+}
+
+impl ReturnExpr {
+ /// The expression to return.
+ pub fn body(&self) -> Option<Expr> {
+ self.0.cast_last_child()
+ }
+}
+
+node! {
/// An identifier.
Ident: NodeKind::Ident(_)
}
diff --git a/src/syntax/highlight.rs b/src/syntax/highlight.rs
index c399b487..315e8f17 100644
--- a/src/syntax/highlight.rs
+++ b/src/syntax/highlight.rs
@@ -223,6 +223,9 @@ impl Category {
NodeKind::ImportExpr => None,
NodeKind::ImportItems => None,
NodeKind::IncludeExpr => None,
+ NodeKind::BreakExpr => None,
+ NodeKind::ContinueExpr => None,
+ NodeKind::ReturnExpr => None,
}
}
diff --git a/src/syntax/mod.rs b/src/syntax/mod.rs
index 74a642ca..9b606e0e 100644
--- a/src/syntax/mod.rs
+++ b/src/syntax/mod.rs
@@ -689,6 +689,12 @@ pub enum NodeKind {
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,
/// A line comment, two slashes followed by inner contents, terminated with
/// a newline: `//<str>\n`.
LineComment,
@@ -755,7 +761,7 @@ impl NodeKind {
}
}
- /// Whether this token appears in Markup.
+ /// Which mode this token can appear in, in both if `None`.
pub fn mode(&self) -> Option<TokenMode> {
match self {
Self::Markup(_)
@@ -780,6 +786,9 @@ impl NodeKind {
| Self::Block
| Self::Ident(_)
| Self::LetExpr
+ | Self::SetExpr
+ | Self::ShowExpr
+ | Self::WrapExpr
| Self::IfExpr
| Self::WhileExpr
| Self::ForExpr
@@ -897,6 +906,9 @@ impl NodeKind {
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::LineComment => "line comment",
Self::BlockComment => "block comment",
Self::Error(_, _) => "parse error",
diff --git a/src/syntax/pretty.rs b/src/syntax/pretty.rs
index f8285f0c..e8110262 100644
--- a/src/syntax/pretty.rs
+++ b/src/syntax/pretty.rs
@@ -234,6 +234,9 @@ impl Pretty for Expr {
Self::For(v) => v.pretty(p),
Self::Import(v) => v.pretty(p),
Self::Include(v) => v.pretty(p),
+ Self::Break(v) => v.pretty(p),
+ Self::Continue(v) => v.pretty(p),
+ Self::Return(v) => v.pretty(p),
}
}
}
@@ -547,6 +550,28 @@ impl Pretty for IncludeExpr {
}
}
+impl Pretty for BreakExpr {
+ fn pretty(&self, p: &mut Printer) {
+ p.push_str("break");
+ }
+}
+
+impl Pretty for ContinueExpr {
+ fn pretty(&self, p: &mut Printer) {
+ p.push_str("continue");
+ }
+}
+
+impl Pretty for ReturnExpr {
+ fn pretty(&self, p: &mut Printer) {
+ p.push_str("return");
+ if let Some(body) = self.body() {
+ p.push(' ');
+ body.pretty(p);
+ }
+ }
+}
+
impl Pretty for Ident {
fn pretty(&self, p: &mut Printer) {
p.push_str(self);
@@ -681,5 +706,9 @@ mod tests {
roundtrip("#for k, x in y {z}");
roundtrip("#import * from \"file.typ\"");
roundtrip("#include \"chapter1.typ\"");
+ roundtrip("{break}");
+ roundtrip("{continue}");
+ roundtrip("{return}");
+ roundtrip("{return x + 1}");
}
}