From 408bba76bd95a2aabd49046443950a37771f6008 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sat, 4 May 2019 16:13:18 +0200 Subject: Thread Spans through the AST --- dhall/src/typecheck.rs | 2 +- dhall_proc_macros/src/quote.rs | 2 +- dhall_syntax/src/core.rs | 93 +++++++++++++---------- dhall_syntax/src/parser.rs | 162 ++++++++++++++++++++--------------------- dhall_syntax/src/visitor.rs | 11 +-- 5 files changed, 141 insertions(+), 129 deletions(-) diff --git a/dhall/src/typecheck.rs b/dhall/src/typecheck.rs index ce4ca96..732f7bc 100644 --- a/dhall/src/typecheck.rs +++ b/dhall/src/typecheck.rs @@ -350,7 +350,7 @@ fn type_of_const(c: Const) -> Result { } } -fn type_of_builtin(b: Builtin) -> Expr { +fn type_of_builtin(b: Builtin) -> Expr { use dhall_syntax::Builtin::*; match b { Bool | Natural | Integer | Double | Text => dhall::expr!(Type), diff --git a/dhall_proc_macros/src/quote.rs b/dhall_proc_macros/src/quote.rs index e11bbaa..eaf4946 100644 --- a/dhall_proc_macros/src/quote.rs +++ b/dhall_proc_macros/src/quote.rs @@ -11,7 +11,7 @@ pub fn expr(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let no_import = |_: &Import| -> X { panic!("Don't use import in dhall::expr!()") }; let expr = expr.map_embed(no_import); - let output = quote_expr(&expr.unroll(), &Context::new()); + let output = quote_expr(expr.as_ref(), &Context::new()); output.into() } diff --git a/dhall_syntax/src/core.rs b/dhall_syntax/src/core.rs index a81f96c..a186d19 100644 --- a/dhall_syntax/src/core.rs +++ b/dhall_syntax/src/core.rs @@ -141,12 +141,13 @@ pub type ParsedExpr = SubExpr; pub type ResolvedExpr = SubExpr; pub type DhallExpr = ResolvedExpr; +// Each node carries an annotation. In practice it's either X (no annotation) or a Span. #[derive(Debug)] -pub struct SubExpr(Rc>, Option); +pub struct SubExpr(Rc<(Expr, Option)>); impl std::cmp::PartialEq for SubExpr { fn eq(&self, other: &Self) -> bool { - self.0 == other.0 + self.0.as_ref().0 == other.0.as_ref().0 } } @@ -345,14 +346,6 @@ impl Expr { trivial_result(self.traverse_embed(|x| Ok(map_embed(x)))) } - pub fn roll(&self) -> SubExpr - where - N: Clone, - E: Clone, - { - rc(ExprF::clone(self)) - } - pub fn squash_embed( &self, f: impl FnMut(&E) -> SubExpr, @@ -378,7 +371,33 @@ impl Expr { impl SubExpr { pub fn as_ref(&self) -> &Expr { - self.0.as_ref() + &self.0.as_ref().0 + } + + pub fn new(x: Expr, n: N) -> Self { + SubExpr(Rc::new((x, Some(n)))) + } + + pub fn from_expr_no_note(x: Expr) -> Self { + SubExpr(Rc::new((x, None))) + } + + pub fn unnote(&self) -> SubExpr + where + E: Clone, + { + SubExpr::from_expr_no_note( + self.as_ref().visit(&mut visitor::UnNoteVisitor), + ) + } +} + +impl SubExpr { + pub fn rewrap(&self, x: Expr) -> SubExpr + where + N: Clone, + { + SubExpr(Rc::new((x, (self.0).1.clone()))) } pub fn traverse_embed( @@ -388,7 +407,7 @@ impl SubExpr { where N: Clone, { - Ok(rc(self.as_ref().traverse_embed(visit_embed)?)) + Ok(self.rewrap(self.as_ref().traverse_embed(visit_embed)?)) } pub fn map_embed( @@ -398,7 +417,7 @@ impl SubExpr { where N: Clone, { - rc(self.as_ref().map_embed(map_embed)) + self.rewrap(self.as_ref().map_embed(map_embed)) } pub fn map_subexprs_with_special_handling_of_binders<'a>( @@ -409,7 +428,7 @@ impl SubExpr { match self.as_ref() { ExprF::Embed(_) => SubExpr::clone(self), // This calls ExprF::map_ref - e => rc(e.map_ref_with_special_handling_of_binders( + e => self.rewrap(e.map_ref_with_special_handling_of_binders( map_expr, map_under_binder, |_| unreachable!(), @@ -418,28 +437,13 @@ impl SubExpr { } } - pub fn unroll(&self) -> Expr - where - N: Clone, - E: Clone, - { - ExprF::clone(self.as_ref()) - } - - pub fn unnote(&self) -> SubExpr - where - E: Clone, - { - rc(self.as_ref().visit(&mut visitor::UnNoteVisitor)) - } - /// `shift` is used by both normalization and type-checking to avoid variable /// capture by shifting variable indices /// See https://github.com/dhall-lang/dhall-lang/blob/master/standard/semantics.md#shift /// for details pub fn shift(&self, delta: isize, var: &V