diff options
Diffstat (limited to 'dhall/src/lib.rs')
-rw-r--r-- | dhall/src/lib.rs | 114 |
1 files changed, 52 insertions, 62 deletions
diff --git a/dhall/src/lib.rs b/dhall/src/lib.rs index 6747eff..ad16a24 100644 --- a/dhall/src/lib.rs +++ b/dhall/src/lib.rs @@ -5,17 +5,18 @@ clippy::needless_lifetimes, clippy::new_ret_no_self, clippy::new_without_default, + clippy::try_err, clippy::useless_format )] pub mod builtins; +pub mod ctxt; pub mod error; pub mod operations; pub mod semantics; pub mod syntax; pub mod utils; -use std::fmt::Display; use std::path::Path; use url::Url; @@ -26,6 +27,8 @@ use crate::semantics::resolve::ImportLocation; use crate::semantics::{typecheck, typecheck_with, Hir, Nir, Tir, Type}; use crate::syntax::Expr; +pub use ctxt::*; + #[derive(Debug, Clone)] pub struct Parsed(Expr, ImportLocation); @@ -33,20 +36,20 @@ pub struct Parsed(Expr, ImportLocation); /// /// Invariant: there must be no `Import` nodes or `ImportAlt` operations left. #[derive(Debug, Clone)] -pub struct Resolved(Hir); +pub struct Resolved<'cx>(Hir<'cx>); /// A typed expression #[derive(Debug, Clone)] -pub struct Typed { - pub hir: Hir, - pub ty: Type, +pub struct Typed<'cx> { + pub hir: Hir<'cx>, + pub ty: Type<'cx>, } /// A normalized expression. /// /// This is actually a lie, because the expression will only get normalized on demand. #[derive(Debug, Clone)] -pub struct Normalized(Nir); +pub struct Normalized<'cx>(Nir<'cx>); /// Controls conversion from `Nir` to `Expr` #[derive(Copy, Clone, Default)] @@ -56,6 +59,11 @@ pub struct ToExprOptions { } impl Parsed { + /// Construct from an `Expr`. This `Expr` will have imports disabled. + pub fn from_expr_without_imports(e: Expr) -> Self { + Parsed(e, ImportLocation::dhall_code_without_imports()) + } + pub fn parse_file(f: &Path) -> Result<Parsed, Error> { parse::parse_file(f) } @@ -73,11 +81,14 @@ impl Parsed { parse::parse_binary(data) } - pub fn resolve(self) -> Result<Resolved, Error> { - resolve::resolve(self) + pub fn resolve<'cx>(self, cx: Ctxt<'cx>) -> Result<Resolved<'cx>, Error> { + resolve::resolve(cx, self) } - pub fn skip_resolve(self) -> Result<Resolved, Error> { - resolve::skip_resolve(self) + pub fn skip_resolve<'cx>( + self, + cx: Ctxt<'cx>, + ) -> Result<Resolved<'cx>, Error> { + resolve::skip_resolve(cx, self) } /// Converts a value back to the corresponding AST expression. @@ -86,59 +97,66 @@ impl Parsed { } } -impl Resolved { - pub fn typecheck(&self) -> Result<Typed, TypeError> { - Ok(Typed::from_tir(typecheck(&self.0)?)) +impl<'cx> Resolved<'cx> { + pub fn typecheck(&self, cx: Ctxt<'cx>) -> Result<Typed<'cx>, TypeError> { + Ok(Typed::from_tir(typecheck(cx, &self.0)?)) } - pub fn typecheck_with(self, ty: &Hir) -> Result<Typed, TypeError> { - Ok(Typed::from_tir(typecheck_with(&self.0, ty)?)) + pub fn typecheck_with( + self, + cx: Ctxt<'cx>, + ty: &Hir<'cx>, + ) -> Result<Typed<'cx>, TypeError> { + Ok(Typed::from_tir(typecheck_with(cx, &self.0, ty)?)) } /// Converts a value back to the corresponding AST expression. - pub fn to_expr(&self) -> Expr { - self.0.to_expr_noopts() + pub fn to_expr(&self, cx: Ctxt<'cx>) -> Expr { + self.0.to_expr_noopts(cx) } } -impl Typed { - fn from_tir(tir: Tir<'_>) -> Self { +impl<'cx> Typed<'cx> { + fn from_tir(tir: Tir<'cx, '_>) -> Self { Typed { hir: tir.as_hir().clone(), ty: tir.ty().clone(), } } /// Reduce an expression to its normal form, performing beta reduction - pub fn normalize(&self) -> Normalized { - Normalized(self.hir.eval_closed_expr()) + pub fn normalize(&self, cx: Ctxt<'cx>) -> Normalized<'cx> { + Normalized(self.hir.eval_closed_expr(cx)) } /// Converts a value back to the corresponding AST expression. - fn to_expr(&self) -> Expr { - self.hir.to_expr(ToExprOptions { alpha: false }) + fn to_expr(&self, cx: Ctxt<'cx>) -> Expr { + self.hir.to_expr(cx, ToExprOptions { alpha: false }) } - pub fn ty(&self) -> &Type { + pub fn as_hir(&self) -> &Hir<'cx> { + &self.hir + } + pub fn ty(&self) -> &Type<'cx> { &self.ty } - pub fn get_type(&self) -> Result<Normalized, TypeError> { + pub fn get_type(&self) -> Result<Normalized<'cx>, TypeError> { Ok(Normalized(self.ty.clone().into_nir())) } } -impl Normalized { +impl<'cx> Normalized<'cx> { /// Converts a value back to the corresponding AST expression. - pub fn to_expr(&self) -> Expr { - self.0.to_expr(ToExprOptions::default()) + pub fn to_expr(&self, cx: Ctxt<'cx>) -> Expr { + self.0.to_expr(cx, ToExprOptions::default()) } /// Converts a value back to the corresponding Hir expression. - pub fn to_hir(&self) -> Hir { + pub fn to_hir(&self) -> Hir<'cx> { self.0.to_hir_noenv() } - pub fn as_nir(&self) -> &Nir { + pub fn as_nir(&self) -> &Nir<'cx> { &self.0 } /// Converts a value back to the corresponding AST expression, alpha-normalizing in the process. - pub fn to_expr_alpha(&self) -> Expr { - self.0.to_expr(ToExprOptions { alpha: true }) + pub fn to_expr_alpha(&self, cx: Ctxt<'cx>) -> Expr { + self.0.to_expr(cx, ToExprOptions { alpha: true }) } } @@ -170,38 +188,10 @@ impl From<Parsed> for Expr { other.to_expr() } } -impl From<Normalized> for Expr { - fn from(other: Normalized) -> Self { - other.to_expr() - } -} - -impl Display for Resolved { - fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { - self.to_expr().fmt(f) - } -} - -impl Eq for Typed {} -impl PartialEq for Typed { - fn eq(&self, other: &Self) -> bool { - self.normalize() == other.normalize() - } -} -impl Display for Typed { - fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { - self.to_expr().fmt(f) - } -} -impl Eq for Normalized {} -impl PartialEq for Normalized { +impl<'cx> Eq for Normalized<'cx> {} +impl<'cx> PartialEq for Normalized<'cx> { fn eq(&self, other: &Self) -> bool { self.0 == other.0 } } -impl Display for Normalized { - fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { - self.to_expr().fmt(f) - } -} |