statement body parsing

This commit is contained in:
2026-05-24 12:55:33 +02:00
parent 6551aee03b
commit f4fe38140a
3 changed files with 48 additions and 11 deletions
+20 -5
View File
@@ -8,27 +8,33 @@ pub struct Block(
pub Option<Spanned<Expression>>, pub Option<Spanned<Expression>>,
); );
#[derive(Debug, Clone, Serialize)]
pub enum StatementBody {
Statement(Box<Statement>),
Expression(Expression),
}
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]
pub enum Statement { pub enum Statement {
Block(Block), Block(Block),
If { If {
initial: StatementBranch, initial: StatementBranch,
else_if: Vec<StatementBranch>, else_if: Vec<StatementBranch>,
else_branch: Option<Expression>, else_branch: Option<StatementBody>,
}, },
Loop(Expression), Loop(StatementBody),
While(StatementBranch), While(StatementBranch),
CStyleFor { CStyleFor {
init: Expression, init: Expression,
condition: Expression, condition: Expression,
update: Expression, update: Expression,
body: Expression, body: StatementBody,
}, },
For { For {
mutable: bool, mutable: bool,
pattern: Pattern, pattern: Pattern,
iterator: Expression, iterator: Expression,
body: Expression, body: StatementBody,
}, },
Match(Expression, Vec<(Vec<Pattern>, Expression)>), Match(Expression, Vec<(Vec<Pattern>, Expression)>),
@@ -54,7 +60,7 @@ pub struct VarDeclStmt {
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]
pub struct StatementBranch { pub struct StatementBranch {
pub condition: Expression, pub condition: Expression,
pub body: Box<Expression>, pub body: Box<StatementBody>,
} }
impl Statement { impl Statement {
@@ -84,3 +90,12 @@ impl Statement {
} }
} }
} }
impl StatementBody {
pub fn is_block(&self) -> bool {
match self {
Self::Expression(_) => false,
_ => true,
}
}
}
+9 -5
View File
@@ -343,6 +343,10 @@ statement = _{
| (expr ~ semicolon) | (expr ~ semicolon)
} }
statement_wrapper = { statement }
statement_body = { statement_wrapper | expr }
// ------------------------------------------------------ // ------------------------------------------------------
// BASIC STATEMENTS // BASIC STATEMENTS
// ------------------------------------------------------ // ------------------------------------------------------
@@ -384,7 +388,7 @@ control_flow = {
| block | block
} }
statement_branch = { "(" ~ expr ~ ")" ~ statement } statement_branch = { "(" ~ expr ~ ")" ~ statement_body }
else_if = { else_if = {
"else" ~ "if" ~ statement_branch "else" ~ "if" ~ statement_branch
@@ -395,7 +399,7 @@ else_if_list = {
} }
if_stmt = { if_stmt = {
"if" ~ statement_branch ~ else_if_list ~ ("else" ~ statement)? "if" ~ statement_branch ~ else_if_list ~ ("else" ~ statement_body)?
} }
// ------------------------------------------------------ // ------------------------------------------------------
@@ -407,15 +411,15 @@ while_stmt = {
} }
c_for_stmt = { c_for_stmt = {
"for" ~ "(" ~ statement ~ statement ~ expr ~ ")" ~ statement "for" ~ "(" ~ statement ~ statement ~ expr ~ ")" ~ statement_body
} }
for_stmt = { for_stmt = {
"for" ~ "(" ~ mutable? ~ pattern ~ ":" ~ expr ~ ")" ~ statement "for" ~ "(" ~ mutable? ~ pattern ~ ":" ~ expr ~ ")" ~ statement_body
} }
loop_stmt = { loop_stmt = {
"loop" ~ statement "loop" ~ statement_body
} }
// ------------------------------------------------------ // ------------------------------------------------------
+19 -1
View File
@@ -18,6 +18,24 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Block {
} }
} }
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for StatementBody {
type Error = AstError<'a, Self>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let mut inner = pair.clone().into_inner();
ast_ensure!(pair, Rule::statement_body => {
let i = inner.next().unwrap();
match i.as_rule() {
Rule::expr => ast_expr!(StatementBody::Expression(i.try_into())),
Rule::statement_wrapper => ast_expr!(StatementBody::Statement(i.try_into().map(Box::new).get_map(Box::new))),
_ => AstError::bug_unimplemented(i),
}
})
}
}
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for StatementBranch { impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for StatementBranch {
type Error = AstError<'a, Self>; type Error = AstError<'a, Self>;
@@ -63,7 +81,7 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Statement {
ast_expr!(Statement::If { ast_expr!(Statement::If {
initial: inner.next().unwrap().try_into(), initial: inner.next().unwrap().try_into(),
else_if: collect_recovered(inner.next().unwrap().into_inner()), else_if: collect_recovered(inner.next().unwrap().into_inner()),
else_branch: inner.next().map(Expression::try_from).transpose(), else_branch: inner.next().map(StatementBody::try_from).transpose(),
}) })
} }