summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Brown <gmb60@cam.ac.uk>2021-01-09 11:53:21 +0000
committerGreg Brown <gmb60@cam.ac.uk>2021-01-09 11:53:21 +0000
commit487ce4fe0fa081f58d790d7d6417bf7d2659197c (patch)
tree435dbca41a6a8c67eac0fd875599103c611349bb
parentae1511dc11236601da174a146b1713b9d68ddc30 (diff)
Make all ast spans optional.
-rw-r--r--src/chomp/ast.rs12
-rw-r--r--src/chomp/check/inline.rs157
-rw-r--r--src/chomp/check/spanning.rs2
-rw-r--r--src/chomp/typed.rs2
-rw-r--r--src/nibble/convert.rs4
-rw-r--r--src/nibble/cst.rs2
6 files changed, 154 insertions, 25 deletions
diff --git a/src/chomp/ast.rs b/src/chomp/ast.rs
index 58d76c9..76d75ae 100644
--- a/src/chomp/ast.rs
+++ b/src/chomp/ast.rs
@@ -262,7 +262,7 @@ pub struct Parameter {
}
impl Parameter {
- pub fn new(name: Name, index: usize) -> Self {
+ pub const fn new(name: Name, index: usize) -> Self {
Self { name, index }
}
@@ -288,17 +288,17 @@ impl Display for Parameter {
/// A macro invocation.
#[derive(Clone, Debug)]
pub struct Call {
- pub name: Ident,
+ pub name: Name,
pub args: Vec<Expression>,
pub span: Option<Span>,
}
impl Call {
- pub fn new(name: Ident, args: Vec<Expression>, span: Option<Span>) -> Self {
+ pub fn new(name: Name, args: Vec<Expression>, span: Option<Span>) -> Self {
Self { name, args, span }
}
- pub fn name(&self) -> &Ident {
+ pub fn name(&self) -> &Name {
&self.name
}
@@ -487,14 +487,14 @@ impl From<Call> for Expression {
#[derive(Clone, Debug)]
pub struct Function {
- pub name: Ident,
+ pub name: Name,
pub params: usize,
pub expr: Expression,
pub span: Option<Span>,
}
impl Function {
- pub const fn new(name: Ident, params: usize, expr: Expression, span: Option<Span>) -> Self {
+ pub const fn new(name: Name, params: usize, expr: Expression, span: Option<Span>) -> Self {
Self {
name,
params,
diff --git a/src/chomp/check/inline.rs b/src/chomp/check/inline.rs
index a6a831c..43a2eb8 100644
--- a/src/chomp/check/inline.rs
+++ b/src/chomp/check/inline.rs
@@ -79,27 +79,156 @@ impl Folder for InlineCalls {
#[cfg(test)]
mod tests {
- use proc_macro2::Span;
- use syn::Ident;
+ use crate::chomp::Name;
use super::*;
- const OPT_NAME: &str = "opt";
- const OPT: Function = Function::new(
- Ident::new(OPT_NAME, Span::call_site()),
- 1,
- Expression::Alt(Alt::new(
- Epsilon::default().into(),
+ fn opt() -> Function {
+ Function::new(
+ Name::Spanless("opt".to_string()),
+ 1,
+ Expression::Alt(Alt::new(
+ Expression::Epsilon(None),
+ None,
+ Parameter::new(Name::Spanless("x".to_string()), 0).into(),
+ )),
None,
- Parameter::new(None, 0).into(),
- )),
- None,
- );
+ )
+ }
#[test]
fn test_inline_absent() {
let expr = Epsilon::default();
- let inlined = expr.fold(&mut InlineCalls::new(OPT));
- assert_eq!(inlined, Ok(Expression::from(Epsilon::default())))
+ let inlined = expr.fold(&mut InlineCalls::new(opt()));
+ assert_eq!(inlined, Ok(Epsilon::default().into()))
+ }
+
+ #[test]
+ fn test_inline_in_fix() {
+ let expr = Fix::new(
+ Name::Spanless("rec".to_string()),
+ Call::new(
+ Name::Spanless("opt".to_string()),
+ vec![Variable::new(Name::Spanless("rec".to_string()), 0).into()],
+ None,
+ )
+ .into(),
+ None,
+ );
+ let inlined = expr.fold(&mut InlineCalls::new(opt()));
+ assert_eq!(
+ inlined,
+ Ok(Fix::new(
+ Name::Spanless("rec".to_string()),
+ Alt::new(
+ Epsilon::default().into(),
+ None,
+ Variable::new(Name::Spanless("rec".to_string()), 0).into()
+ )
+ .into(),
+ None
+ )
+ .into())
+ )
+ }
+
+ #[test]
+ fn test_inline_deepens_vars() {
+ let function = Function::new(
+ Name::Spanless("plus".into()),
+ 1,
+ Fix::new(
+ Name::Spanless("rec".to_string()),
+ Cat::new(
+ Parameter::new(Name::Spanless("x".to_string()), 0).into(),
+ None,
+ Variable::new(Name::Spanless("rec".to_string()), 0).into(),
+ )
+ .into(),
+ None,
+ )
+ .into(),
+ None,
+ );
+ let expr = Fix::new(
+ Name::Spanless("var".to_string()),
+ Call::new(
+ Name::Spanless("plus".into()),
+ vec![Variable::new(Name::Spanless("var".to_string()), 0).into()],
+ None,
+ )
+ .into(),
+ None
+ );
+ let inlined = expr.fold(&mut InlineCalls::new(function));
+ assert_eq!(
+ inlined,
+ Ok(Fix::new(
+ Name::Spanless("var".to_string()),
+ Fix::new(
+ Name::Spanless("rec".to_string()),
+ Cat::new(
+ Variable::new(Name::Spanless("var".to_string()), 1).into(),
+ None,
+ Variable::new(Name::Spanless("rec".to_string()), 0).into(),
+ )
+ .into(),
+ None,
+ )
+ .into(),
+ None
+ )
+ .into())
+ )
+ }
+
+ #[test]
+ fn test_inline_resets_vars() {
+ let function = Function::new(
+ Name::Spanless("plus".into()),
+ 1,
+ Cat::new(
+ Fix::new(
+ Name::Spanless("rec".to_string()),
+ Epsilon::default().into(),
+ None,
+ )
+ .into(),
+ None,
+ Parameter::new(Name::Spanless("x".to_string()), 0).into(),
+ )
+ .into(),
+ None,
+ );
+ let expr = Fix::new(
+ Name::Spanless("var".to_string()),
+ Call::new(
+ Name::Spanless("plus".into()),
+ vec![Variable::new(Name::Spanless("var".to_string()), 0).into()],
+ None,
+ )
+ .into(),
+ None
+ );
+ let inlined = expr.fold(&mut InlineCalls::new(function));
+ assert_eq!(
+ inlined,
+ Ok(Fix::new(
+ Name::Spanless("var".to_string()),
+ Cat::new(
+ Fix::new(
+ Name::Spanless("rec".to_string()),
+ Epsilon::default().into(),
+ None,
+ )
+ .into(),
+ None,
+ Variable::new(Name::Spanless("var".to_string()), 0).into(),
+ )
+ .into(),
+ None
+ )
+ .into())
+ )
}
}
diff --git a/src/chomp/check/spanning.rs b/src/chomp/check/spanning.rs
index 91e593b..59c3811 100644
--- a/src/chomp/check/spanning.rs
+++ b/src/chomp/check/spanning.rs
@@ -1,4 +1,4 @@
-use proc_macro2::{Ident, Span};
+use proc_macro2::Span;
use super::super::{
ast::{Alt, Call, Cat, Epsilon, Fix, Literal, Parameter, Variable},
diff --git a/src/chomp/typed.rs b/src/chomp/typed.rs
index ab6cbc8..db07552 100644
--- a/src/chomp/typed.rs
+++ b/src/chomp/typed.rs
@@ -1,7 +1,7 @@
use std::hash::{Hash, Hasher};
use proc_macro2::Span;
-use syn::{Ident, Token};
+use syn::Token;
use super::{
ast,
diff --git a/src/nibble/convert.rs b/src/nibble/convert.rs
index 1a175a0..422d100 100644
--- a/src/nibble/convert.rs
+++ b/src/nibble/convert.rs
@@ -73,7 +73,7 @@ impl Convert for Ident {
match context.lookup(&self)? {
Binding::Variable(index) => Some(ast::Variable::new(self.into(), index).into()),
Binding::Parameter(index) => Some(ast::Parameter::new(self.into(), index).into()),
- Binding::Global => Some(ast::Call::new(self, Vec::new(), Some(span)).into()),
+ Binding::Global => Some(ast::Call::new(self.into(), Vec::new(), Some(span)).into()),
}
}
}
@@ -86,7 +86,7 @@ impl Convert for Call {
.into_iter()
.map(|arg| arg.convert(context))
.collect::<Option<_>>()?;
- Some(ast::Call::new(self.name, args, span).into())
+ Some(ast::Call::new(self.name.into(), args, span).into())
}
}
diff --git a/src/nibble/cst.rs b/src/nibble/cst.rs
index 383eae9..2b52678 100644
--- a/src/nibble/cst.rs
+++ b/src/nibble/cst.rs
@@ -260,7 +260,7 @@ impl File {
);
names.push(stmt.name.clone());
map.push(ast::Function::new(
- stmt.name.clone(),
+ stmt.name.into(),
count,
stmt.expr.convert(&mut context)?,
span,