diff options
Diffstat (limited to 'src/ast')
-rw-r--r-- | src/ast/convert.rs | 76 | ||||
-rw-r--r-- | src/ast/mod.rs | 15 |
2 files changed, 91 insertions, 0 deletions
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<String>, +} + +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<T: ?Sized + PartialEq<str>>(&self, name: &T) -> Option<usize> { + 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<F: FnOnce(&Self) -> 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; +} diff --git a/src/ast/mod.rs b/src/ast/mod.rs new file mode 100644 index 0000000..1fa7d23 --- /dev/null +++ b/src/ast/mod.rs @@ -0,0 +1,15 @@ +pub mod convert; + +type Ident = String; + +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum Term { + Epsilon, + Bottom, + Literal(String), + Cat(Box<Term>, Box<Term>), + Alt(Box<Term>, Box<Term>), + Fix(Box<Term>), // Uses de Bruijn indices + Variable(usize), + Call(Ident, Vec<Term>), +} |