printer.rs 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. use crate::types::MalVal;
  2. use crate::types::MalVal::{Atom, Bool, Func, Hash, Int, List, MalFunc, Nil, Str, Sym, Vector, Zk};
  3. fn escape_str(s: &str) -> String {
  4. s.chars()
  5. .map(|c| match c {
  6. '"' => "\\\"".to_string(),
  7. '\n' => "\\n".to_string(),
  8. '\\' => "\\\\".to_string(),
  9. _ => c.to_string(),
  10. })
  11. .collect::<Vec<String>>()
  12. .join("")
  13. }
  14. impl MalVal {
  15. pub fn pr_str(&self, print_readably: bool) -> String {
  16. match self {
  17. Nil => String::from("nil"),
  18. Bool(true) => String::from("true"),
  19. Bool(false) => String::from("false"),
  20. Int(i) => format!("{}", i),
  21. //Float(f) => format!("{}", f),
  22. Str(s) => {
  23. if s.starts_with("\u{29e}") {
  24. format!(":{}", &s[2..])
  25. } else if print_readably {
  26. format!("\"{}\"", escape_str(s))
  27. } else {
  28. s.clone()
  29. }
  30. }
  31. Sym(s) => s.clone(),
  32. List(l, _) => pr_seq(&**l, print_readably, "(", ")", " "),
  33. Vector(l, _) => pr_seq(&**l, print_readably, "[", "]", " "),
  34. Hash(hm, _) => {
  35. let l: Vec<MalVal> = hm
  36. .iter()
  37. .flat_map(|(k, v)| vec![Str(k.to_string()), v.clone()])
  38. .collect();
  39. pr_seq(&l, print_readably, "{", "}", " ")
  40. }
  41. Func(f, _) => format!("#<fn {:?}>", f),
  42. MalFunc {
  43. ast: a, params: p, ..
  44. } => format!("(fn* {} {})", p.pr_str(true), a.pr_str(true)),
  45. Atom(a) => format!("(atom {})", a.borrow().pr_str(true)),
  46. Zk(a) => format!("{:?}", a),
  47. Add => format!("add"),
  48. Lc0 => format!("Lc0"),
  49. i => format!("{:?}", i.pr_str(true)),
  50. }
  51. }
  52. }
  53. pub fn pr_seq(
  54. seq: &Vec<MalVal>,
  55. print_readably: bool,
  56. start: &str,
  57. end: &str,
  58. join: &str,
  59. ) -> String {
  60. let strs: Vec<String> = seq.iter().map(|x| x.pr_str(print_readably)).collect();
  61. format!("{}{}{}", start, strs.join(join), end)
  62. }