1pub trait IntoIR {
2 type Forward;
3 fn into_ir(self, map: &crate::DeclareGraph) -> Self::Forward;
4}
5
6pub mod mir_variable {
7 use crate::{branches, BranchesBuilder, DeclareGraph, GroupIdx};
8 use py_ir as ir;
9 use py_ir::value::Literal;
10 use py_lex::ops::Operators;
11
12 use super::IntoIR;
13
14 #[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
15 pub enum Value {
16 Literal(Literal),
17 Variable(String),
18 }
19
20 impl From<Literal> for Value {
21 fn from(v: Literal) -> Self {
22 Self::Literal(v)
23 }
24 }
25
26 #[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
27 pub struct Undeclared<V> {
28 pub val: V,
29 pub ty: GroupIdx,
30 }
31
32 impl<V> Undeclared<V> {
33 pub fn new(val: V, ty: GroupIdx) -> Self {
34 Self { val, ty }
35 }
36 }
37
38 impl Undeclared<Value> {
39 pub fn literal_branches(var: &Literal) -> Vec<BranchesBuilder> {
40 use py_ir::types::PrimitiveType;
41 match var {
42 Literal::Char(_) => branches! {() => PrimitiveType::char()},
43 Literal::Integer(_) => branches! {
45 () => PrimitiveType::U8, () => PrimitiveType::U16,
46 () => PrimitiveType::U32,() => PrimitiveType::U64,
47 () => PrimitiveType::U128,() => PrimitiveType::Usize,
48 () => PrimitiveType::I8, () => PrimitiveType::I16,
49 () => PrimitiveType::I32,() => PrimitiveType::I64,
50 () => PrimitiveType::I128,() => PrimitiveType::Isize
51
52 },
53 Literal::Float(_) => branches! {
54 () => PrimitiveType::F32,
55 () => PrimitiveType::F64
56 },
57 }
58 }
59 }
60
61 #[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
62 pub enum AssignValue {
63 Value(Value),
64 FnCall(FnCall),
65 Operate(Operate),
66 }
67
68 impl From<Value> for AssignValue {
69 fn from(v: Value) -> Self {
70 Self::Value(v)
71 }
72 }
73
74 impl From<FnCall> for AssignValue {
75 fn from(v: FnCall) -> Self {
76 Self::FnCall(v)
77 }
78 }
79
80 impl From<Operate> for AssignValue {
81 fn from(v: Operate) -> Self {
82 Self::Operate(v)
83 }
84 }
85
86 #[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
87 pub enum Operate {
88 Unary(Operators, Undeclared<Value>),
89 Binary(Operators, Undeclared<Value>, Undeclared<Value>),
90 }
91
92 #[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
93 pub struct FnCall {
94 pub args: Vec<Undeclared<Value>>,
95 }
96
97 impl py_ir::IRValue for Undeclared<Value> {
98 type AssignValue = Undeclared<AssignValue>;
99 type VarDefineType = GroupIdx;
100 type FnDefineType = ir::types::TypeDefine;
101 type ParameterType = ir::types::TypeDefine;
102 }
103
104 impl IntoIR for Undeclared<Value> {
105 type Forward = ir::value::Value;
106
107 fn into_ir(self, map: &crate::DeclareGraph) -> Self::Forward {
108 match self.val {
109 Value::Literal(literal) => {
110 let ty = *map.get_type(self.ty).as_primitive().unwrap();
111 ir::value::Value::Literal(literal, ty)
112 }
113 Value::Variable(variable) => ir::value::Value::Variable(variable),
114 }
115 }
116 }
117
118 impl IntoIR for Undeclared<AssignValue> {
119 type Forward = ir::value::AssignValue;
120
121 fn into_ir(self, map: &DeclareGraph) -> Self::Forward {
122 match self.val {
123 AssignValue::Value(value) => Undeclared::new(value, self.ty).into_ir(map).into(),
124 AssignValue::FnCall(fn_call) => {
125 let fn_name = map[self.ty].result().overload().name.clone();
126 ir::value::FnCall {
127 fn_name,
128 args: fn_call.args.into_ir(map),
129 }
130 .into()
131 }
132 AssignValue::Operate(operate) => {
133 let ty = *map.get_type(self.ty).as_primitive().unwrap();
134 let operate = match operate {
135 Operate::Unary(op, l) => ir::value::Operate::Unary(op, l.into_ir(map)),
136 Operate::Binary(op, l, r) => {
137 ir::value::Operate::Binary(op, l.into_ir(map), r.into_ir(map))
138 }
139 };
140 (operate, ty).into()
141 }
142 }
143 }
144 }
145
146 impl IntoIR for Vec<Undeclared<Value>> {
147 type Forward = Vec<ir::value::Value>;
148
149 fn into_ir(self, map: &DeclareGraph) -> Self::Forward {
150 self.into_iter().map(|val| val.into_ir(map)).collect()
151 }
152 }
153}
154
155pub use mir_variable::*;
156
157mod into_ir_impls {
158
159 use super::{IntoIR, Undeclared};
160 use crate::DeclareGraph;
161 use py_ir::value::Value;
162 use py_ir::*;
163
164 type MirVariable = Undeclared<super::Value>;
165
166 impl IntoIR for Item<MirVariable> {
167 type Forward = Item<Value>;
168
169 fn into_ir(self, map: &DeclareGraph) -> Self::Forward {
170 match self {
171 Item::FnDefine(fn_define) => fn_define.into_ir(map).into(),
172 }
173 }
174 }
175
176 impl IntoIR for FnDefine<MirVariable> {
177 type Forward = FnDefine<Value>;
178
179 fn into_ir(self, map: &DeclareGraph) -> Self::Forward {
180 FnDefine {
181 export: self.export,
182 ty: self.ty,
183 name: self.name,
184 params: self.params,
185 body: self.body.into_ir(map),
186 }
187 }
188 }
189
190 impl IntoIR for Statements<MirVariable> {
191 type Forward = Statements<Value>;
192
193 fn into_ir(self, map: &DeclareGraph) -> Self::Forward {
194 Statements {
195 stmts: self
196 .stmts
197 .into_iter()
198 .map(|stmt| stmt.into_ir(map))
199 .collect(),
200 returned: self.returned,
201 }
202 }
203 }
204
205 impl IntoIR for Statement<MirVariable> {
206 type Forward = Statement<Value>;
207
208 fn into_ir(self, map: &DeclareGraph) -> Self::Forward {
209 match self {
210 Statement::VarDefine(item) => item.into_ir(map).into(),
211 Statement::VarStore(item) => item.into_ir(map).into(),
212 Statement::Block(item) => item.into_ir(map).into(),
213 Statement::If(item) => item.into_ir(map).into(),
214 Statement::While(item) => item.into_ir(map).into(),
215 Statement::Return(item) => item.into_ir(map).into(),
216 }
217 }
218 }
219
220 impl IntoIR for VarDefine<MirVariable> {
221 type Forward = VarDefine<Value>;
222
223 fn into_ir(self, map: &DeclareGraph) -> Self::Forward {
224 let ty = map.get_type(self.ty).clone();
225 VarDefine {
226 ty,
227 name: self.name,
228 init: self.init.map(|init| init.into_ir(map)),
229 is_temp: self.is_temp,
230 }
231 }
232 }
233
234 impl IntoIR for VarStore<MirVariable> {
235 type Forward = VarStore<Value>;
236
237 fn into_ir(self, map: &DeclareGraph) -> Self::Forward {
238 VarStore {
239 name: self.name,
240 val: self.val.into_ir(map),
241 }
242 }
243 }
244
245 impl IntoIR for Condition<MirVariable> {
246 type Forward = Condition<Value>;
247
248 fn into_ir(self, map: &DeclareGraph) -> Self::Forward {
249 Condition {
250 val: self.val.into_ir(map),
251 compute: self.compute.into_ir(map),
252 }
253 }
254 }
255
256 impl IntoIR for IfBranch<MirVariable> {
257 type Forward = IfBranch<Value>;
258
259 fn into_ir(self, map: &DeclareGraph) -> Self::Forward {
260 IfBranch {
261 cond: self.cond.into_ir(map),
262 body: self.body.into_ir(map),
263 }
264 }
265 }
266
267 impl IntoIR for If<MirVariable> {
268 type Forward = If<Value>;
269
270 fn into_ir(self, map: &DeclareGraph) -> Self::Forward {
271 If {
272 branches: self
273 .branches
274 .into_iter()
275 .map(|branch| branch.into_ir(map))
276 .collect(),
277 else_: self.else_.map(|else_| else_.into_ir(map)),
278 }
279 }
280 }
281
282 impl IntoIR for While<MirVariable> {
283 type Forward = While<Value>;
284
285 fn into_ir(self, map: &DeclareGraph) -> Self::Forward {
286 While {
287 cond: self.cond.into_ir(map),
288 body: self.body.into_ir(map),
289 }
290 }
291 }
292
293 impl IntoIR for Return<MirVariable> {
294 type Forward = Return<Value>;
295
296 fn into_ir(self, map: &DeclareGraph) -> Self::Forward {
297 Return {
298 val: self.val.map(|val| val.into_ir(map)),
299 }
300 }
301 }
302}
303
304py_ir::custom_ir_variable!(pub IR<Undeclared<mir_variable::Value>>);