| 689 | } else { |
| 690 | write!(f, "_")?; |
| 691 | } |
| 692 | write!(f, " : ")?; |
| 693 | fmt_expr(ty, f, depth + 1)?; |
| 694 | write!(f, ") -> ")?; |
| 695 | fmt_expr(body, f, depth + 1)?; |
| 696 | write!(f, ")") |
| 697 | }, |
| 698 | ExprData::Let(name, ty, val, body, _, _) => { |
| 699 | write!(f, "(let ")?; |
| 700 | if name.has_meta() { |
| 701 | name.meta_fmt(f)?; |
| 702 | } else { |
| 703 | write!(f, "_")?; |
| 704 | } |
| 705 | write!(f, " : ")?; |
| 706 | fmt_expr(ty, f, depth + 1)?; |
| 707 | write!(f, " := ")?; |
| 708 | fmt_expr(val, f, depth + 1)?; |
| 709 | write!(f, " in ")?; |
| 710 | fmt_expr(body, f, depth + 1)?; |
| 711 | write!(f, ")") |
| 712 | }, |
| 713 | ExprData::Prj(id, field, val, _) => { |
| 714 | fmt_expr(val, f, depth + 1)?; |
| 715 | write!(f, ".{field}@{id}") |
| 716 | }, |
| 717 | ExprData::Nat(val, _, _) => write!(f, "{val}"), |
| 718 | ExprData::Str(val, _, _) => write!(f, "{val:?}"), |
| 719 | } |
| 720 | } |
| 721 | |
| 722 | fn collect_spine<M: KernelMode>(e: &KExpr<M>) -> (KExpr<M>, Vec<KExpr<M>>) { |
| 723 | let mut args = Vec::new(); |
| 724 | let mut cur = e.clone(); |
| 725 | while let ExprData::App(func, arg, _) = cur.data() { |
| 726 | args.push(arg.clone()); |
| 727 | cur = func.clone(); |
| 728 | } |
| 729 | args.reverse(); |
| 730 | (cur, args) |
| 731 | } |
| 732 | |
| 733 | #[cfg(test)] |
| 734 | mod tests { |
| 735 | use super::super::mode::{Anon, Meta}; |
| 736 | use super::*; |
| 737 | use ix_common::address::Address; |
| 738 | use ix_common::env::BinderInfo; |
| 739 | |
| 740 | type ME = KExpr<Meta>; |
| 741 | type AE = KExpr<Anon>; |
| 742 | type MU = KUniv<Meta>; |
| 743 | type AU = KUniv<Anon>; |
| 744 | |
| 745 | fn mk_name(s: &str) -> Name { |
| 746 | let mut name = Name::anon(); |
| 747 | for part in s.split('.') { |
| 748 | name = Name::str(name, part.to_string()); |