use super::ir::*;
use super::program::Program;
use std::fmt;
impl ToString for Program {
fn to_string(&self) -> String {
return prog_to_string(
&self.functions,
&self.consts,
&self.expr,
&self.name_to_var,
&self.name_to_func,
);
}
}
impl fmt::Display for Index {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Index::Arg(idx) => write!(f, "arg<{}>", idx),
Index::Loc(idx) => write!(f, "loc({})", idx),
Index::Cmd(idx) => write!(f, "cmd({})", idx),
Index::Expr(idx) => write!(f, "expr<{}>", idx),
Index::Udf(idx) => write!(f, "udf<{}>", idx),
Index::Const(idx) => write!(f, "const<{}>", idx),
}
}
}
impl fmt::Display for IR {
fn fmt(&self, f: &mut fmt::Formatter) -> std::fmt::Result {
match self {
IR::LocalAssignement(var, val) => write!(f, "loc({}) = {}", var, val),
IR::GlobalAssignement(var, val) => write!(f, "glob({}) = {}", var, *val),
IR::CmdCall(idx, args) => _display_callable(f, "cmd_const", *idx, args),
IR::UdfCall(idx, args) => _display_callable(f, "udf", *idx, args),
IR::BuiltinCall(idx, args) => _display_callable(f, "built_in", *idx, args),
}
}
}
fn _display_callable(f: &mut fmt::Formatter, kind: &str, idx: u16, args: &[Index]) -> fmt::Result {
let mut res = String::new();
for arg in args.iter() {
let val = format!("{},", arg);
res.push_str(&val);
}
res.pop();
write!(f, "{}<{}>({})", kind, idx, res)
}
impl fmt::Display for Expr {
fn fmt(&self, f: &mut fmt::Formatter) -> std::fmt::Result {
let var = &self.data;
let len = var.len();
let mut res: Vec<u8> = Vec::with_capacity(2 * len);
let mut idx = 0;
while idx < len {
let ch = var[idx];
res.push(ch);
idx += 1;
if ch == GLOB_VAR_INDIC {
let _msb = var[idx] as u16;
let lsb = var[idx + 1];
res.push(lsb + '0' as u8);
idx += 2;
} else if ch == LOCL_VAR_INDIC {
res.push(var[idx] + '0' as u8);
idx += 1;
}
}
let res = std::str::from_utf8(&res).unwrap().to_owned();
write!(f, "{}", res)
}
}
impl fmt::Display for UDF {
fn fmt(&self, f: &mut fmt::Formatter) -> std::fmt::Result {
write!(
f,
"fn({},{},{:?}):\n",
self.nbr_args,
self.instructions.len(),
self.default_args
)?;
for instruct in self.instructions.iter() {
writeln!(f, " {}", instruct)?;
}
Ok(())
}
}
pub fn prog_to_string(
functions: &Vec<UDF>,
consts: &Vec<String>,
expr: &Vec<Expr>,
name_to_var: &NameToIndex,
name_to_func: &NameToIndex,
) -> String {
let mut res = String::with_capacity(1000);
res.push_str("\n---- const : idx->value ----\n");
for idx in 0..consts.len() {
let val = &consts[idx as usize];
let val = format!("{}->{}\n", idx, val);
res.push_str(&val);
}
res.push_str("\n---- expressions: idx->value ----\n");
for idx in 0..expr.len() {
let val = &expr[idx as usize];
let val = format!("{}->{}\n", idx, val);
res.push_str(&val);
}
res.push_str("\n---- name to var: name->idx ----\n");
let mut tmp_bfr = Vec::new();
for (key, val) in name_to_var {
tmp_bfr.push((val, key));
}
tmp_bfr.sort_by_key(|k| k.0);
for i in 0..tmp_bfr.len() {
let idx = tmp_bfr[i].0;
let val = format!("{}->{}\n", tmp_bfr[i].1, idx);
res.push_str(&val);
}
res.push_str("\n---- funcs: idx->name->fn(nbr_args, nbr_instructions, defaults): body ----\n");
let mut tmp_bfr = Vec::new();
for (key, val) in name_to_func {
tmp_bfr.push((val, key));
}
tmp_bfr.sort_by_key(|k| k.0);
for i in 0..tmp_bfr.len() {
let idx = tmp_bfr[i].0;
let func = &functions[*idx as usize];
let val = format!("{}->{}->{}\n", idx, tmp_bfr[i].1, func);
res.push_str(&val);
}
return res;
}