diff options
author | Greg Brown <gmb60@cam.ac.uk> | 2021-04-27 13:07:27 +0100 |
---|---|---|
committer | Greg Brown <gmb60@cam.ac.uk> | 2021-04-27 13:07:27 +0100 |
commit | 51dcf19eb6f8d2127f3dedfc1d7d5326d7a8017b (patch) | |
tree | 9d66a63fa1d017cad1b4483399950bf216d58bf8 /src/chomp/ast-old/mod.rs | |
parent | 61eb62dde6a62cf19d33d5c689b0c3a4f36d93c3 (diff) |
Start rewrite using query system.queries
Diffstat (limited to 'src/chomp/ast-old/mod.rs')
-rw-r--r-- | src/chomp/ast-old/mod.rs | 325 |
1 files changed, 325 insertions, 0 deletions
diff --git a/src/chomp/ast-old/mod.rs b/src/chomp/ast-old/mod.rs new file mode 100644 index 0000000..232381a --- /dev/null +++ b/src/chomp/ast-old/mod.rs @@ -0,0 +1,325 @@ +use std::fmt::{self, Display}; + +use proc_macro2::Span; + +use super::Name; + +pub mod error; +pub mod substitute; + +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Hash)] +pub struct Epsilon; + +pub type Literal = String; + +#[derive(Clone, Debug)] +pub struct Cat { + pub first: Box<NamedExpression>, + pub rest: Vec<(Option<Span>, NamedExpression)>, +} + +impl Display for Cat { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "({}", self.first)?; + for (_, other) in &self.rest { + write!(f, " . {}", other)?; + } + write!(f, ")") + } +} + +impl PartialEq for Cat { + fn eq(&self, other: &Self) -> bool { + self.first == other.first + && self.rest.len() == other.rest.len() + && self + .rest + .iter() + .zip(other.rest.iter()) + .all(|((_, me), (_, them))| me == them) + } +} + +impl Eq for Cat {} + +#[derive(Clone, Debug)] +pub struct Alt { + pub first: Box<NamedExpression>, + pub rest: Vec<(Option<Span>, NamedExpression)> +} + +impl Display for Alt { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "({}", self.first)?; + for (_, other) in &self.rest { + write!(f, " | {}", other)?; + } + write!(f, ")") + } +} + +impl PartialEq for Alt { + fn eq(&self, other: &Self) -> bool { + self.first == other.first + && self.rest.len() == other.rest.len() + && self + .rest + .iter() + .zip(other.rest.iter()) + .all(|((_, me), (_, them))| me == them) + } +} + +impl Eq for Alt {} + +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct Fix { + pub inner: Box<NamedExpression>, +} + +impl Display for Fix { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "!{}", self.inner) + } +} + +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub struct Variable { + pub index: usize, +} + +impl Display for Variable { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "'{}", self.index) + } +} + +/// A function invocation. +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct Call { + pub on: Box<NamedExpression>, + pub args: Vec<NamedExpression>, +} + +impl Display for Call { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "({}", self.on)?; + + for arg in self.args { + write!(f, " {}", arg)?; + } + + write!(f, ")") + } +} + +/// A function abstraction. +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct Lambda { + pub args: Vec<Name>, + pub inner: Box<NamedExpression>, +} + +impl Display for Lambda { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "/")?; + let mut iter = self.args.iter(); + if let Some(arg) = iter.next() { + write!(f, "{}", arg)?; + + for arg in iter { + write!(f, ", {}", arg)?; + } + } + write!(f, "/ {}", self.inner) + } +} + +#[derive(Clone, Debug)] +pub enum Expression { + /// Matches the empty string. + Epsilon(Epsilon), + /// Matches the literal string. + Literal(Literal), + /// Matches one term followed by another. + Cat(Cat), + /// Matches either one term or another. + Alt(Alt), + /// The least fix point of a term. + Fix(Fix), + /// A fixed point variable. + Variable(Variable), + /// A function invocation. + Call(Call), + /// A function abstraction. + Lambda(Lambda), +} + +impl Expression { + pub fn try_into_lambda(self) -> Result<Lambda, Self> { + if let Self::Lambda(l) = self { + Ok(l) + } else { + Err(self) + } + } +} + +impl Display for Expression { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Epsilon(_) => write!(f, "_"), + Self::Literal(l) => l.fmt(f), + Self::Cat(c) => c.fmt(f), + Self::Alt(a) => a.fmt(f), + Self::Fix(x) => x.fmt(f), + Self::Variable(v) => v.fmt(f), + Self::Lambda(p) => p.fmt(f), + Self::Call(c) => c.fmt(f), + } + } +} + +impl PartialEq for Expression { + fn eq(&self, other: &Self) -> bool { + match self { + Self::Epsilon(_) => matches!(other, Self::Epsilon(_)), + Self::Literal(l) => { + if let Self::Literal(them) = other { + l == them + } else { + false + } + } + Self::Cat(c) => { + if let Self::Cat(them) = other { + c == them + } else { + false + } + } + Self::Alt(a) => { + if let Self::Alt(them) = other { + a == them + } else { + false + } + } + Self::Fix(f) => { + if let Self::Fix(them) = other { + f == them + } else { + false + } + } + Self::Variable(v) => { + if let Self::Variable(them) = other { + v == them + } else { + false + } + } + Self::Lambda(p) => { + if let Self::Lambda(them) = other { + p == them + } else { + false + } + } + Self::Call(c) => { + if let Self::Call(them) = other { + c == them + } else { + false + } + } + } + } +} + +impl Eq for Expression {} + +impl From<Epsilon> for Expression { + fn from(eps: Epsilon) -> Self { + Self::Epsilon(eps) + } +} + +impl From<Literal> for Expression { + fn from(lit: Literal) -> Self { + Self::Literal(lit) + } +} + +impl From<Cat> for Expression { + fn from(cat: Cat) -> Self { + Self::Cat(cat) + } +} + +impl From<Alt> for Expression { + fn from(alt: Alt) -> Self { + Self::Alt(alt) + } +} + +impl From<Fix> for Expression { + fn from(fix: Fix) -> Self { + Self::Fix(fix) + } +} + +impl From<Variable> for Expression { + fn from(var: Variable) -> Self { + Self::Variable(var) + } +} + +impl From<Lambda> for Expression { + fn from(lambda: Lambda) -> Self { + Self::Lambda(lambda) + } +} + +impl From<Call> for Expression { + fn from(call: Call) -> Self { + Self::Call(call) + } +} + +#[derive(Clone, Debug)] +pub struct NamedExpression { + pub name: Option<Name>, + pub expr: Expression, + pub span: Option<Span>, +} + +impl Display for NamedExpression { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match &self.name { + Some(name) => write!(f, "({} : {})", self.expr, name), + None => self.expr.fmt(f), + } + } +} + +impl PartialEq for NamedExpression { + fn eq(&self, other: &Self) -> bool { + self.expr == other.expr + } +} + +impl Eq for NamedExpression {} + +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct Let { + pub name: Name, + pub val: NamedExpression, + pub inner: Box<TopLevel>, +} + +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum TopLevel { + Let(Let), + Goal(NamedExpression), +} |