use core::fmt;
use miden_debug_types::{SourceSpan, Span, Spanned};
use super::{Block, Immediate, Instruction};
#[derive(Clone)]
#[repr(u8)]
pub enum Op {
If {
span: SourceSpan,
then_blk: Block,
else_blk: Block,
} = 0,
While { span: SourceSpan, body: Block } = 1,
Repeat {
span: SourceSpan,
count: Immediate<u32>,
body: Block,
} = 2,
Inst(Span<Instruction>) = 3,
}
impl crate::prettier::PrettyPrint for Op {
fn render(&self) -> crate::prettier::Document {
use crate::prettier::*;
match self {
Self::If { then_blk, else_blk, .. } => {
text("if.true") + then_blk.render() + text("else") + else_blk.render() + text("end")
},
Self::While { body, .. } => text("while.true") + body.render() + text("end"),
Self::Repeat { count, body, .. } => {
display(format!("repeat.{count}")) + body.render() + text("end")
},
Self::Inst(inst) => inst.render(),
}
}
}
impl fmt::Debug for Op {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::If { then_blk, else_blk, .. } => {
f.debug_struct("If").field("then", then_blk).field("else", else_blk).finish()
},
Self::While { body, .. } => f.debug_tuple("While").field(body).finish(),
Self::Repeat { count, body, .. } => {
f.debug_struct("Repeat").field("count", count).field("body", body).finish()
},
Self::Inst(inst) => fmt::Debug::fmt(&**inst, f),
}
}
}
impl Eq for Op {}
impl PartialEq for Op {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(
Self::If { then_blk: lt, else_blk: le, .. },
Self::If { then_blk: rt, else_blk: re, .. },
) => lt == rt && le == re,
(Self::While { body: lbody, .. }, Self::While { body: rbody, .. }) => lbody == rbody,
(
Self::Repeat { count: lcount, body: lbody, .. },
Self::Repeat { count: rcount, body: rbody, .. },
) => lcount == rcount && lbody == rbody,
(Self::Inst(l), Self::Inst(r)) => l == r,
_ => false,
}
}
}
impl Spanned for Op {
fn span(&self) -> SourceSpan {
match self {
Self::If { span, .. } | Self::While { span, .. } | Self::Repeat { span, .. } => *span,
Self::Inst(spanned) => spanned.span(),
}
}
}