summaryrefslogtreecommitdiff
path: root/dhall/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'dhall/src/lib.rs')
-rw-r--r--dhall/src/lib.rs114
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)
- }
-}