use std::cell::RefCell; use std::collections::HashMap; use std::rc::Rc; use crate::error::TypeError; use crate::semantics::core::value::Value; use crate::semantics::core::value::ValueKind; use crate::semantics::core::var::{AlphaVar, Binder, Shift, Subst}; use crate::syntax::{Label, V}; #[derive(Debug, Clone)] enum CtxItem { Kept(AlphaVar, Value), Replaced(Value), } #[derive(Debug, Clone)] pub(crate) struct TyCtx { ctx: Vec<(Binder, CtxItem)>, /// Keeps track of the next free binder id to assign. Shared among all the contexts to ensure /// unicity across the expression. next_uid: Rc>, } impl TyCtx { pub fn new() -> Self { TyCtx { ctx: Vec::new(), next_uid: Rc::new(RefCell::new(0)), } } fn with_vec(&self, vec: Vec<(Binder, CtxItem)>) -> Self { TyCtx { ctx: vec, next_uid: self.next_uid.clone(), } } pub fn insert_type(&self, x: &Binder, t: Value) -> Self { let mut vec = self.ctx.clone(); vec.push((x.clone(), CtxItem::Kept(x.into(), t.under_binder(x)))); self.with_vec(vec) } pub fn insert_value( &self, x: &Binder, e: Value, ) -> Result { let mut vec = self.ctx.clone(); vec.push((x.clone(), CtxItem::Replaced(e))); Ok(self.with_vec(vec)) } pub fn lookup(&self, var: &V