summaryrefslogtreecommitdiff
path: root/crates/typst-syntax/src
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2024-02-27 11:05:16 +0100
committerGitHub <noreply@github.com>2024-02-27 10:05:16 +0000
commit145723b1ef4fa23f1f6665b8907dfe79d0bf83cf (patch)
tree02a7de661ddd5dafa75dfce3e3c8b45a7333b9dc /crates/typst-syntax/src
parente9ee00a7c0df083663ff5ccca162238b88525e14 (diff)
New context system (#3497)
Diffstat (limited to 'crates/typst-syntax/src')
-rw-r--r--crates/typst-syntax/src/ast.rs17
-rw-r--r--crates/typst-syntax/src/highlight.rs2
-rw-r--r--crates/typst-syntax/src/kind.rs7
-rw-r--r--crates/typst-syntax/src/lexer.rs1
-rw-r--r--crates/typst-syntax/src/parser.rs9
-rw-r--r--crates/typst-syntax/src/set.rs1
6 files changed, 37 insertions, 0 deletions
diff --git a/crates/typst-syntax/src/ast.rs b/crates/typst-syntax/src/ast.rs
index 6dd9b5f6..df9cef0c 100644
--- a/crates/typst-syntax/src/ast.rs
+++ b/crates/typst-syntax/src/ast.rs
@@ -187,6 +187,8 @@ pub enum Expr<'a> {
Set(SetRule<'a>),
/// A show rule: `show heading: it => emph(it.body)`.
Show(ShowRule<'a>),
+ /// A contextual expression: `context text.lang`.
+ Contextual(Contextual<'a>),
/// An if-else conditional: `if x { y } else { z }`.
Conditional(Conditional<'a>),
/// A while loop: `while x { y }`.
@@ -264,6 +266,7 @@ impl<'a> AstNode<'a> for Expr<'a> {
SyntaxKind::DestructAssignment => node.cast().map(Self::DestructAssign),
SyntaxKind::SetRule => node.cast().map(Self::Set),
SyntaxKind::ShowRule => node.cast().map(Self::Show),
+ SyntaxKind::Contextual => node.cast().map(Self::Contextual),
SyntaxKind::Conditional => node.cast().map(Self::Conditional),
SyntaxKind::WhileLoop => node.cast().map(Self::While),
SyntaxKind::ForLoop => node.cast().map(Self::For),
@@ -326,6 +329,7 @@ impl<'a> AstNode<'a> for Expr<'a> {
Self::DestructAssign(v) => v.to_untyped(),
Self::Set(v) => v.to_untyped(),
Self::Show(v) => v.to_untyped(),
+ Self::Contextual(v) => v.to_untyped(),
Self::Conditional(v) => v.to_untyped(),
Self::While(v) => v.to_untyped(),
Self::For(v) => v.to_untyped(),
@@ -361,6 +365,7 @@ impl Expr<'_> {
| Self::Let(_)
| Self::Set(_)
| Self::Show(_)
+ | Self::Contextual(_)
| Self::Conditional(_)
| Self::While(_)
| Self::For(_)
@@ -1947,6 +1952,18 @@ impl<'a> ShowRule<'a> {
}
node! {
+ /// A contextual expression: `context text.lang`.
+ Contextual
+}
+
+impl<'a> Contextual<'a> {
+ /// The expression which depends on the context.
+ pub fn body(self) -> Expr<'a> {
+ self.0.cast_first_match().unwrap_or_default()
+ }
+}
+
+node! {
/// An if-else conditional: `if x { y } else { z }`.
Conditional
}
diff --git a/crates/typst-syntax/src/highlight.rs b/crates/typst-syntax/src/highlight.rs
index 99fbf4fe..19d35d0a 100644
--- a/crates/typst-syntax/src/highlight.rs
+++ b/crates/typst-syntax/src/highlight.rs
@@ -230,6 +230,7 @@ pub fn highlight(node: &LinkedNode) -> Option<Tag> {
SyntaxKind::Let => Some(Tag::Keyword),
SyntaxKind::Set => Some(Tag::Keyword),
SyntaxKind::Show => Some(Tag::Keyword),
+ SyntaxKind::Context => Some(Tag::Keyword),
SyntaxKind::If => Some(Tag::Keyword),
SyntaxKind::Else => Some(Tag::Keyword),
SyntaxKind::For => Some(Tag::Keyword),
@@ -267,6 +268,7 @@ pub fn highlight(node: &LinkedNode) -> Option<Tag> {
SyntaxKind::LetBinding => None,
SyntaxKind::SetRule => None,
SyntaxKind::ShowRule => None,
+ SyntaxKind::Contextual => None,
SyntaxKind::Conditional => None,
SyntaxKind::WhileLoop => None,
SyntaxKind::ForLoop => None,
diff --git a/crates/typst-syntax/src/kind.rs b/crates/typst-syntax/src/kind.rs
index 536c9381..e5dd4e9b 100644
--- a/crates/typst-syntax/src/kind.rs
+++ b/crates/typst-syntax/src/kind.rs
@@ -159,6 +159,8 @@ pub enum SyntaxKind {
Set,
/// The `show` keyword.
Show,
+ /// The `context` keyword.
+ Context,
/// The `if` keyword.
If,
/// The `else` keyword.
@@ -232,6 +234,8 @@ pub enum SyntaxKind {
SetRule,
/// A show rule: `show heading: it => emph(it.body)`.
ShowRule,
+ /// A contextual expression: `context text.lang`.
+ Contextual,
/// An if-else conditional: `if x { y } else { z }`.
Conditional,
/// A while loop: `while x { y }`.
@@ -322,6 +326,7 @@ impl SyntaxKind {
| Self::Let
| Self::Set
| Self::Show
+ | Self::Context
| Self::If
| Self::Else
| Self::For
@@ -426,6 +431,7 @@ impl SyntaxKind {
Self::Let => "keyword `let`",
Self::Set => "keyword `set`",
Self::Show => "keyword `show`",
+ Self::Context => "keyword `context`",
Self::If => "keyword `if`",
Self::Else => "keyword `else`",
Self::For => "keyword `for`",
@@ -462,6 +468,7 @@ impl SyntaxKind {
Self::LetBinding => "`let` expression",
Self::SetRule => "`set` expression",
Self::ShowRule => "`show` expression",
+ Self::Contextual => "`context` expression",
Self::Conditional => "`if` expression",
Self::WhileLoop => "while-loop expression",
Self::ForLoop => "for-loop expression",
diff --git a/crates/typst-syntax/src/lexer.rs b/crates/typst-syntax/src/lexer.rs
index f0cf8846..cd1998a6 100644
--- a/crates/typst-syntax/src/lexer.rs
+++ b/crates/typst-syntax/src/lexer.rs
@@ -616,6 +616,7 @@ fn keyword(ident: &str) -> Option<SyntaxKind> {
"let" => SyntaxKind::Let,
"set" => SyntaxKind::Set,
"show" => SyntaxKind::Show,
+ "context" => SyntaxKind::Context,
"if" => SyntaxKind::If,
"else" => SyntaxKind::Else,
"for" => SyntaxKind::For,
diff --git a/crates/typst-syntax/src/parser.rs b/crates/typst-syntax/src/parser.rs
index 32e15cb7..567bcbd1 100644
--- a/crates/typst-syntax/src/parser.rs
+++ b/crates/typst-syntax/src/parser.rs
@@ -750,6 +750,7 @@ fn code_primary(p: &mut Parser, atomic: bool) {
SyntaxKind::Let => let_binding(p),
SyntaxKind::Set => set_rule(p),
SyntaxKind::Show => show_rule(p),
+ SyntaxKind::Context => contextual(p, atomic),
SyntaxKind::If => conditional(p),
SyntaxKind::While => while_loop(p),
SyntaxKind::For => for_loop(p),
@@ -889,6 +890,14 @@ fn show_rule(p: &mut Parser) {
p.wrap(m, SyntaxKind::ShowRule);
}
+/// Parses a contextual expression: `context text.lang`.
+fn contextual(p: &mut Parser, atomic: bool) {
+ let m = p.marker();
+ p.assert(SyntaxKind::Context);
+ code_expr_prec(p, atomic, 0);
+ p.wrap(m, SyntaxKind::Contextual);
+}
+
/// Parses an if-else conditional: `if x { y } else { z }`.
fn conditional(p: &mut Parser) {
let m = p.marker();
diff --git a/crates/typst-syntax/src/set.rs b/crates/typst-syntax/src/set.rs
index 88a9b18b..906d5fac 100644
--- a/crates/typst-syntax/src/set.rs
+++ b/crates/typst-syntax/src/set.rs
@@ -102,6 +102,7 @@ pub const ATOMIC_CODE_PRIMARY: SyntaxSet = SyntaxSet::new()
.add(SyntaxKind::Let)
.add(SyntaxKind::Set)
.add(SyntaxKind::Show)
+ .add(SyntaxKind::Context)
.add(SyntaxKind::If)
.add(SyntaxKind::While)
.add(SyntaxKind::For)