diff options
Diffstat (limited to '')
-rw-r--r-- | dhall/src/syntax/ast/expr.rs (renamed from dhall/src/syntax/core/expr.rs) | 203 |
1 files changed, 102 insertions, 101 deletions
diff --git a/dhall/src/syntax/core/expr.rs b/dhall/src/syntax/ast/expr.rs index 5b9f401..48c48d8 100644 --- a/dhall/src/syntax/core/expr.rs +++ b/dhall/src/syntax/ast/expr.rs @@ -1,51 +1,15 @@ use crate::syntax::map::{DupTreeMap, DupTreeSet}; -use crate::syntax::visitor::{self, ExprFMutVisitor, ExprFVisitor}; +use crate::syntax::visitor::{self, ExprKindMutVisitor, ExprKindVisitor}; use crate::syntax::*; pub type Integer = isize; pub type Natural = usize; pub type Double = NaiveDouble; -pub fn trivial_result<T>(x: Result<T, !>) -> T { - match x { - Ok(x) => x, - Err(e) => e, - } -} - /// Double with bitwise equality #[derive(Debug, Copy, Clone)] pub struct NaiveDouble(f64); -impl PartialEq for NaiveDouble { - fn eq(&self, other: &Self) -> bool { - self.0.to_bits() == other.0.to_bits() - } -} - -impl Eq for NaiveDouble {} - -impl std::hash::Hash for NaiveDouble { - fn hash<H>(&self, state: &mut H) - where - H: std::hash::Hasher, - { - self.0.to_bits().hash(state) - } -} - -impl From<f64> for NaiveDouble { - fn from(x: f64) -> Self { - NaiveDouble(x) - } -} - -impl From<NaiveDouble> for f64 { - fn from(x: NaiveDouble) -> f64 { - x.0 - } -} - /// Constants for a pure type system #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum Const { @@ -62,18 +26,6 @@ pub enum Const { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct V<Label>(pub Label, pub usize); -// This is only for the specific `Label` type, not generic -impl From<Label> for V<Label> { - fn from(x: Label) -> V<Label> { - V(x, 0) - } -} -impl<'a> From<&'a Label> for V<Label> { - fn from(x: &'a Label) -> V<Label> { - V(x.clone(), 0) - } -} - // Definition order must match precedence order for // pretty-printing to work correctly #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -142,33 +94,19 @@ pub enum Builtin { // Each node carries an annotation. #[derive(Debug, Clone)] -pub struct Expr<Embed>(Box<(RawExpr<Embed>, Span)>); - -pub type RawExpr<Embed> = ExprF<Expr<Embed>, Embed>; - -impl<Embed: PartialEq> std::cmp::PartialEq for Expr<Embed> { - fn eq(&self, other: &Self) -> bool { - self.0.as_ref().0 == other.0.as_ref().0 - } +pub struct Expr<Embed> { + kind: Box<ExprKind<Expr<Embed>, Embed>>, + span: Span, } -impl<Embed: Eq> std::cmp::Eq for Expr<Embed> {} - -impl<Embed: std::hash::Hash> std::hash::Hash for Expr<Embed> { - fn hash<H>(&self, state: &mut H) - where - H: std::hash::Hasher, - { - (self.0).0.hash(state) - } -} +pub type UnspannedExpr<Embed> = ExprKind<Expr<Embed>, Embed>; /// Syntax tree for expressions // Having the recursion out of the enum definition enables writing // much more generic code and improves pattern-matching behind // smart pointers. #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum ExprF<SubExpr, Embed> { +pub enum ExprKind<SubExpr, Embed> { Const(Const), /// `x` /// `x@n` @@ -231,12 +169,12 @@ pub enum ExprF<SubExpr, Embed> { Embed(Embed), } -impl<SE, E> ExprF<SE, E> { +impl<SE, E> ExprKind<SE, E> { pub fn traverse_ref_with_special_handling_of_binders<'a, SE2, Err>( &'a self, visit_subexpr: impl FnMut(&'a SE) -> Result<SE2, Err>, visit_under_binder: impl FnOnce(&'a Label, &'a SE) -> Result<SE2, Err>, - ) -> Result<ExprF<SE2, E>, Err> + ) -> Result<ExprKind<SE2, E>, Err> where E: Clone, { @@ -250,7 +188,7 @@ impl<SE, E> ExprF<SE, E> { fn traverse_ref<'a, SE2, Err>( &'a self, visit_subexpr: impl FnMut(&'a SE) -> Result<SE2, Err>, - ) -> Result<ExprF<SE2, E>, Err> + ) -> Result<ExprKind<SE2, E>, Err> where E: Clone, { @@ -268,7 +206,7 @@ impl<SE, E> ExprF<SE, E> { &'a self, mut map_subexpr: impl FnMut(&'a SE) -> SE2, mut map_under_binder: impl FnMut(&'a Label, &'a SE) -> SE2, - ) -> ExprF<SE2, E> + ) -> ExprKind<SE2, E> where E: Clone, { @@ -281,7 +219,7 @@ impl<SE, E> ExprF<SE, E> { pub fn map_ref<'a, SE2>( &'a self, mut map_subexpr: impl FnMut(&'a SE) -> SE2, - ) -> ExprF<SE2, E> + ) -> ExprKind<SE2, E> where E: Clone, { @@ -294,22 +232,25 @@ impl<SE, E> ExprF<SE, E> { } impl<E> Expr<E> { - pub fn as_ref(&self) -> &RawExpr<E> { - &self.0.as_ref().0 - } - pub fn as_mut(&mut self) -> &mut RawExpr<E> { - &mut self.0.as_mut().0 + pub fn as_ref(&self) -> &UnspannedExpr<E> { + &self.kind } pub fn span(&self) -> Span { - self.0.as_ref().1.clone() + self.span.clone() } - pub fn new(x: RawExpr<E>, n: Span) -> Self { - Expr(Box::new((x, n))) + pub fn new(kind: UnspannedExpr<E>, span: Span) -> Self { + Expr { + kind: Box::new(kind), + span, + } } - pub fn rewrap<E2>(&self, x: RawExpr<E2>) -> Expr<E2> { - Expr(Box::new((x, (self.0).1.clone()))) + pub fn rewrap<E2>(&self, kind: UnspannedExpr<E2>) -> Expr<E2> { + Expr { + kind: Box::new(kind), + span: self.span.clone(), + } } pub fn traverse_resolve_mut<Err, F1>( @@ -320,21 +261,21 @@ impl<E> Expr<E> { E: Clone, F1: FnMut(Import<Expr<E>>) -> Result<E, Err>, { - match self.as_mut() { - ExprF::BinOp(BinOp::ImportAlt, l, r) => { - let garbage_expr = ExprF::BoolLit(false); + match self.kind.as_mut() { + ExprKind::BinOp(BinOp::ImportAlt, l, r) => { + let garbage_expr = ExprKind::BoolLit(false); let new_self = if l.traverse_resolve_mut(f).is_ok() { l } else { r.traverse_resolve_mut(f)?; r }; - *self.as_mut() = - std::mem::replace(new_self.as_mut(), garbage_expr); + *self.kind = + std::mem::replace(new_self.kind.as_mut(), garbage_expr); } _ => { - self.as_mut().traverse_mut(|e| e.traverse_resolve_mut(f))?; - if let ExprF::Import(import) = self.as_mut() { + self.kind.traverse_mut(|e| e.traverse_resolve_mut(f))?; + if let ExprKind::Import(import) = self.kind.as_mut() { let garbage_import = Import { mode: ImportMode::Code, location: ImportLocation::Missing, @@ -342,7 +283,7 @@ impl<E> Expr<E> { }; // Move out of &mut import let import = std::mem::replace(import, garbage_import); - *self.as_mut() = ExprF::Embed(f(import)?); + *self.kind = ExprKind::Embed(f(import)?); } } } @@ -350,16 +291,6 @@ impl<E> Expr<E> { } } -/// Add an isize to an usize -/// Returns `None` on over/underflow -fn add_ui(u: usize, i: isize) -> Option<usize> { - Some(if i < 0 { - u.checked_sub(i.checked_neg()? as usize)? - } else { - u.checked_add(i as usize)? - }) -} - impl<Label: PartialEq + Clone> V<Label> { pub fn shift(&self, delta: isize, var: &V<Label>) -> Option<Self> { let V(x, n) = var; @@ -375,3 +306,73 @@ impl<Label: PartialEq + Clone> V<Label> { self.shift(-1, &V(x.clone(), 0)) } } + +pub fn trivial_result<T>(x: Result<T, !>) -> T { + match x { + Ok(x) => x, + Err(e) => e, + } +} + +/// Add an isize to an usize +/// Returns `None` on over/underflow +fn add_ui(u: usize, i: isize) -> Option<usize> { + Some(if i < 0 { + u.checked_sub(i.checked_neg()? as usize)? + } else { + u.checked_add(i as usize)? + }) +} + +impl PartialEq for NaiveDouble { + fn eq(&self, other: &Self) -> bool { + self.0.to_bits() == other.0.to_bits() + } +} + +impl Eq for NaiveDouble {} + +impl std::hash::Hash for NaiveDouble { + fn hash<H>(&self, state: &mut H) + where + H: std::hash::Hasher, + { + self.0.to_bits().hash(state) + } +} + +impl From<f64> for NaiveDouble { + fn from(x: f64) -> Self { + NaiveDouble(x) + } +} + +impl From<NaiveDouble> for f64 { + fn from(x: NaiveDouble) -> f64 { + x.0 + } +} + +/// This is only for the specific `Label` type, not generic +impl From<Label> for V<Label> { + fn from(x: Label) -> V<Label> { + V(x, 0) + } +} + +impl<Embed: PartialEq> std::cmp::PartialEq for Expr<Embed> { + fn eq(&self, other: &Self) -> bool { + self.kind == other.kind + } +} + +impl<Embed: Eq> std::cmp::Eq for Expr<Embed> {} + +impl<Embed: std::hash::Hash> std::hash::Hash for Expr<Embed> { + fn hash<H>(&self, state: &mut H) + where + H: std::hash::Hasher, + { + self.kind.hash(state) + } +} |