diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2024-05-05 20:35:30 +0200 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2024-05-05 21:42:11 +0200 |
commit | b4c25932f538bbfe332f2ff406d510dbc9641339 (patch) | |
tree | 7625840a4ae379103582b56186972362503040aa /crates/rebel-parse | |
parent | 1f0894a45be2ba1bd2d17fef771cf41ecf46309d (diff) | |
download | rebel-b4c25932f538bbfe332f2ff406d510dbc9641339.tar rebel-b4c25932f538bbfe332f2ff406d510dbc9641339.zip |
rebel-parse: make fetch bodies struct-like rather than block-like
Fetch statements can't have parameters, so we don't need a code block
where a simple data structure would suffice.
Diffstat (limited to 'crates/rebel-parse')
-rw-r--r-- | crates/rebel-parse/src/ast/mod.rs | 21 | ||||
-rw-r--r-- | crates/rebel-parse/src/grammar/recipe.rs | 4 |
2 files changed, 17 insertions, 8 deletions
diff --git a/crates/rebel-parse/src/ast/mod.rs b/crates/rebel-parse/src/ast/mod.rs index 0598cbd..adeac2e 100644 --- a/crates/rebel-parse/src/ast/mod.rs +++ b/crates/rebel-parse/src/ast/mod.rs @@ -1,13 +1,13 @@ +use rustc_hash::FxHashSet; + pub mod expr; pub mod pat; pub mod typ; -use expr::Expr; -use pat::DestrPat; +use expr::{Expr, StructField}; +use pat::{DestrPat, Pat}; use typ::Type; -use self::pat::Pat; - pub type Recipe<'a> = Vec<RecipeStmt<'a>>; #[derive(Debug, Clone, PartialEq, Eq)] @@ -15,7 +15,7 @@ pub enum RecipeStmt<'a> { BlockStmt(BlockStmt<'a>), Fetch { name: Ident<'a>, - block: Block<'a>, + entries: Vec<StructField<'a>>, }, Task { name: Ident<'a>, @@ -28,7 +28,16 @@ impl<'a> RecipeStmt<'a> { pub fn validate(&self) -> Result<(), ValidationError> { match self { RecipeStmt::BlockStmt(stmt) => stmt.validate(), - RecipeStmt::Fetch { name: _, block } => block.validate(), + RecipeStmt::Fetch { name: _, entries } => { + let mut fields = FxHashSet::default(); + for StructField { name, value } in entries { + if !fields.insert(name) { + return Err(ValidationError::DuplicateKey); + } + value.validate()?; + } + Ok(()) + } RecipeStmt::Task { name: _, params: _, diff --git a/crates/rebel-parse/src/grammar/recipe.rs b/crates/rebel-parse/src/grammar/recipe.rs index 85a6d8d..96ef61d 100644 --- a/crates/rebel-parse/src/grammar/recipe.rs +++ b/crates/rebel-parse/src/grammar/recipe.rs @@ -19,8 +19,8 @@ peg::parser! { = recipe:recipe_stmt()* { recipe } pub rule recipe_stmt() -> ast::RecipeStmt<'a> - = [Token::Keyword(Keyword::Fetch)] name:ident() p('{') block:block() p('}') { - ast::RecipeStmt::Fetch { name, block } + = [Token::Keyword(Keyword::Fetch)] name:ident() p('{') entries:delimited(<struct_field()>, <p(',')>) p('}') { + ast::RecipeStmt::Fetch { name, entries } } / [Token::Keyword(Keyword::Task)] name:ident() p('(') params:func_params() p(')') p('{') block:block() p('}') { |