From 0141e8e8c7f3e295d57990fdce6019e2d777aed0 Mon Sep 17 00:00:00 2001 From: Greg Brown Date: Wed, 18 Nov 2020 13:31:27 +0000 Subject: Convert concrete to abstract syntax tree --- src/ast/convert.rs | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 src/ast/convert.rs (limited to 'src/ast/convert.rs') diff --git a/src/ast/convert.rs b/src/ast/convert.rs new file mode 100644 index 0000000..c27c75f --- /dev/null +++ b/src/ast/convert.rs @@ -0,0 +1,76 @@ +use super::Term; + +#[derive(Clone, Debug, Default)] +pub struct Context { + vars: Vec, +} + +impl Context { + /// # Examples + /// ``` + /// use chomp::ast::convert::Context; + /// + /// let context = Context::new(); + /// assert_eq!(context.get("x"), None); + /// assert_eq!(context.get("y"), None); + /// assert_eq!(context.get("z"), None); + /// ``` + pub fn new() -> Self { + Self::default() + } + + /// # Examples + /// ``` + /// use chomp::ast::convert::Context; + /// + /// let context = Context::new(); + /// assert_eq!(context.get("x"), None); + /// + /// context.push("x".to_owned(), |c| { + /// assert_eq!(c.get("x"), Some(0)); + /// + /// c.push("y".to_owned(), |c| { + /// assert_eq!(c.get("x"), Some(1)); + /// }) + /// }); + /// + /// assert_eq!(context.get("x"), None); + /// ``` + pub fn get>(&self, name: &T) -> Option { + let mut iter = self.vars.iter(); + let mut pos = 0; + + while let Some(var) = iter.next_back() { + if T::eq(&name, &var) { + return Some(pos); + } else { + pos += 1; + } + } + + None + } + + /// # Examples + /// ``` + /// use chomp::ast::convert::Context; + /// + /// let context = Context::new(); + /// assert_eq!(context.get("x"), None); + /// + /// context.push("x".to_owned(), |c| { + /// assert_eq!(c.get("x"), Some(0)); + /// }); + /// + /// assert_eq!(context.get("x"), None); + /// ``` + pub fn push T, T>(&self, var: String, f: F) -> T { + let mut context = self.clone(); + context.vars.push(var); + f(&context) + } +} + +pub trait Convert { + fn convert(self, context: &Context) -> Term; +} -- cgit v1.2.3