use rucc_base::Symbol;
use crate::asm::AsmId;
use crate::ast::{AttrList, StmtList, SymbolList};
use crate::decl::DeclId;
use crate::expr::ExprId;
pub type StmtId = rucc_base::Idx<Stmt>;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Stmt {
Error,
Empty,
Expr(ExprId),
Decl(DeclId),
Compound(StmtList),
If {
cond: ExprId,
then: StmtId,
otherwise: Option<StmtId>,
},
Switch {
scrutinee: ExprId,
body: StmtId,
},
While {
cond: ExprId,
body: StmtId,
},
DoWhile {
body: StmtId,
cond: ExprId,
},
For {
init: ForInit,
cond: Option<ExprId>,
step: Option<ExprId>,
body: StmtId,
},
Goto(Symbol),
GotoExpr(ExprId),
Continue,
Break,
Return(Option<ExprId>),
Label {
name: Symbol,
body: Option<StmtId>,
attrs: AttrList,
},
Case {
lo: ExprId,
hi: Option<ExprId>,
body: Option<StmtId>,
},
Default {
body: Option<StmtId>,
},
LocalLabels(SymbolList),
Asm(AsmId),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ForInit {
None,
Expr(ExprId),
Decl(DeclId),
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn a_statement_is_twenty_bytes() {
assert_eq!(size_of::<Stmt>(), 20);
}
#[test]
fn a_statement_id_is_four_bytes_even_when_optional() {
assert_eq!(size_of::<StmtId>(), 4);
assert_eq!(size_of::<Option<StmtId>>(), 4);
}
#[test]
fn a_for_clause_is_eight_bytes() {
assert_eq!(size_of::<ForInit>(), 8);
}
}