diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2024-05-04 13:45:43 +0200 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2024-05-04 20:14:47 +0200 |
commit | 318a842241fccef0184c69e31a7d08306799c6c6 (patch) | |
tree | 74ac021a78a06f4f253793c98c87149d705ec675 /crates/rebel-parse | |
parent | 50443fbd17651861a738d940d8ebd2883f6f2651 (diff) | |
download | rebel-318a842241fccef0184c69e31a7d08306799c6c6.tar rebel-318a842241fccef0184c69e31a7d08306799c6c6.zip |
rebel-parse, rebel-lang: implement if-else expressions
Diffstat (limited to 'crates/rebel-parse')
-rw-r--r-- | crates/rebel-parse/src/ast/expr.rs | 17 | ||||
-rw-r--r-- | crates/rebel-parse/src/grammar/recipe.rs | 15 |
2 files changed, 29 insertions, 3 deletions
diff --git a/crates/rebel-parse/src/ast/expr.rs b/crates/rebel-parse/src/ast/expr.rs index 2e8d750..3994296 100644 --- a/crates/rebel-parse/src/ast/expr.rs +++ b/crates/rebel-parse/src/ast/expr.rs @@ -34,6 +34,10 @@ pub enum Expr<'a> { field: Ident<'a>, }, Block(Block<'a>), + IfElse { + if_blocks: Vec<(Expr<'a>, Block<'a>)>, + else_block: Option<Box<Block<'a>>>, + }, Paren(Box<Expr<'a>>), Path(Path<'a>), Literal(Literal<'a>), @@ -129,6 +133,19 @@ impl<'a> Expr<'a> { } Ok(()) } + Expr::IfElse { + if_blocks, + else_block, + } => { + for (cond, block) in if_blocks { + cond.validate()?; + block.validate()?; + } + if let Some(block) = else_block { + block.validate()?; + } + Ok(()) + } Expr::Paren(expr) => expr.validate(), Expr::Path(_) => Ok(()), Expr::Literal(lit) => lit.validate(), diff --git a/crates/rebel-parse/src/grammar/recipe.rs b/crates/rebel-parse/src/grammar/recipe.rs index 11f1ce6..1ada80c 100644 --- a/crates/rebel-parse/src/grammar/recipe.rs +++ b/crates/rebel-parse/src/grammar/recipe.rs @@ -133,15 +133,24 @@ peg::parser! { } base:@ p('.') field:field() { Expr::field(base, field) } -- - p('(') e:expr() p(')') { Expr::paren(e) } - p('{') block:block() p('}') { Expr::Block(block) } e:atom() { e } } rule atom() -> Expr<'a> - = lit:literal() { Expr::Literal(lit) } + = p('(') e:expr() p(')') { Expr::paren(e) } + / [Token::Keyword(Keyword::If)] + if_blocks:(cond_block() ++ ([Token::Keyword(Keyword::Else)] [Token::Keyword(Keyword::If)])) + else_block:([Token::Keyword(Keyword::Else)] p('{') block:block() p('}') { Box::new(block) })? + { + Expr::IfElse { if_blocks, else_block } + } + / p('{') block:block() p('}') { Expr::Block(block) } + / lit:literal() { Expr::Literal(lit) } / path:path() { Expr::Path(path) } + rule cond_block() -> (Expr<'a>, ast::Block<'a>) + = cond:expr() p('{') block:block() p('}') { (cond, block) } + rule call_params() -> Vec<expr::Expr<'a>> = args:delimited(<expr()>, <p(',')>) { args } |