py_declare/
mir.rs

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                // String: greatly in processing...
44                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>>);