1use core::fmt::Display;
2
3use cairo_lang_utils::bigint::BigIntAsHex;
4
5#[cfg(test)]
6#[path = "operand_test.rs"]
7mod test;
8
9#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
10#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
11#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
12#[cfg_attr(
13 feature = "parity-scale-codec",
14 derive(parity_scale_codec::Encode, parity_scale_codec::Decode)
15)]
16pub enum Register {
17 #[cfg_attr(feature = "parity-scale-codec", codec(index = 0))]
18 AP,
19 #[cfg_attr(feature = "parity-scale-codec", codec(index = 1))]
20 FP,
21}
22impl Display for Register {
23 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
24 match self {
25 Register::AP => write!(f, "ap"),
26 Register::FP => write!(f, "fp"),
27 }
28 }
29}
30
31#[derive(Clone, Debug, Eq, PartialEq)]
33#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
34#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
35#[cfg_attr(
36 feature = "parity-scale-codec",
37 derive(parity_scale_codec::Encode, parity_scale_codec::Decode)
38)]
39pub enum ResOperand {
40 #[cfg_attr(feature = "parity-scale-codec", codec(index = 0))]
41 Deref(CellRef),
42 #[cfg_attr(feature = "parity-scale-codec", codec(index = 1))]
43 DoubleDeref(CellRef, i16),
44 #[cfg_attr(feature = "parity-scale-codec", codec(index = 2))]
45 Immediate(BigIntAsHex),
46 #[cfg_attr(feature = "parity-scale-codec", codec(index = 3))]
47 BinOp(BinOpOperand),
48}
49impl Display for ResOperand {
50 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
51 match self {
52 ResOperand::Deref(operand) => write!(f, "{operand}"),
53 ResOperand::DoubleDeref(operand, offset) => write!(f, "[{operand} + {offset}]"),
54 ResOperand::Immediate(operand) => write!(f, "{}", operand.value),
55 ResOperand::BinOp(operand) => write!(f, "{operand}"),
56 }
57 }
58}
59impl From<DerefOrImmediate> for ResOperand {
60 fn from(x: DerefOrImmediate) -> Self {
61 match x {
62 DerefOrImmediate::Deref(deref) => ResOperand::Deref(deref),
63 DerefOrImmediate::Immediate(imm) => ResOperand::Immediate(imm),
64 }
65 }
66}
67
68impl<T: Into<BigIntAsHex>> From<T> for ResOperand {
69 fn from(imm: T) -> Self {
70 ResOperand::Immediate(imm.into())
71 }
72}
73
74#[derive(Copy, Clone, Debug, Eq, PartialEq)]
76#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
77#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
78#[cfg_attr(
79 feature = "parity-scale-codec",
80 derive(parity_scale_codec::Encode, parity_scale_codec::Decode)
81)]
82pub struct CellRef {
83 pub register: Register,
84 pub offset: i16,
85}
86impl Display for CellRef {
87 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
88 write!(f, "[{} + {}]", self.register, self.offset)
89 }
90}
91
92pub fn ap_cell_ref(offset: i16) -> CellRef {
94 CellRef { register: Register::AP, offset }
95}
96
97#[derive(Clone, Debug, Eq, PartialEq)]
98#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
99#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
100#[cfg_attr(
101 feature = "parity-scale-codec",
102 derive(parity_scale_codec::Encode, parity_scale_codec::Decode)
103)]
104pub enum DerefOrImmediate {
105 #[cfg_attr(feature = "parity-scale-codec", codec(index = 0))]
106 Deref(CellRef),
107 #[cfg_attr(feature = "parity-scale-codec", codec(index = 1))]
108 Immediate(BigIntAsHex),
109}
110impl Display for DerefOrImmediate {
111 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
112 match self {
113 DerefOrImmediate::Deref(operand) => write!(f, "{operand}"),
114 DerefOrImmediate::Immediate(operand) => write!(f, "{}", operand.value),
115 }
116 }
117}
118impl<T: Into<BigIntAsHex>> From<T> for DerefOrImmediate {
119 fn from(x: T) -> Self {
120 DerefOrImmediate::Immediate(x.into())
121 }
122}
123impl From<CellRef> for DerefOrImmediate {
124 fn from(x: CellRef) -> Self {
125 DerefOrImmediate::Deref(x)
126 }
127}
128
129#[derive(Clone, Debug, Eq, PartialEq)]
130#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
131#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
132#[cfg_attr(
133 feature = "parity-scale-codec",
134 derive(parity_scale_codec::Encode, parity_scale_codec::Decode)
135)]
136pub enum Operation {
137 #[cfg_attr(feature = "parity-scale-codec", codec(index = 0))]
138 Add,
139 #[cfg_attr(feature = "parity-scale-codec", codec(index = 1))]
140 Mul,
141}
142impl Display for Operation {
143 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
144 match self {
145 Operation::Add => write!(f, "+"),
146 Operation::Mul => write!(f, "*"),
147 }
148 }
149}
150
151#[derive(Clone, Debug, Eq, PartialEq)]
152#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
153#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
154#[cfg_attr(
155 feature = "parity-scale-codec",
156 derive(parity_scale_codec::Encode, parity_scale_codec::Decode)
157)]
158pub struct BinOpOperand {
159 pub op: Operation,
160 pub a: CellRef,
161 pub b: DerefOrImmediate,
162}
163impl Display for BinOpOperand {
164 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
165 write!(f, "{} {} {}", self.a, self.op, self.b)
166 }
167}