miden_assembly_syntax/ast/
op.rs1use core::fmt;
2
3use miden_debug_types::{SourceSpan, Span, Spanned};
4
5use super::{Block, Immediate, Instruction};
6
7#[derive(Clone)]
12#[repr(u8)]
13pub enum Op {
14 If {
18 span: SourceSpan,
19 then_blk: Block,
21 else_blk: Block,
23 } = 0,
24 While { span: SourceSpan, body: Block } = 1,
26 DoWhile {
32 span: SourceSpan,
33 body: Block,
34 condition: Block,
35 } = 4,
36 Repeat {
42 span: SourceSpan,
43 count: Immediate<u32>,
44 body: Block,
45 } = 2,
46 Inst(Span<Instruction>) = 3,
48}
49
50impl crate::prettier::PrettyPrint for Op {
51 fn render(&self) -> crate::prettier::Document {
52 use crate::prettier::*;
53
54 match self {
55 Self::If { then_blk, else_blk, .. } => {
56 text("if.true") + then_blk.render() + text("else") + else_blk.render() + text("end")
57 },
58 Self::While { body, .. } => text("while.true") + body.render() + text("end"),
59 Self::DoWhile { body, condition, .. } => {
60 text("do") + body.render() + text("while") + condition.render() + text("end")
61 },
62 Self::Repeat { count, body, .. } => {
63 display(format!("repeat.{count}")) + body.render() + text("end")
64 },
65 Self::Inst(inst) => inst.render(),
66 }
67 }
68}
69
70impl fmt::Debug for Op {
71 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
72 match self {
73 Self::If { then_blk, else_blk, .. } => {
74 f.debug_struct("If").field("then", then_blk).field("else", else_blk).finish()
75 },
76 Self::While { body, .. } => f.debug_tuple("While").field(body).finish(),
77 Self::DoWhile { body, condition, .. } => f
78 .debug_struct("DoWhile")
79 .field("body", body)
80 .field("condition", condition)
81 .finish(),
82 Self::Repeat { count, body, .. } => {
83 f.debug_struct("Repeat").field("count", count).field("body", body).finish()
84 },
85 Self::Inst(inst) => fmt::Debug::fmt(&**inst, f),
86 }
87 }
88}
89
90impl Eq for Op {}
91
92impl PartialEq for Op {
93 fn eq(&self, other: &Self) -> bool {
94 match (self, other) {
95 (
96 Self::If { then_blk: lt, else_blk: le, .. },
97 Self::If { then_blk: rt, else_blk: re, .. },
98 ) => lt == rt && le == re,
99 (Self::While { body: lbody, .. }, Self::While { body: rbody, .. }) => lbody == rbody,
100 (
101 Self::DoWhile { body: lbody, condition: lcond, .. },
102 Self::DoWhile { body: rbody, condition: rcond, .. },
103 ) => lbody == rbody && lcond == rcond,
104 (
105 Self::Repeat { count: lcount, body: lbody, .. },
106 Self::Repeat { count: rcount, body: rbody, .. },
107 ) => lcount == rcount && lbody == rbody,
108 (Self::Inst(l), Self::Inst(r)) => l == r,
109 _ => false,
110 }
111 }
112}
113
114impl Spanned for Op {
115 fn span(&self) -> SourceSpan {
116 match self {
117 Self::If { span, .. }
118 | Self::While { span, .. }
119 | Self::DoWhile { span, .. }
120 | Self::Repeat { span, .. } => *span,
121 Self::Inst(spanned) => spanned.span(),
122 }
123 }
124}