diff options
author | Greg Brown <gmb60@cam.ac.uk> | 2021-01-09 11:53:21 +0000 |
---|---|---|
committer | Greg Brown <gmb60@cam.ac.uk> | 2021-01-09 11:53:21 +0000 |
commit | 487ce4fe0fa081f58d790d7d6417bf7d2659197c (patch) | |
tree | 435dbca41a6a8c67eac0fd875599103c611349bb | |
parent | ae1511dc11236601da174a146b1713b9d68ddc30 (diff) |
Make all ast spans optional.
-rw-r--r-- | src/chomp/ast.rs | 12 | ||||
-rw-r--r-- | src/chomp/check/inline.rs | 157 | ||||
-rw-r--r-- | src/chomp/check/spanning.rs | 2 | ||||
-rw-r--r-- | src/chomp/typed.rs | 2 | ||||
-rw-r--r-- | src/nibble/convert.rs | 4 | ||||
-rw-r--r-- | src/nibble/cst.rs | 2 |
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, |