summaryrefslogtreecommitdiffstats
path: root/crates
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2024-04-28 13:45:11 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2024-04-28 13:45:11 +0200
commit0795e76ae45b0479289acb2ee4be5ab29980f7a2 (patch)
treea4c3ce3f74b892d9a2390a2cf917e11ca8df609c /crates
parentf9005692a1e2dba89274f39df762fdcfa59b739b (diff)
downloadrebel-0795e76ae45b0479289acb2ee4be5ab29980f7a2.tar
rebel-0795e76ae45b0479289acb2ee4be5ab29980f7a2.zip
rebel-parse: implement validation for statements
Diffstat (limited to 'crates')
-rw-r--r--crates/rebel-lang/examples/repl.rs22
-rw-r--r--crates/rebel-parse/src/ast.rs41
-rw-r--r--crates/rebel-parse/src/grammar/recipe.rs4
3 files changed, 50 insertions, 17 deletions
diff --git a/crates/rebel-lang/examples/repl.rs b/crates/rebel-lang/examples/repl.rs
index 4a7b755..914f318 100644
--- a/crates/rebel-lang/examples/repl.rs
+++ b/crates/rebel-lang/examples/repl.rs
@@ -85,15 +85,16 @@ fn main() {
}
};
+ match stmt.validate() {
+ Ok(()) => (),
+ Err(err) => {
+ println!("Validation error: {err:?}");
+ continue;
+ }
+ };
+
match &stmt {
rebel_parse::ast::BodyStmt::Assign { dest: _, expr } => {
- match expr.validate() {
- Ok(_) => (),
- Err(err) => {
- println!("Validation error: {err:?}");
- continue;
- }
- };
match Type::ast_expr_type(&ctx, expr) {
Ok(_) => (),
Err(err) => {
@@ -103,13 +104,6 @@ fn main() {
};
}
rebel_parse::ast::BodyStmt::Expr { expr } => {
- match expr.validate() {
- Ok(_) => (),
- Err(err) => {
- println!("Validation error: {err:?}");
- continue;
- }
- };
match Type::ast_expr_type(&ctx, expr) {
Ok(_) => (),
Err(err) => {
diff --git a/crates/rebel-parse/src/ast.rs b/crates/rebel-parse/src/ast.rs
index 1dcbdd9..e3b93ba 100644
--- a/crates/rebel-parse/src/ast.rs
+++ b/crates/rebel-parse/src/ast.rs
@@ -18,7 +18,34 @@ pub enum RecipeStmt<'a> {
},
}
-pub type Body<'a> = Vec<BodyStmt<'a>>;
+impl<'a> RecipeStmt<'a> {
+ pub fn validate(&self) -> Result<(), ValidationError> {
+ match self {
+ RecipeStmt::BodyStmt(stmt) => stmt.validate(),
+ RecipeStmt::Fetch { name: _, body } => body.validate(),
+ RecipeStmt::Task {
+ name: _,
+ params: _,
+ body,
+ } => {
+ // TODO: Validate params?
+ body.validate()
+ }
+ }
+ }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct Body<'a>(pub Vec<BodyStmt<'a>>);
+
+impl<'a> Body<'a> {
+ pub fn validate(&self) -> Result<(), ValidationError> {
+ for stmt in &self.0 {
+ stmt.validate()?;
+ }
+ Ok(())
+ }
+}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum BodyStmt<'a> {
@@ -40,6 +67,18 @@ impl<'a> BodyStmt<'a> {
None => BodyStmt::Assign { dest, expr },
}
}
+
+ pub fn validate(&self) -> Result<(), ValidationError> {
+ match self {
+ BodyStmt::Assign { dest, expr } => {
+ // TODO: Extend destination validation
+ dest.expr.validate()?;
+ expr.validate()
+ }
+ BodyStmt::Expr { expr } => expr.validate(),
+ BodyStmt::Empty => Ok(()),
+ }
+ }
}
#[derive(Debug, Clone, PartialEq, Eq)]
diff --git a/crates/rebel-parse/src/grammar/recipe.rs b/crates/rebel-parse/src/grammar/recipe.rs
index 71c2733..393b12c 100644
--- a/crates/rebel-parse/src/grammar/recipe.rs
+++ b/crates/rebel-parse/src/grammar/recipe.rs
@@ -13,7 +13,7 @@ peg::parser! {
pub rule recipe_stmt() -> ast::RecipeStmt<'a>
= keyword_fetch() name:ident() p('{') body:body() p('}') {
- ast::RecipeStmt::Fetch { name, body: Vec::new() }
+ ast::RecipeStmt::Fetch { name, body: ast::Body(Vec::new()) }
}
/ keyword_task() name:ident() p('(') params:func_params() p(')')
p('{') body:body() p('}') {
@@ -24,7 +24,7 @@ peg::parser! {
}
pub rule body() -> ast::Body<'a>
- = body:body_stmt() ++ p(';') { body }
+ = body:body_stmt() ++ p(';') { ast::Body(body) }
pub rule body_stmt() -> ast::BodyStmt<'a>
= dest:typed_expr() op:assign_op() expr:expr() {