summaryrefslogtreecommitdiff
path: root/dhall
diff options
context:
space:
mode:
authorNadrieril2019-04-07 16:45:30 +0200
committerNadrieril2019-04-07 16:47:55 +0200
commit4bebcd96b6e76b9b8ae7877af91d2ae571e617a9 (patch)
tree09012b2d9294a58455b74e8bd0e041f7cb153a23 /dhall
parentf680a3221c7475fae413a260d739cf8e0025081d (diff)
Restrict public API
Closes #20
Diffstat (limited to 'dhall')
-rw-r--r--dhall/src/expr.rs48
-rw-r--r--dhall/src/imports.rs15
-rw-r--r--dhall/src/lib.rs12
-rw-r--r--dhall/src/main.rs20
-rw-r--r--dhall/src/normalize.rs8
-rw-r--r--dhall/src/typecheck.rs9
-rw-r--r--dhall/tests/common/mod.rs63
7 files changed, 104 insertions, 71 deletions
diff --git a/dhall/src/expr.rs b/dhall/src/expr.rs
index 555db2f..7baf628 100644
--- a/dhall/src/expr.rs
+++ b/dhall/src/expr.rs
@@ -1,34 +1,46 @@
use crate::imports::ImportRoot;
use dhall_core::*;
+macro_rules! derive_other_traits {
+ ($ty:ident) => {
+ impl std::cmp::PartialEq for $ty {
+ fn eq(&self, other: &Self) -> bool {
+ self.0 == other.0
+ }
+ }
+
+ impl std::fmt::Display for $ty {
+ fn fmt(
+ &self,
+ f: &mut std::fmt::Formatter,
+ ) -> Result<(), std::fmt::Error> {
+ self.0.fmt(f)
+ }
+ }
+ };
+}
+
#[derive(Debug, Clone, Eq)]
pub struct Parsed(pub(crate) SubExpr<X, Import>, pub(crate) ImportRoot);
+derive_other_traits!(Parsed);
-#[derive(Debug, Clone, PartialEq, Eq)]
+#[derive(Debug, Clone, Eq)]
pub struct Resolved(pub(crate) SubExpr<X, X>);
+derive_other_traits!(Resolved);
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, Eq)]
pub struct Typed(pub(crate) SubExpr<X, X>, pub(crate) Type);
+derive_other_traits!(Typed);
+
+#[derive(Debug, Clone, Eq)]
+pub struct Normalized(pub(crate) SubExpr<X, X>, pub(crate) Type);
+derive_other_traits!(Normalized);
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Type(pub(crate) TypeInternal);
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) enum TypeInternal {
Expr(Box<Normalized>),
Untyped,
}
-
-#[derive(Debug, Clone)]
-pub struct Normalized(pub(crate) SubExpr<X, X>, pub(crate) Type);
-
-impl PartialEq for Parsed {
- fn eq(&self, other: &Self) -> bool {
- self.0 == other.0
- }
-}
-impl std::fmt::Display for Parsed {
- fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
- self.0.fmt(f)
- }
-}
diff --git a/dhall/src/imports.rs b/dhall/src/imports.rs
index 5d94b6a..fdde8c3 100644
--- a/dhall/src/imports.rs
+++ b/dhall/src/imports.rs
@@ -44,12 +44,6 @@ impl fmt::Display for ImportError {
}
}
-// Deprecated
-pub fn panic_imports<S: Clone>(expr: &Expr<S, Import>) -> Expr<S, X> {
- let no_import = |i: &Import| -> X { panic!("ahhh import: {:?}", i) };
- expr.map_embed(&no_import)
-}
-
/// A root from which to resolve relative imports.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ImportRoot {
@@ -121,7 +115,7 @@ impl Parsed {
pub fn resolve(self) -> Result<Resolved, ImportError> {
crate::imports::resolve_expr(self, true)
}
- pub fn resolve_no_imports(self) -> Result<Resolved, ImportError> {
+ pub fn skip_resolve(self) -> Result<Resolved, ImportError> {
crate::imports::resolve_expr(self, false)
}
}
@@ -135,10 +129,3 @@ pub fn load_dhall_file(
let expr = resolve_expr(expr, resolve_imports)?;
Ok(expr.0.unroll())
}
-
-// Deprecated
-pub fn load_dhall_file_no_resolve_imports(
- f: &Path,
-) -> Result<ParsedExpr, ImportError> {
- Ok(Parsed::load_from_file(f)?.0)
-}
diff --git a/dhall/src/lib.rs b/dhall/src/lib.rs
index 28b43ba..f00e5b6 100644
--- a/dhall/src/lib.rs
+++ b/dhall/src/lib.rs
@@ -7,16 +7,14 @@
clippy::many_single_char_names
)]
-mod normalize;
-pub use crate::normalize::*;
mod binary;
-pub mod imports;
-mod traits;
+mod imports;
+mod normalize;
+pub mod traits;
pub mod typecheck;
-pub use crate::imports::*;
-pub use crate::traits::*;
+pub use crate::imports::{load_dhall_file, ImportError};
+pub use crate::traits::StaticType;
pub use dhall_generator::expr;
pub use dhall_generator::subexpr;
pub use dhall_generator::StaticType;
pub mod expr;
-pub use crate::expr::*;
diff --git a/dhall/src/main.rs b/dhall/src/main.rs
index 77f558c..2881d5a 100644
--- a/dhall/src/main.rs
+++ b/dhall/src/main.rs
@@ -2,9 +2,6 @@ use std::error::Error;
use std::io::{self, Read};
use term_painter::ToStyle;
-use dhall::*;
-use dhall_core::*;
-
const ERROR_STYLE: term_painter::Color = term_painter::Color::Red;
const BOLD: term_painter::Attr = term_painter::Attr::Bold;
@@ -57,17 +54,19 @@ fn print_error(message: &str, source: &str, start: usize, end: usize) {
fn main() {
let mut buffer = String::new();
io::stdin().read_to_string(&mut buffer).unwrap();
- let expr = match parse_expr(&buffer) {
- Ok(e) => e,
+
+ let expr = match dhall::expr::Parsed::load_from_str(&buffer) {
+ Ok(expr) => expr,
Err(e) => {
print_error(&format!("Parse error {}", e), &buffer, 0, 0);
return;
}
};
- let expr: SubExpr<_, _> = rc(imports::panic_imports(expr.as_ref()));
+ let expr = expr.resolve().unwrap();
- let type_expr = match typecheck::type_of(expr.clone()) {
+ let expr = match expr.typecheck() {
+ Ok(expr) => expr,
Err(e) => {
let explain = ::std::env::args().any(|s| s == "--explain");
if !explain {
@@ -84,10 +83,9 @@ fn main() {
// FIXME Print source position
return;
}
- Ok(type_expr) => type_expr,
};
- println!("{}", type_expr);
- println!();
- println!("{}", normalize(expr));
+ let expr = expr.normalize();
+
+ println!("{}", expr);
}
diff --git a/dhall/src/normalize.rs b/dhall/src/normalize.rs
index f9633fb..c07d3cb 100644
--- a/dhall/src/normalize.rs
+++ b/dhall/src/normalize.rs
@@ -8,6 +8,10 @@ impl Typed {
pub fn normalize(self) -> Normalized {
Normalized(normalize(self.0), self.1)
}
+ /// Pretends this expression is normalized. Use with care.
+ pub fn skip_normalize(self) -> Normalized {
+ Normalized(self.0, self.1)
+ }
}
fn apply_builtin<S, A>(b: Builtin, args: &Vec<Expr<S, A>>) -> WhatNext<S, A>
@@ -209,7 +213,7 @@ enum WhatNext<'a, S, A> {
DoneAsIs,
}
-pub fn normalize_ref<S, A>(expr: &Expr<S, A>) -> Expr<S, A>
+fn normalize_ref<S, A>(expr: &Expr<S, A>) -> Expr<S, A>
where
S: fmt::Debug + Clone,
A: fmt::Debug + Clone,
@@ -313,7 +317,7 @@ where
/// However, `normalize` will not fail if the expression is ill-typed and will
/// leave ill-typed sub-expressions unevaluated.
///
-pub fn normalize<S, A>(e: SubExpr<S, A>) -> SubExpr<S, A>
+fn normalize<S, A>(e: SubExpr<S, A>) -> SubExpr<S, A>
where
S: fmt::Debug + Clone,
A: fmt::Debug + Clone,
diff --git a/dhall/src/typecheck.rs b/dhall/src/typecheck.rs
index a0782f8..babfad0 100644
--- a/dhall/src/typecheck.rs
+++ b/dhall/src/typecheck.rs
@@ -11,8 +11,11 @@ use self::TypeMessage::*;
impl Resolved {
pub fn typecheck(self) -> Result<Typed, TypeError<X>> {
- let typ = crate::typecheck::type_of_(self.0.clone())?;
- Ok(typ)
+ type_of_(self.0.clone())
+ }
+ /// Pretends this expression has been typechecked. Use with care.
+ pub fn skip_typecheck(self) -> Typed {
+ Typed(self.0, UNTYPE)
}
}
impl Typed {
@@ -63,7 +66,7 @@ impl Normalized {
}
impl Type {
#[inline(always)]
- fn as_normalized(&self) -> Result<&Normalized, TypeError<X>> {
+ pub fn as_normalized(&self) -> Result<&Normalized, TypeError<X>> {
use TypeInternal::*;
match &self.0 {
Expr(e) => Ok(e),
diff --git a/dhall/tests/common/mod.rs b/dhall/tests/common/mod.rs
index fc5aa5b..5f16d2c 100644
--- a/dhall/tests/common/mod.rs
+++ b/dhall/tests/common/mod.rs
@@ -44,20 +44,21 @@ pub enum Feature {
TypeInferenceFailure,
}
+// Deprecated
fn read_dhall_file<'i>(file_path: &str) -> Result<Expr<X, X>, ImportError> {
- load_dhall_file(&PathBuf::from(file_path), true)
+ dhall::load_dhall_file(&PathBuf::from(file_path), true)
}
fn load_from_file_str<'i>(
file_path: &str,
-) -> Result<dhall::Parsed, ImportError> {
- Parsed::load_from_file(&PathBuf::from(file_path))
+) -> Result<dhall::expr::Parsed, ImportError> {
+ dhall::expr::Parsed::load_from_file(&PathBuf::from(file_path))
}
fn load_from_binary_file_str<'i>(
file_path: &str,
-) -> Result<dhall::Parsed, ImportError> {
- Parsed::load_from_binary_file(&PathBuf::from(file_path))
+) -> Result<dhall::expr::Parsed, ImportError> {
+ dhall::expr::Parsed::load_from_binary_file(&PathBuf::from(file_path))
}
pub fn run_test(base_path: &str, feature: Feature) {
@@ -88,7 +89,8 @@ pub fn run_test(base_path: &str, feature: Feature) {
assert_eq_pretty!(expr, expected);
// Round-trip pretty-printer
- let expr = Parsed::load_from_str(&expr.to_string()).unwrap();
+ let expr =
+ dhall::expr::Parsed::load_from_str(&expr.to_string()).unwrap();
assert_eq!(expr, expected);
}
ParserFailure => {
@@ -102,15 +104,29 @@ pub fn run_test(base_path: &str, feature: Feature) {
Normalization => {
let expr_file_path = base_path.clone() + "A.dhall";
let expected_file_path = base_path + "B.dhall";
- let expr = rc(read_dhall_file(&expr_file_path).unwrap());
- let expected = rc(read_dhall_file(&expected_file_path).unwrap());
+ let expr = load_from_file_str(&expr_file_path)
+ .unwrap()
+ .resolve()
+ .unwrap()
+ .skip_typecheck()
+ .normalize();
+ let expected = load_from_file_str(&expected_file_path)
+ .unwrap()
+ .resolve()
+ .unwrap()
+ .skip_typecheck()
+ .normalize();
- assert_eq_display!(normalize(expr), normalize(expected));
+ assert_eq_display!(expr, expected);
}
TypecheckFailure => {
let file_path = base_path + ".dhall";
- let expr = rc(read_dhall_file(&file_path).unwrap());
- typecheck::type_of(expr).unwrap_err();
+ load_from_file_str(&file_path)
+ .unwrap()
+ .skip_resolve()
+ .unwrap()
+ .typecheck()
+ .unwrap_err();
}
TypecheckSuccess => {
// Many tests stack overflow in debug mode
@@ -131,15 +147,30 @@ pub fn run_test(base_path: &str, feature: Feature) {
}
TypeInferenceFailure => {
let file_path = base_path + ".dhall";
- let expr = rc(read_dhall_file(&file_path).unwrap());
- typecheck::type_of(expr).unwrap_err();
+ load_from_file_str(&file_path)
+ .unwrap()
+ .skip_resolve()
+ .unwrap()
+ .typecheck()
+ .unwrap_err();
}
TypeInferenceSuccess => {
let expr_file_path = base_path.clone() + "A.dhall";
let expected_file_path = base_path + "B.dhall";
- let expr = rc(read_dhall_file(&expr_file_path).unwrap());
- let expected = rc(read_dhall_file(&expected_file_path).unwrap());
- assert_eq_display!(typecheck::type_of(expr).unwrap(), expected);
+ let expr = load_from_file_str(&expr_file_path)
+ .unwrap()
+ .skip_resolve()
+ .unwrap()
+ .typecheck()
+ .unwrap();
+ let ty = expr.get_type().as_normalized().unwrap();
+ let expected = load_from_file_str(&expected_file_path)
+ .unwrap()
+ .skip_resolve()
+ .unwrap()
+ .skip_typecheck()
+ .skip_normalize();
+ assert_eq_display!(ty, &expected);
}
}
}