From dc10a278cca74d737e4af0fe034a1caa8abb291d Mon Sep 17 00:00:00 2001 From: Greg Brown Date: Wed, 6 Jan 2021 14:56:11 +0000 Subject: Restructure code base to separate compilation phases. --- src/chomp/context.rs | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/chomp/context.rs (limited to 'src/chomp/context.rs') diff --git a/src/chomp/context.rs b/src/chomp/context.rs new file mode 100644 index 0000000..392023f --- /dev/null +++ b/src/chomp/context.rs @@ -0,0 +1,51 @@ +use super::{ast::Variable, error::VariableError, typed::Type}; + +#[derive(Debug, Default)] +pub struct Context { + vars: Vec, + unguard_points: Vec, +} + +impl Context { + pub fn new() -> Self { + Self::default() + } + + pub fn depth(&self) -> usize { + self.vars.len() + } + + pub fn is_unguarded(&self, var: &Variable) -> Option { + if self.vars.len() <= var.index() { + None + } else if self.unguard_points.is_empty() { + Some(false) + } else { + Some( + self.unguard_points[self.unguard_points.len() - 1] + var.index() >= self.vars.len(), + ) + } + } + + pub fn with_unguard R, R>(&mut self, f: F) -> R { + self.unguard_points.push(self.vars.len()); + let res = f(self); + self.unguard_points.pop(); + res + } + + pub fn get_variable_type(&self, var: &Variable) -> Result<&Type, VariableError> { + match self.is_unguarded(var) { + None => Err(VariableError::FreeVariable(var.clone())), + Some(false) => Err(VariableError::GuardedVariable(var.clone())), + Some(true) => Ok(&self.vars[self.vars.len() - var.index() - 1]), + } + } + + pub fn with_variable_type R, R>(&mut self, ty: Type, f: F) -> R { + self.vars.push(ty); + let res = f(self); + self.vars.pop(); + res + } +} -- cgit v1.2.3