summaryrefslogtreecommitdiffstats
path: root/crates/rebel-parse
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2024-05-04 23:53:39 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2024-05-05 00:10:01 +0200
commit5c04851b48099463afbfd4fb9e015d99d28ab4b9 (patch)
tree67561f72cbd5c0a56bdaf869748ae3e92f707368 /crates/rebel-parse
parentbd9a27bdd4145507ab239801fe1d125322db55df (diff)
downloadrebel-5c04851b48099463afbfd4fb9e015d99d28ab4b9.tar
rebel-5c04851b48099463afbfd4fb9e015d99d28ab4b9.zip
rebel-parse, rebel-lang: add support for map literals
Diffstat (limited to 'crates/rebel-parse')
-rw-r--r--crates/rebel-parse/src/ast/expr.rs14
-rw-r--r--crates/rebel-parse/src/grammar/recipe.rs8
2 files changed, 22 insertions, 0 deletions
diff --git a/crates/rebel-parse/src/ast/expr.rs b/crates/rebel-parse/src/ast/expr.rs
index 341b8ad..0a47cb2 100644
--- a/crates/rebel-parse/src/ast/expr.rs
+++ b/crates/rebel-parse/src/ast/expr.rs
@@ -193,6 +193,7 @@ pub enum Literal<'a> {
},
Tuple(Vec<Expr<'a>>),
Array(Vec<Expr<'a>>),
+ Map(Vec<MapEntry<'a>>),
Struct(Vec<StructField<'a>>),
}
@@ -224,6 +225,13 @@ impl<'a> Literal<'a> {
}
Ok(())
}
+ Literal::Map(entries) => {
+ for MapEntry { key, value } in entries {
+ key.validate()?;
+ value.validate()?;
+ }
+ Ok(())
+ }
Literal::Struct(entries) => {
let mut fields = FxHashSet::default();
for StructField { name, value } in entries {
@@ -262,6 +270,12 @@ impl<'a> TryFrom<&token::StrPiece<'a>> for StrPiece<'a> {
}
#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct MapEntry<'a> {
+ pub key: Expr<'a>,
+ pub value: Expr<'a>,
+}
+
+#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StructField<'a> {
pub name: &'a str,
pub value: Expr<'a>,
diff --git a/crates/rebel-parse/src/grammar/recipe.rs b/crates/rebel-parse/src/grammar/recipe.rs
index 1ada80c..8181ee2 100644
--- a/crates/rebel-parse/src/grammar/recipe.rs
+++ b/crates/rebel-parse/src/grammar/recipe.rs
@@ -178,10 +178,18 @@ peg::parser! {
/ p('[') elements:delimited(<expr()>, <p(',')>) p(']') {
expr::Literal::Array(elements)
}
+ / [Token::Keyword(Keyword::Map)] p('{') entries:delimited(<map_entry()>, <p(',')>) p('}') {
+ expr::Literal::Map(entries)
+ }
/ [Token::Keyword(Keyword::Struct)] p('{') entries:delimited(<struct_field()>, <p(',')>) p('}') {
expr::Literal::Struct(entries)
}
+ rule map_entry() -> expr::MapEntry<'a>
+ = key:expr() p2('=', '>') value:expr() {
+ expr::MapEntry { key, value }
+ }
+
rule struct_field() -> expr::StructField<'a>
= field:field() p('=') value:expr() {
expr::StructField { name: field.name, value }