summaryrefslogtreecommitdiff
path: root/src/chomp/ast.rs
diff options
context:
space:
mode:
authorGreg Brown <gmb60@cam.ac.uk>2021-01-14 11:42:55 +0000
committerGreg Brown <gmb60@cam.ac.uk>2021-01-14 11:42:55 +0000
commitaac3549a72663c523a456b2f5d7c3b77f509cdd6 (patch)
tree562824f3cfa5feca791715c733f7749197bb7e7a /src/chomp/ast.rs
parent0d01692c97ea8ca6fc4b229e5b9678cb252bceda (diff)
Add labelled expressions.
Restructure project (again). Convert `Cat` and `Alt` from binary to n+2-ary.
Diffstat (limited to 'src/chomp/ast.rs')
-rw-r--r--src/chomp/ast.rs505
1 files changed, 0 insertions, 505 deletions
diff --git a/src/chomp/ast.rs b/src/chomp/ast.rs
deleted file mode 100644
index 76d75ae..0000000
--- a/src/chomp/ast.rs
+++ /dev/null
@@ -1,505 +0,0 @@
-use std::{
- fmt::{self, Display},
- hash,
-};
-
-use proc_macro2::Span;
-use syn::{Ident, LitStr, Token};
-
-use super::Name;
-
-pub type Epsilon = Option<Token![_]>;
-
-#[derive(Clone, Debug)]
-pub enum Literal {
- Spanned(LitStr),
- Spanless(String),
-}
-
-impl Literal {
- pub fn value(&self) -> String {
- match self {
- Self::Spanned(l) => l.value(),
- Self::Spanless(s) => s.clone(),
- }
- }
-
- pub fn span(&self) -> Option<Span> {
- match self {
- Self::Spanned(l) => Some(l.span()),
- Self::Spanless(_) => None,
- }
- }
-
- pub fn as_litstr(self, span: Span) -> LitStr {
- match self {
- Self::Spanned(l) => l,
- Self::Spanless(s) => LitStr::new(&s, span),
- }
- }
-}
-
-impl PartialEq for Literal {
- fn eq(&self, other: &Self) -> bool {
- match (self, other) {
- (Self::Spanned(me), Self::Spanned(them)) => me == them,
- (Self::Spanned(me), Self::Spanless(them)) => &me.value() == them,
- (Self::Spanless(me), Self::Spanned(them)) => me == &them.value(),
- (Self::Spanless(me), Self::Spanless(them)) => me == them,
- }
- }
-}
-
-impl Eq for Literal {}
-
-impl hash::Hash for Literal {
- fn hash<H: hash::Hasher>(&self, state: &mut H) {
- self.value().hash(state)
- }
-}
-
-impl Display for Literal {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "{:?}", self.value())
- }
-}
-
-impl From<LitStr> for Literal {
- fn from(l: LitStr) -> Self {
- Self::Spanned(l)
- }
-}
-
-impl From<String> for Literal {
- fn from(s: String) -> Self {
- Self::Spanless(s)
- }
-}
-
-#[derive(Clone, Debug)]
-pub struct Cat {
- pub fst: Box<Expression>,
- pub punct: Option<Token![.]>,
- pub snd: Box<Expression>,
-}
-
-impl Cat {
- pub fn new(fst: Expression, punct: Option<Token![.]>, snd: Expression) -> Self {
- Self {
- fst: Box::new(fst),
- punct,
- snd: Box::new(snd),
- }
- }
-
- pub fn first(&self) -> &Expression {
- &self.fst
- }
-
- pub fn first_mut(&mut self) -> &mut Expression {
- &mut self.fst
- }
-
- pub fn punct(&self) -> Option<Token![.]> {
- self.punct
- }
-
- pub fn second(&self) -> &Expression {
- &self.snd
- }
-
- pub fn second_mut(&mut self) -> &mut Expression {
- &mut self.snd
- }
-}
-
-impl Display for Cat {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "({}.{})", self.fst, self.snd)
- }
-}
-
-impl PartialEq for Cat {
- fn eq(&self, other: &Self) -> bool {
- self.first() == other.first() && self.second() == other.second()
- }
-}
-
-impl Eq for Cat {}
-
-#[derive(Clone, Debug)]
-pub struct Alt {
- pub left: Box<Expression>,
- pub punct: Option<Token![|]>,
- pub right: Box<Expression>,
-}
-
-impl Alt {
- pub fn new(left: Expression, punct: Option<Token![|]>, right: Expression) -> Self {
- Self {
- left: Box::new(left),
- punct,
- right: Box::new(right),
- }
- }
-
- pub fn left(&self) -> &Expression {
- &self.left
- }
-
- pub fn left_mut(&mut self) -> &mut Expression {
- &mut self.left
- }
-
- pub fn punct(&self) -> Option<Token![|]> {
- self.punct
- }
-
- pub fn right(&self) -> &Expression {
- &self.right
- }
-
- pub fn right_mut(&mut self) -> &mut Expression {
- &mut self.right
- }
-}
-
-impl Display for Alt {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "({}|{})", self.left, self.right)
- }
-}
-
-impl PartialEq for Alt {
- fn eq(&self, other: &Self) -> bool {
- self.left() == other.left() && self.right() == other.right()
- }
-}
-
-impl Eq for Alt {}
-
-#[derive(Clone, Debug)]
-pub struct Fix {
- pub arg: Name,
- pub inner: Box<Expression>,
- pub span: Option<Span>,
-}
-
-impl Fix {
- pub fn new(arg: Name, inner: Expression, span: Option<Span>) -> Self {
- Self {
- arg,
- inner: Box::new(inner),
- span,
- }
- }
-
- pub fn arg(&self) -> &Name {
- &self.arg
- }
-
- pub fn inner(&self) -> &Expression {
- &self.inner
- }
-
- pub fn inner_mut(&mut self) -> &mut Expression {
- &mut self.inner
- }
-
- pub fn span(&self) -> Option<Span> {
- self.span
- }
-}
-
-impl Display for Fix {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "[{}]({})", self.arg, self.inner)
- }
-}
-
-impl PartialEq for Fix {
- fn eq(&self, other: &Self) -> bool {
- self.inner() == other.inner()
- }
-}
-
-impl Eq for Fix {}
-
-#[derive(Clone, Debug, Eq, Hash, PartialEq)]
-pub struct Variable {
- pub name: Name,
- pub index: usize,
-}
-
-impl Variable {
- pub fn new(name: Name, index: usize) -> Self {
- Self { name, index }
- }
-
- pub fn name(&self) -> &Name {
- &self.name
- }
-
- pub fn index(&self) -> usize {
- self.index
- }
-
- pub fn index_mut(&mut self) -> &mut usize {
- &mut self.index
- }
-}
-
-impl Display for Variable {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- self.name.fmt(f)
- }
-}
-
-#[derive(Clone, Debug, Eq, Hash, PartialEq)]
-pub struct Parameter {
- pub name: Name,
- pub index: usize,
-}
-
-impl Parameter {
- pub const fn new(name: Name, index: usize) -> Self {
- Self { name, index }
- }
-
- pub fn name(&self) -> &Name {
- &self.name
- }
-
- pub fn index(&self) -> usize {
- self.index
- }
-
- pub fn index_mut(&mut self) -> &mut usize {
- &mut self.index
- }
-}
-
-impl Display for Parameter {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "{}", self.name)
- }
-}
-
-/// A macro invocation.
-#[derive(Clone, Debug)]
-pub struct Call {
- pub name: Name,
- pub args: Vec<Expression>,
- pub span: Option<Span>,
-}
-
-impl Call {
- pub fn new(name: Name, args: Vec<Expression>, span: Option<Span>) -> Self {
- Self { name, args, span }
- }
-
- pub fn name(&self) -> &Name {
- &self.name
- }
-
- pub fn args(&self) -> &[Expression] {
- &self.args
- }
-
- pub fn args_mut(&mut self) -> &mut [Expression] {
- &mut self.args
- }
-
- pub fn span(&self) -> Option<Span> {
- self.span
- }
-}
-
-impl Display for Call {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "{}", self.name)?;
-
- let mut iter = self.args.iter();
-
- if let Some(arg) = iter.next() {
- write!(f, "({}", arg)?;
-
- for arg in iter {
- write!(f, ", {}", arg)?;
- }
-
- write!(f, ")")
- } else {
- Ok(())
- }
- }
-}
-
-impl PartialEq for Call {
- fn eq(&self, other: &Self) -> bool {
- self.name() == other.name() && self.args() == other.args()
- }
-}
-
-impl Eq for Call {}
-
-#[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 formal parameter.
- Parameter(Parameter),
- /// A macro invocation.
- Call(Call),
-}
-
-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::Parameter(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::Parameter(p) => {
- if let Self::Parameter(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<Parameter> for Expression {
- fn from(param: Parameter) -> Self {
- Self::Parameter(param)
- }
-}
-
-impl From<Call> for Expression {
- fn from(call: Call) -> Self {
- Self::Call(call)
- }
-}
-
-#[derive(Clone, Debug)]
-pub struct Function {
- pub name: Name,
- pub params: usize,
- pub expr: Expression,
- pub span: Option<Span>,
-}
-
-impl Function {
- pub const fn new(name: Name, params: usize, expr: Expression, span: Option<Span>) -> Self {
- Self {
- name,
- params,
- expr,
- span,
- }
- }
-}