summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2024-04-25 19:27:34 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2024-04-25 21:14:18 +0200
commitbf44f9a24df6713f89ed95eaa69eab28f102d0cc (patch)
treec8fdbbd6a0198a98b5db49a0a51cba9019b48f24
parentac9d36ac937b80705d47fa10803ff905b4ed90a6 (diff)
downloadrebel-bf44f9a24df6713f89ed95eaa69eab28f102d0cc.tar
rebel-bf44f9a24df6713f89ed95eaa69eab28f102d0cc.zip
rebel-parse: token: represent string tokens as a Vec as well
-rw-r--r--crates/rebel-parse/src/ast.rs18
-rw-r--r--crates/rebel-parse/src/grammar/recipe.rs6
-rw-r--r--crates/rebel-parse/src/grammar/tokenize.rs21
-rw-r--r--crates/rebel-parse/src/token.rs11
4 files changed, 45 insertions, 11 deletions
diff --git a/crates/rebel-parse/src/ast.rs b/crates/rebel-parse/src/ast.rs
index f9943d4..648a79e 100644
--- a/crates/rebel-parse/src/ast.rs
+++ b/crates/rebel-parse/src/ast.rs
@@ -1,3 +1,5 @@
+use crate::token;
+
pub type Recipe<'a> = Vec<RecipeStmt<'a>>;
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -165,6 +167,22 @@ pub enum StringPiece<'a> {
Interp(Expr<'a>),
}
+impl<'a> TryFrom<&token::StringPiece<'a>> for StringPiece<'a> {
+ type Error = &'static str;
+
+ fn try_from(value: &token::StringPiece<'a>) -> Result<Self, Self::Error> {
+ use crate::recipe;
+
+ Ok(match value {
+ token::StringPiece::Chars(chars) => StringPiece::Chars(chars),
+ token::StringPiece::Escape(c) => StringPiece::Escape(*c),
+ token::StringPiece::Interp(tokens) => StringPiece::Interp(
+ recipe::expr(tokens).or(Err("Invalid expression in string interpolation"))?,
+ ),
+ })
+ }
+}
+
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct MapEntry<'a> {
pub key: &'a str,
diff --git a/crates/rebel-parse/src/grammar/recipe.rs b/crates/rebel-parse/src/grammar/recipe.rs
index 6bd96bb..49b1689 100644
--- a/crates/rebel-parse/src/grammar/recipe.rs
+++ b/crates/rebel-parse/src/grammar/recipe.rs
@@ -97,9 +97,9 @@ peg::parser! {
/ [Token::Number(content)] { ?
ast::Literal::number(content)
}
- / [Token::String(String { content, .. })] {
- let ast_pieces = vec![ast::StringPiece::Chars(content)];
- ast::Literal::String(ast_pieces)
+ / [Token::String(String { pieces, .. })] { ?
+ let ast_pieces = pieces.iter().map(|piece| piece.try_into()).collect::<Result<_, _>>()?;
+ Ok(ast::Literal::String(ast_pieces))
}
/ p('(') p(')') { ast::Literal::Unit }
/ p('(') elements:(expr() ** p(',')) p(',')? p(')') {
diff --git a/crates/rebel-parse/src/grammar/tokenize.rs b/crates/rebel-parse/src/grammar/tokenize.rs
index 5f21461..a64c5e1 100644
--- a/crates/rebel-parse/src/grammar/tokenize.rs
+++ b/crates/rebel-parse/src/grammar/tokenize.rs
@@ -33,14 +33,23 @@ peg::parser! {
= $(['0'..='9'] ['0'..='9' | 'a'..='z' | 'A'..='Z' | '_']*)
rule string() -> String<'input>
- = "\"" content:$(string_char()*) "\"" {
- String { content, kind: StringKind::String }
+ = "\"" chars:$(string_char()*) "\"" {
+ String {
+ pieces: vec![StringPiece::Chars(chars)],
+ kind: StringKind::String,
+ }
}
- / "r\"" content:$([^'"']*) "\"" {
- String { content, kind: StringKind::RawString }
+ / "r\"" chars:$([^'"']*) "\"" {
+ String {
+ pieces: vec![StringPiece::Chars(chars)],
+ kind: StringKind::RawString,
+ }
}
- / "```" newline() content:$((!"```" [_])+) "```" {
- String { content, kind: StringKind::ScriptString }
+ / "```" newline() chars:$((!"```" [_])+) "```" {
+ String {
+ pieces: vec![StringPiece::Chars(chars)],
+ kind: StringKind::ScriptString,
+ }
}
rule string_char()
diff --git a/crates/rebel-parse/src/token.rs b/crates/rebel-parse/src/token.rs
index d147205..2f2f849 100644
--- a/crates/rebel-parse/src/token.rs
+++ b/crates/rebel-parse/src/token.rs
@@ -15,12 +15,19 @@ pub enum Spacing {
Joint,
}
-#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
pub struct String<'a> {
- pub content: &'a str,
+ pub pieces: Vec<StringPiece<'a>>,
pub kind: StringKind,
}
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub enum StringPiece<'a> {
+ Chars(&'a str),
+ Escape(char),
+ Interp(TokenStream<'a>),
+}
+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum StringKind {
String,