1use std::fmt::Display;
2
3use crate::{
4 frontend::token::Operator,
5 model::{guard::ProcessConstraint, Data},
6};
7
8use owo_colors::OwoColorize;
9
10#[derive(Debug, Clone)]
12pub enum LMNtalIR {
13 CreateAtom {
15 id: usize,
16 name: String,
17 arity: usize,
18 data: Data,
19 },
20 RemoveAtom {
25 id: usize,
26 },
27 RemoveAtomAt {
29 id: usize,
30 port: usize,
31 },
32 CloneAtom {
34 id: usize,
35 from_id: usize,
36 from_port: usize,
37 },
38
39 Link {
41 src: VarSource,
42 dst: VarSource,
43 },
44 Relink {
46 src: usize,
47 src_port: usize,
48 dst: VarSource,
49 },
50
51 CreateHyperlink {
55 id: usize,
56 name: String,
57 },
58 LinkToHyperlink {
60 atom: VarSource,
61 hyperlink: VarSource,
62 },
63 RemoveFromHyperlink {
65 atom: VarSource,
66 hyperlink: VarSource,
67 },
68 FuseHyperlink {
72 into: VarSource,
73 from: VarSource,
74 },
75
76 FindAtom {
80 id: usize,
81 name: String,
82 arity: usize,
83 },
84 GetAtomAtPort {
86 id: usize,
87 from: usize,
88 port: usize,
89 name: String,
90 arity: usize,
91 },
92 GetHyperlinkAtPort {
94 id: usize,
95 from: usize,
96 port: usize,
97 },
98 AtomEqualityIdPort {
100 id_port_list: Vec<(usize, usize)>,
102 eq: bool,
104 },
105 AtomEquality {
107 id_list: Vec<usize>,
109 eq: bool,
111 hyperlinks: bool,
113 },
114 CheckType {
116 id: usize,
117 port: usize,
118 ty: ProcessConstraint,
119 },
120 CheckValue(Operation),
122 DefineTempVar {
124 id: usize,
125 name: String,
126 ty: ProcessConstraint,
127 op: Operation,
128 },
129 Unify {
130 into: VarSource,
131 from: VarSource,
132 },
133}
134
135impl Display for LMNtalIR {
136 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
137 match self {
138 LMNtalIR::CreateAtom {
139 id,
140 name,
141 arity,
142 data,
143 } => {
144 write!(
145 f,
146 "create atom at {} with name: {} arity: {} data: {}",
147 id.underline().bold(),
148 name,
149 arity,
150 data
151 )
152 }
153 LMNtalIR::RemoveAtom { id } => write!(f, "remove atom at {}", id.underline().bold()),
154 LMNtalIR::CloneAtom {
155 id,
156 from_id,
157 from_port,
158 } => {
159 write!(
160 f,
161 "clone atom into {} from {} port {} ",
162 id.underline().bold(),
163 from_id,
164 from_port
165 )
166 }
167 LMNtalIR::Link { src, dst } => write!(f, "link {} with {}", src, dst,),
168 LMNtalIR::Relink { src, src_port, dst } => {
169 write!(f, "relink {} port {} with {}", src, src_port, dst)
170 }
171 LMNtalIR::FindAtom { id, name, arity } => {
172 write!(
173 f,
174 "find_atom into {} with name: {} arity: {}",
175 id.underline().bold(),
176 name,
177 arity
178 )
179 }
180 LMNtalIR::GetAtomAtPort {
181 id,
182 from,
183 port,
184 name,
185 arity,
186 } => write!(
187 f,
188 "get atom into {} from {} port {} with name: {} arity: {}",
189 id.underline().bold(),
190 from.underline().bold(),
191 port,
192 name,
193 arity
194 ),
195 LMNtalIR::GetHyperlinkAtPort { id, from, port } => write!(
196 f,
197 "get hyperlink into {} from {} port {}",
198 id.underline().bold(),
199 from.underline().bold(),
200 port,
201 ),
202 LMNtalIR::AtomEqualityIdPort { id_port_list, eq } => {
203 let predicate = if *eq { "are" } else { "are not" };
204 write!(f, "atoms {} equal:\n\t\t", predicate)?;
205 for (id, port) in id_port_list {
206 write!(f, "at {} port {},", id.underline().bold(), port)?;
207 }
208 Ok(())
209 }
210 LMNtalIR::AtomEquality {
211 id_list,
212 eq,
213 hyperlinks,
214 } => {
215 let content = if *hyperlinks { "hyperlinks" } else { "atoms" };
216 let predicate = if *eq { "are" } else { "are not" };
217 write!(f, "{} {} equal:\n\t\t", content, predicate)?;
218 for id in id_list {
219 write!(f, "at {},", id.underline().bold())?;
220 }
221 Ok(())
222 }
223 LMNtalIR::CheckType { id, port, ty } => write!(
224 f,
225 "check type at {} port {} is {}",
226 id.underline().bold(),
227 port,
228 ty
229 ),
230 LMNtalIR::CheckValue(op) => write!(f, "check if {}", op),
231 LMNtalIR::DefineTempVar { id, name, ty, op } => {
232 write!(
233 f,
234 "define a temp var at {} {} {} {}",
235 id.underline().bold(),
236 name,
237 ty,
238 op
239 )
240 }
241 LMNtalIR::RemoveAtomAt { id, port } => {
242 write!(f, "remove atom at {} port {}", id.underline().bold(), port)
243 }
244 LMNtalIR::CreateHyperlink { id, name } => {
245 write!(
246 f,
247 "create hyperlink at {} with name: {}",
248 id.underline().bold(),
249 name,
250 )
251 }
252 LMNtalIR::LinkToHyperlink { atom, hyperlink } => {
253 write!(f, "add atom {} to hyperlink {}", atom, hyperlink)
254 }
255 LMNtalIR::RemoveFromHyperlink { atom, hyperlink } => {
256 write!(f, "remove atom {} from hyperlink {}", atom, hyperlink)
257 }
258 LMNtalIR::FuseHyperlink { into, from } => {
259 write!(f, "fuse hyperlink {} into hyperlink {}", from, into)
260 }
261 LMNtalIR::Unify { into, from } => {
262 write!(f, "unify {} with {}", from, into)
263 }
264 }
265 }
266}
267
268#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
269pub enum VarSource {
270 Head(usize, usize),
271 Variable(usize),
272 Body(usize, usize),
273}
274
275impl VarSource {
276 pub fn id(&self) -> usize {
277 match self {
278 VarSource::Head(id, _) => *id,
279 VarSource::Variable(id) => *id,
280 VarSource::Body(id, _) => *id,
281 }
282 }
283}
284
285impl Display for VarSource {
286 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
287 match self {
288 VarSource::Head(id, port) => write!(f, "head {} port {}", id.underline().bold(), port),
289 VarSource::Variable(id) => write!(f, "temp {}", id.underline().bold()),
290 VarSource::Body(id, port) => write!(f, "body {} port {}", id.underline().bold(), port),
291 }
292 }
293}
294
295#[derive(Debug, Clone)]
296pub enum Operation {
297 Literal(Literal),
298 Variable {
299 source: VarSource,
300 ty_: ProcessConstraint,
301 },
302 BinaryOP {
303 op: BinaryOperator,
304 lhs: Box<Operation>,
305 rhs: Box<Operation>,
306 },
307 UnaryOP {
308 op: UnaryOperator,
309 operand: Box<Operation>,
310 },
311 FunctionCall {
312 name: String,
313 args: Vec<Operation>,
314 ty_: ProcessConstraint,
315 },
316}
317
318impl Display for Operation {
319 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
320 match self {
321 Operation::Literal(l) => write!(f, "{}", l),
322 Operation::Variable { source, ty_ } => match source {
323 VarSource::Head(id, port) => {
324 write!(
325 f,
326 "(var at {} port {} with type {})",
327 id.underline().bold(),
328 port,
329 ty_
330 )
331 }
332 VarSource::Variable(id) => {
333 write!(f, "(var at {} with type {})", id.underline().bold(), ty_)
334 }
335 VarSource::Body(id, port) => {
336 write!(
337 f,
338 "(var at {} port {} with type {})",
339 id.underline().bold(),
340 port,
341 ty_
342 )
343 }
344 },
345 Operation::BinaryOP { op, lhs, rhs } => write!(f, "({} {} {})", lhs, op, rhs),
346 Operation::UnaryOP { op, operand } => write!(f, "({} {})", op, operand),
347 Operation::FunctionCall { name, args, .. } => {
348 write!(
349 f,
350 "{}({})",
351 name,
352 args.iter()
353 .map(|a| format!("{}", a))
354 .collect::<Vec<String>>()
355 .join(", ")
356 )
357 }
358 }
359 }
360}
361
362#[derive(Debug, Clone, PartialEq)]
363pub enum Literal {
364 Int(i64),
365 Float(f64),
366 Char(char),
367 String(String),
368}
369
370impl Display for Literal {
371 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
372 match self {
373 Literal::Int(i) => write!(f, "{}", i),
374 Literal::Float(fl) => write!(f, "{}", fl),
375 Literal::Char(c) => write!(f, "{}", c),
376 Literal::String(s) => write!(f, "{}", s),
377 }
378 }
379}
380
381#[derive(Debug, Clone, Copy)]
382pub enum BinaryOperator {
383 Add,
384 Sub,
385 Mul,
386 Div,
387 Mod,
388 Pow,
389 Eq,
390 Ne,
391 Lt,
392 Le,
393 Gt,
394 Ge,
395}
396
397impl Display for BinaryOperator {
398 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
399 let s = match self {
400 BinaryOperator::Add => "+",
401 BinaryOperator::Sub => "-",
402 BinaryOperator::Mul => "*",
403 BinaryOperator::Div => "/",
404 BinaryOperator::Mod => "%",
405 BinaryOperator::Pow => "**",
406 BinaryOperator::Eq => "==",
407 BinaryOperator::Ne => "!=",
408 BinaryOperator::Lt => "<",
409 BinaryOperator::Le => "<=",
410 BinaryOperator::Gt => ">",
411 BinaryOperator::Ge => ">=",
412 };
413 write!(f, "{}", s)
414 }
415}
416
417impl From<&Operator> for BinaryOperator {
418 fn from(value: &Operator) -> Self {
419 match value {
420 Operator::IAdd | Operator::FAdd => Self::Add,
421 Operator::ISub | Operator::FSub => Self::Sub,
422 Operator::IMul | Operator::FMul => Self::Mul,
423 Operator::IDiv | Operator::FDiv => Self::Div,
424 Operator::IMod => Self::Mod,
425 Operator::IPow => Self::Pow,
426 Operator::IEq | Operator::FEq | Operator::UnaryEq | Operator::GroundEq => Self::Eq,
427 Operator::INe | Operator::FNe | Operator::UnaryNe | Operator::GroundNe => Self::Ne,
428 Operator::ILt | Operator::FLt => Self::Lt,
429 Operator::ILe | Operator::FLe => Self::Le,
430 Operator::IGt | Operator::FGt => Self::Gt,
431 Operator::IGe | Operator::FGe => Self::Ge,
432 Operator::Equal => todo!(),
433 Operator::HyperlinkFuse => todo!(),
434 Operator::HyperlinkUnify => todo!(),
435 Operator::Negative => todo!(),
436 Operator::Question => todo!(),
437 Operator::DoubleColon => todo!(),
438 Operator::LogicalAnd => todo!(),
439 Operator::LogicalOr => todo!(),
440 Operator::LogicalNot => todo!(),
441 Operator::LogicalXor => todo!(),
442 Operator::LogicalShift => todo!(),
443 Operator::ArithmeticShift => todo!(),
444 }
445 }
446}
447
448#[derive(Debug, Clone, Copy)]
449pub enum UnaryOperator {
450 Not,
451 Neg,
452}
453
454impl Display for UnaryOperator {
455 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
456 let s = match self {
457 UnaryOperator::Not => "!",
458 UnaryOperator::Neg => "-",
459 };
460 write!(f, "{}", s)
461 }
462}