mimium_lang/mir/
print.rs

1use crate::format_vec;
2
3use super::*;
4
5impl std::fmt::Display for Mir {
6    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7        for fun in self.functions.iter() {
8            let af = fun
9                .args
10                .iter()
11                .zip(fun.get_argtypes())
12                .map(|(a, t)| format!("{}:{}", *a, t.to_type()))
13                .collect::<Vec<_>>()
14                .join(",");
15            let _ = writeln!(f, "fn {} [{af}]", fun.label);
16            let upi = format_vec!(fun.upindexes, ",");
17            let _ = write!(f, "upindexes:[{upi}]");
18            if let Some(upper_i) = fun.upperfn_i {
19                let _ = write!(f, "upper:{upper_i}");
20            }
21            let _ = write!(f, " states: {:?}", fun.state_skeleton);
22            for (i, block) in fun.body.iter().enumerate() {
23                let _ = write!(f, "\n  block {i}\n");
24                for (v, insts) in block.0.iter() {
25                    let _ = match v.as_ref() {
26                        Value::None => writeln!(f, "  {: <10} {insts}", " "),
27                        _ => writeln!(f, "  {:<7} := {insts}", format!("{}", *v)),
28                    };
29                }
30            }
31        }
32        Ok(())
33    }
34}
35
36impl std::fmt::Display for Argument {
37    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
38        let Argument(label, t) = self;
39        write!(f, "arg {}: {}", label.0, t.to_type())
40    }
41}
42
43impl std::fmt::Display for Value {
44    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
45        match self {
46            Value::Global(gv) => write!(f, "global({})", *gv),
47            Value::Argument(i) => write!(f, "arg({})", i),
48            Value::Register(r) => write!(f, "reg({r})"),
49            Value::Function(id) => write!(f, "function {id}"),
50            Value::ExtFunction(label, t) => {
51                write!(f, "extfun {label} {}", t.to_type())
52            }
53            Value::State(v) => write!(f, "state({})", *v),
54            Value::None => write!(f, "none"),
55        }
56    }
57}
58
59impl std::fmt::Display for Instruction {
60    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61        match self {
62            Instruction::Uinteger(u) => write!(f, "uint {u}"),
63            Instruction::Integer(i) => write!(f, "int {i}"),
64            Instruction::Float(n) => write!(f, "float {n}"),
65            Instruction::String(s) => write!(f, "string {}", s.as_str()),
66            Instruction::Alloc(t) => write!(f, "alloc {}", t.to_type()),
67            Instruction::Load(src, ty) => write!(f, "load {src}, {}", ty.to_type()),
68            Instruction::Store(dst, src, ty) => write!(f, "store {dst}, {src}, {}", ty.to_type()),
69            Instruction::GetElement {
70                value,
71                ty,
72                tuple_offset,
73            } => {
74                let ty = ty.to_type();
75                write!(f, "getelement {value}, {ty}, {tuple_offset}")
76            }
77            Instruction::Call(fptr, args, rty) => {
78                write!(
79                    f,
80                    "call {} [{}] ->{}",
81                    *fptr,
82                    args.iter()
83                        .map(|(a, _t)| a.to_string())
84                        .collect::<Vec<_>>()
85                        .join(","),
86                    rty.to_type()
87                )
88            }
89            Instruction::CallCls(cls, args, rty) => {
90                write!(
91                    f,
92                    "callcls {} [{}] ->{}",
93                    *cls,
94                    args.iter()
95                        .map(|(a, _t)| a.to_string())
96                        .collect::<Vec<_>>()
97                        .join(","),
98                    rty.to_type()
99                )
100            }
101            Instruction::Closure(fun) => {
102                if let Value::Function(idx) = fun.as_ref() {
103                    // TODO: convert idx to function in order to show more information
104                    write!(f, "closure {idx}")
105                } else {
106                    write!(f, "closure {}", *fun)
107                }
108            }
109            Instruction::CloseUpValues(cls, ty) => {
110                write!(f, "close {} {}", *cls, ty.to_type())
111            }
112            Instruction::GetUpValue(idx, ty) => write!(f, "getupval {idx} {}", ty.to_type()),
113            Instruction::SetUpValue(dst, src, ty) => {
114                write!(f, "setupval {dst} {} {}", src, ty.to_type())
115            }
116            Instruction::GetGlobal(v, ty) => write!(f, "getglobal {} {}", *v, ty.to_type()),
117            Instruction::SetGlobal(dst, src, ty) => {
118                write!(f, "setglobal {} {} {}", *dst, *src, ty.to_type())
119            }
120            Instruction::PushStateOffset(v) => {
121                write!(f, "pushstateidx {v}")
122            }
123            Instruction::PopStateOffset(v) => {
124                write!(f, "popstateidx  {v}")
125            }
126            Instruction::GetState(ty) => write!(f, "getstate {}", ty.to_type()),
127            Instruction::JmpIf(cond, tbb, ebb, pbb) => write!(f, "jmpif {cond} {tbb} {ebb} {pbb}"),
128            Instruction::Jmp(bb) => write!(f, "jmp {bb}"),
129            Instruction::Phi(t, e) => write!(f, "phi {t} {e}"),
130            Instruction::Return(a, rty) => write!(f, "ret {} {}", *a, rty.to_type()),
131            Instruction::ReturnFeed(v, rty) => write!(f, "retfeed {} {}", *v, rty.to_type()),
132            Instruction::Delay(max, a, b) => write!(f, "delay {max} {} {}", *a, *b),
133            Instruction::Mem(a) => write!(f, "mem {}", *a),
134            Instruction::AddF(a, b) => write!(f, "addf {} {}", *a, *b),
135            Instruction::SubF(a, b) => write!(f, "subf {} {}", *a, *b),
136            Instruction::MulF(a, b) => write!(f, "mulf {} {}", *a, *b),
137            Instruction::DivF(a, b) => write!(f, "divf {} {}", *a, *b),
138            Instruction::ModF(a, b) => write!(f, "modf {} {}", *a, *b),
139            Instruction::NegF(a) => write!(f, "negf {}", *a),
140            Instruction::AbsF(a) => write!(f, "absf {}", *a),
141            Instruction::SinF(a) => write!(f, "sinf {}", *a),
142            Instruction::CosF(a) => write!(f, "sinf {}", *a),
143            Instruction::SqrtF(a) => write!(f, "sqrtf {}", *a),
144            Instruction::PowF(a, b) => write!(f, "powf {} {}", *a, *b),
145            Instruction::LogF(a) => write!(f, "logf {}", *a),
146            Instruction::AddI(a, b) => write!(f, "addi {} {}", *a, *b),
147            Instruction::SubI(a, b) => write!(f, "subi {} {}", *a, *b),
148            Instruction::MulI(a, b) => write!(f, "muli {} {}", *a, *b),
149            Instruction::DivI(a, b) => write!(f, "divi {} {}", *a, *b),
150            Instruction::ModI(a, b) => write!(f, "modi {} {}", *a, *b),
151            Instruction::NegI(a) => write!(f, "negi {}", *a),
152            Instruction::AbsI(a) => write!(f, "absi {}", *a),
153            Instruction::PowI(a) => write!(f, "powi {}", *a),
154            Instruction::LogI(_, _) => todo!(),
155            Instruction::Not(_) => todo!(),
156            Instruction::Eq(a, b) => write!(f, "eq {} {}", *a, *b),
157            Instruction::Ne(a, b) => write!(f, "ne {} {}", *a, *b),
158            Instruction::Gt(a, b) => write!(f, "gt {} {}", *a, *b),
159            Instruction::Ge(a, b) => write!(f, "ge {} {}", *a, *b),
160            Instruction::Lt(a, b) => write!(f, "lt {} {}", *a, *b),
161            Instruction::Le(a, b) => write!(f, "le {} {}", *a, *b),
162            Instruction::And(a, b) => write!(f, "and {} {}", *a, *b),
163            Instruction::Or(a, b) => write!(f, "or {} {}", *a, *b),
164            Instruction::CastFtoI(_) => todo!(),
165            Instruction::CastItoF(_) => todo!(),
166            Instruction::CastItoB(_) => todo!(),
167            Instruction::Error => write!(f, "error"),
168            Instruction::Array(values, ty) => {
169                write!(f, "array[")?;
170                for (i, value) in values.iter().enumerate() {
171                    if i > 0 {
172                        write!(f, ", ")?;
173                    }
174                    write!(f, "{value}")?;
175                }
176                write!(f, "]({})", ty.to_type())
177            }
178            Instruction::GetArrayElem(value, value1, type_node_id) => {
179                let type_str = type_node_id.to_type();
180                write!(f, "getarrayelem {value} {value1} {type_str}")
181            }
182            Instruction::SetArrayElem(value, value1, value2, type_node_id) => {
183                let type_str = type_node_id.to_type();
184                write!(f, "setarrayelem {value} {value1} {value2} {type_str}")
185            }
186        }
187    }
188}