use std::borrow::Cow; use std::rc::Rc; use dhall_syntax::context::Context; use dhall_syntax::{Label, V}; use crate::core::thunk::Thunk; use crate::core::value::{AlphaVar, Value}; use crate::phase::{Normalized, Type, Typed}; #[derive(Debug, Clone)] enum NzEnvItem { Thunk(Thunk), Skip(AlphaVar), } #[derive(Debug, Clone)] pub(crate) struct NormalizationContext(Rc>); #[derive(Debug, Clone)] pub(crate) enum TyEnvItem { Type(AlphaVar, Type), Value(Normalized), } #[derive(Debug, Clone)] pub(crate) struct TypecheckContext(pub(crate) Context); impl NzEnvItem { pub(crate) fn shift(&self, delta: isize, var: &AlphaVar) -> Self { use NzEnvItem::*; match self { Thunk(e) => Thunk(e.shift(delta, var)), Skip(v) => Skip(v.shift(delta, var)), } } pub(crate) fn subst_shift(&self, var: &AlphaVar, val: &Typed) -> Self { match self { NzEnvItem::Thunk(e) => NzEnvItem::Thunk(e.subst_shift(var, val)), NzEnvItem::Skip(v) if v == var => NzEnvItem::Thunk(val.to_thunk()), NzEnvItem::Skip(v) => NzEnvItem::Skip(v.shift(-1, var)), } } } impl NormalizationContext { pub(crate) fn new() -> Self { NormalizationContext(Rc::new(Context::new())) } pub(crate) fn skip(&self, x: &Label) -> Self { NormalizationContext(Rc::new( self.0 .map(|_, e| e.shift(1, &x.into())) .insert(x.clone(), NzEnvItem::Skip(x.into())), )) } pub(crate) fn lookup(&self, var: &V