summaryrefslogtreecommitdiff
path: root/dhall
diff options
context:
space:
mode:
authorNadrieril2020-04-05 17:57:07 +0100
committerGitHub2020-04-05 17:57:07 +0100
commit7e977f282fb6a0eff0ef45738b9b5c98dc4c6fee (patch)
treead4249609707fd8720a44469152105c2f6a67c79 /dhall
parent5a5aa49e64197899006751db72e404f4b2292d4e (diff)
parent820214615547101f8f2b5de209b5189968bddfee (diff)
Merge pull request #154 from Nadrieril/cleanup-api
Rewrite serde_dhall API
Diffstat (limited to '')
-rw-r--r--dhall/Cargo.toml3
-rw-r--r--dhall/README.md9
-rw-r--r--dhall/src/error/builder.rs2
-rw-r--r--dhall/src/error/mod.rs14
-rw-r--r--dhall/src/lib.rs120
-rw-r--r--dhall/src/semantics/builtins.rs105
-rw-r--r--dhall/src/semantics/mod.rs8
-rw-r--r--dhall/src/semantics/nze/env.rs6
-rw-r--r--dhall/src/semantics/nze/mod.rs8
-rw-r--r--dhall/src/semantics/nze/nir.rs140
-rw-r--r--dhall/src/semantics/nze/normalize.rs100
-rw-r--r--dhall/src/semantics/nze/var.rs4
-rw-r--r--dhall/src/semantics/parse.rs10
-rw-r--r--dhall/src/semantics/resolve/env.rs19
-rw-r--r--dhall/src/semantics/resolve/hir.rs28
-rw-r--r--dhall/src/semantics/resolve/mod.rs6
-rw-r--r--dhall/src/semantics/resolve/resolve.rs20
-rw-r--r--dhall/src/semantics/tck/env.rs8
-rw-r--r--dhall/src/semantics/tck/mod.rs6
-rw-r--r--dhall/src/semantics/tck/tir.rs13
-rw-r--r--dhall/src/semantics/tck/typecheck.rs55
-rw-r--r--dhall/src/syntax/ast/expr.rs16
-rw-r--r--dhall/src/syntax/ast/mod.rs2
-rw-r--r--dhall/src/syntax/ast/span.rs12
-rw-r--r--dhall/src/syntax/ast/visitor.rs4
-rw-r--r--dhall/src/syntax/binary/decode.rs20
-rw-r--r--dhall/src/syntax/binary/encode.rs12
-rw-r--r--dhall/src/syntax/binary/mod.rs4
-rw-r--r--dhall/src/syntax/text/parser.rs14
-rw-r--r--dhall/src/syntax/text/printer.rs6
-rw-r--r--dhall/src/tests.rs17
-rw-r--r--dhall/tests/version_numbers.rs4
-rw-r--r--dhall_proc_macros/Cargo.toml3
-rw-r--r--dhall_proc_macros/src/derive.rs19
-rw-r--r--dhall_proc_macros/tests/version_numbers.rs4
35 files changed, 336 insertions, 485 deletions
diff --git a/dhall/Cargo.toml b/dhall/Cargo.toml
index 0ffe78b..bb60d9e 100644
--- a/dhall/Cargo.toml
+++ b/dhall/Cargo.toml
@@ -22,10 +22,11 @@ reqwest = { version = "0.10", features = ["blocking"] }
serde = "1.0"
serde_cbor = "0.9.0"
smallvec = "1.0.0"
-url = "2.1.1"
+url = "2.1"
[dev-dependencies]
pretty_assertions = "0.6.1"
+version-sync = "0.8"
[build-dependencies]
walkdir = "2"
diff --git a/dhall/README.md b/dhall/README.md
index 82b3e6a..25f11f7 100644
--- a/dhall/README.md
+++ b/dhall/README.md
@@ -1,10 +1,11 @@
# `dhall`
Implementation of the Dhall configuration language.
-This is an internal crate used for [`serde_dhall`], you probably want to use
-that instead.
-The API is very unstable and does not respect semver;
-use at your own risk.
+WARNING: This is an internal crate used for [`serde_dhall`], you probably want
+to use that instead.
+
+WARNING: The API is very unstable and does not respect semver; use at your own
+risk.
[`serde_dhall`]: https://docs.rs/serde_dhall
diff --git a/dhall/src/error/builder.rs b/dhall/src/error/builder.rs
index c0bacb5..3ee65fb 100644
--- a/dhall/src/error/builder.rs
+++ b/dhall/src/error/builder.rs
@@ -6,7 +6,7 @@ use annotate_snippets::{
use crate::syntax::{ParsedSpan, Span};
#[derive(Debug, Clone, Default)]
-pub(crate) struct ErrorBuilder {
+pub struct ErrorBuilder {
title: FreeAnnotation,
annotations: Vec<SpannedAnnotation>,
footer: Vec<FreeAnnotation>,
diff --git a/dhall/src/error/mod.rs b/dhall/src/error/mod.rs
index e28b98b..ef4d41f 100644
--- a/dhall/src/error/mod.rs
+++ b/dhall/src/error/mod.rs
@@ -4,7 +4,7 @@ use crate::semantics::resolve::{ImportLocation, ImportStack};
use crate::syntax::{Import, ParseError};
mod builder;
-pub(crate) use builder::*;
+pub use builder::*;
pub type Result<T> = std::result::Result<T, Error>;
@@ -15,7 +15,7 @@ pub struct Error {
#[derive(Debug)]
#[non_exhaustive]
-pub(crate) enum ErrorKind {
+pub enum ErrorKind {
IO(IOError),
Parse(ParseError),
Decode(DecodeError),
@@ -25,7 +25,7 @@ pub(crate) enum ErrorKind {
}
#[derive(Debug)]
-pub(crate) enum ImportError {
+pub enum ImportError {
Missing,
MissingEnvVar,
SanityCheck,
@@ -53,21 +53,21 @@ pub struct TypeError {
/// The specific type error
#[derive(Debug)]
-pub(crate) enum TypeMessage {
+pub enum TypeMessage {
Custom(String),
}
impl Error {
- pub(crate) fn new(kind: ErrorKind) -> Self {
+ pub fn new(kind: ErrorKind) -> Self {
Error { kind }
}
- pub(crate) fn kind(&self) -> &ErrorKind {
+ pub fn kind(&self) -> &ErrorKind {
&self.kind
}
}
impl TypeError {
- pub(crate) fn new(message: TypeMessage) -> Self {
+ pub fn new(message: TypeMessage) -> Self {
TypeError { message }
}
}
diff --git a/dhall/src/lib.rs b/dhall/src/lib.rs
index 24e4377..392c344 100644
--- a/dhall/src/lib.rs
+++ b/dhall/src/lib.rs
@@ -1,7 +1,10 @@
#![doc(html_root_url = "https://docs.rs/dhall/0.4.0")]
#![allow(
+ clippy::implicit_hasher,
clippy::module_inception,
clippy::needless_lifetimes,
+ clippy::new_ret_no_self,
+ clippy::new_without_default,
clippy::useless_format
)]
@@ -15,23 +18,15 @@ use std::fmt::Display;
use std::path::Path;
use url::Url;
-use crate::error::{EncodeError, Error, TypeError};
+use crate::error::{Error, TypeError};
use crate::semantics::parse;
use crate::semantics::resolve;
use crate::semantics::resolve::ImportLocation;
-use crate::semantics::{
- typecheck, typecheck_with, Hir, Nir, NirKind, Tir, Type,
-};
-use crate::syntax::binary;
-use crate::syntax::{Builtin, Expr};
-
-pub type ParsedExpr = Expr;
-pub type DecodedExpr = Expr;
-pub type ResolvedExpr = Expr;
-pub type NormalizedExpr = Expr;
+use crate::semantics::{typecheck, typecheck_with, Hir, Nir, Tir, Type};
+use crate::syntax::Expr;
#[derive(Debug, Clone)]
-pub struct Parsed(ParsedExpr, ImportLocation);
+pub struct Parsed(Expr, ImportLocation);
/// An expression where all imports have been resolved
///
@@ -48,15 +43,15 @@ pub struct Typed {
/// A normalized expression.
///
-/// Invariant: the contained expression must be in normal form,
+/// This is actually a lie, because the expression will only get normalized on demand.
#[derive(Debug, Clone)]
pub struct Normalized(Nir);
/// Controls conversion from `Nir` to `Expr`
-#[derive(Copy, Clone)]
-pub(crate) struct ToExprOptions {
+#[derive(Copy, Clone, Default)]
+pub struct ToExprOptions {
/// Whether to convert all variables to `_`
- pub(crate) alpha: bool,
+ pub alpha: bool,
}
impl Parsed {
@@ -72,6 +67,7 @@ impl Parsed {
pub fn parse_binary_file(f: &Path) -> Result<Parsed, Error> {
parse::parse_binary_file(f)
}
+ #[allow(dead_code)]
pub fn parse_binary(data: &[u8]) -> Result<Parsed, Error> {
parse::parse_binary(data)
}
@@ -80,15 +76,11 @@ impl Parsed {
resolve::resolve(self)
}
pub fn skip_resolve(self) -> Result<Resolved, Error> {
- Ok(Resolved(resolve::skip_resolve(&self.0)?))
- }
-
- pub fn encode(&self) -> Result<Vec<u8>, EncodeError> {
- binary::encode(&self.0)
+ resolve::skip_resolve(self)
}
/// Converts a value back to the corresponding AST expression.
- pub fn to_expr(&self) -> ParsedExpr {
+ pub fn to_expr(&self) -> Expr {
self.0.clone()
}
}
@@ -97,11 +89,11 @@ impl Resolved {
pub fn typecheck(&self) -> Result<Typed, TypeError> {
Ok(Typed::from_tir(typecheck(&self.0)?))
}
- pub fn typecheck_with(self, ty: &Normalized) -> Result<Typed, TypeError> {
- Ok(Typed::from_tir(typecheck_with(&self.0, ty.to_hir())?))
+ pub fn typecheck_with(self, ty: &Hir) -> Result<Typed, TypeError> {
+ Ok(Typed::from_tir(typecheck_with(&self.0, ty)?))
}
/// Converts a value back to the corresponding AST expression.
- pub fn to_expr(&self) -> ResolvedExpr {
+ pub fn to_expr(&self) -> Expr {
self.0.to_expr_noopts()
}
}
@@ -115,79 +107,38 @@ impl Typed {
}
/// Reduce an expression to its normal form, performing beta reduction
pub fn normalize(&self) -> Normalized {
- Normalized(self.hir.rec_eval_closed_expr())
+ Normalized(self.hir.eval_closed_expr())
}
/// Converts a value back to the corresponding AST expression.
- fn to_expr(&self) -> ResolvedExpr {
+ fn to_expr(&self) -> Expr {
self.hir.to_expr(ToExprOptions { alpha: false })
}
- pub(crate) fn ty(&self) -> &Type {
+ pub fn ty(&self) -> &Type {
&self.ty
}
- pub(crate) fn get_type(&self) -> Result<Normalized, TypeError> {
+ pub fn get_type(&self) -> Result<Normalized, TypeError> {
Ok(Normalized(self.ty.clone().into_nir()))
}
}
impl Normalized {
- pub fn encode(&self) -> Result<Vec<u8>, EncodeError> {
- binary::encode(&self.to_expr())
- }
-
/// Converts a value back to the corresponding AST expression.
- pub fn to_expr(&self) -> NormalizedExpr {
- self.0.to_expr(ToExprOptions { alpha: false })
+ pub fn to_expr(&self) -> Expr {
+ self.0.to_expr(ToExprOptions::default())
}
/// Converts a value back to the corresponding Hir expression.
- pub(crate) fn to_hir(&self) -> Hir {
+ pub fn to_hir(&self) -> Hir {
self.0.to_hir_noenv()
}
+ pub fn as_nir(&self) -> &Nir {
+ &self.0
+ }
/// Converts a value back to the corresponding AST expression, alpha-normalizing in the process.
- pub(crate) fn to_expr_alpha(&self) -> NormalizedExpr {
+ pub fn to_expr_alpha(&self) -> Expr {
self.0.to_expr(ToExprOptions { alpha: true })
}
- pub(crate) fn to_nir(&self) -> Nir {
- self.0.clone()
- }
- pub(crate) fn into_nir(self) -> Nir {
- self.0
- }
-
- pub(crate) fn from_kind(v: NirKind) -> Self {
- Normalized(Nir::from_kind(v))
- }
- pub(crate) fn from_nir(th: Nir) -> Self {
- Normalized(th)
- }
-
- pub fn make_builtin_type(b: Builtin) -> Self {
- Normalized::from_nir(Nir::from_builtin(b))
- }
- pub fn make_optional_type(t: Normalized) -> Self {
- Normalized::from_nir(
- Nir::from_builtin(Builtin::Optional).app(t.to_nir()),
- )
- }
- pub fn make_list_type(t: Normalized) -> Self {
- Normalized::from_nir(Nir::from_builtin(Builtin::List).app(t.to_nir()))
- }
- pub fn make_record_type(
- kts: impl Iterator<Item = (String, Normalized)>,
- ) -> Self {
- Normalized::from_kind(NirKind::RecordType(
- kts.map(|(k, t)| (k.into(), t.into_nir())).collect(),
- ))
- }
- pub fn make_union_type(
- kts: impl Iterator<Item = (String, Option<Normalized>)>,
- ) -> Self {
- Normalized::from_kind(NirKind::UnionType(
- kts.map(|(k, t)| (k.into(), t.map(|t| t.into_nir())))
- .collect(),
- ))
- }
}
macro_rules! derive_traits_for_wrapper_struct {
@@ -213,23 +164,12 @@ macro_rules! derive_traits_for_wrapper_struct {
derive_traits_for_wrapper_struct!(Parsed);
-impl std::hash::Hash for Normalized {
- fn hash<H>(&self, state: &mut H)
- where
- H: std::hash::Hasher,
- {
- if let Ok(vec) = self.encode() {
- vec.hash(state)
- }
- }
-}
-
-impl From<Parsed> for NormalizedExpr {
+impl From<Parsed> for Expr {
fn from(other: Parsed) -> Self {
other.to_expr()
}
}
-impl From<Normalized> for NormalizedExpr {
+impl From<Normalized> for Expr {
fn from(other: Normalized) -> Self {
other.to_expr()
}
diff --git a/dhall/src/semantics/builtins.rs b/dhall/src/semantics/builtins.rs
index 803630b..6007a92 100644
--- a/dhall/src/semantics/builtins.rs
+++ b/dhall/src/semantics/builtins.rs
@@ -1,48 +1,35 @@
use crate::semantics::{
- skip_resolve, typecheck, Hir, HirKind, Nir, NirKind, NzEnv, VarEnv,
+ skip_resolve_expr, typecheck, Hir, HirKind, Nir, NirKind, NzEnv, VarEnv,
};
use crate::syntax::map::DupTreeMap;
use crate::syntax::Const::Type;
use crate::syntax::{
BinOp, Builtin, Const, Expr, ExprKind, InterpolatedText,
- InterpolatedTextContents, Label, LitKind, NaiveDouble, Span, UnspannedExpr,
+ InterpolatedTextContents, Label, NaiveDouble, NumKind, Span, UnspannedExpr,
V,
};
-use crate::Normalized;
use std::collections::HashMap;
use std::convert::TryInto;
/// A partially applied builtin.
/// Invariant: the evaluation of the given args must not be able to progress further
#[derive(Debug, Clone)]
-pub(crate) struct BuiltinClosure<Nir> {
- pub env: NzEnv,
- pub b: Builtin,
+pub struct BuiltinClosure {
+ env: NzEnv,
+ b: Builtin,
/// Arguments applied to the closure so far.
- pub args: Vec<Nir>,
+ args: Vec<Nir>,
}
-impl BuiltinClosure<Nir> {
- pub fn new(b: Builtin, env: NzEnv) -> Self {
- BuiltinClosure {
- env,
- b,
- args: Vec::new(),
- }
+impl BuiltinClosure {
+ pub fn new(b: Builtin, env: NzEnv) -> NirKind {
+ apply_builtin(b, Vec::new(), env)
}
-
pub fn apply(&self, a: Nir) -> NirKind {
use std::iter::once;
let args = self.args.iter().cloned().chain(once(a)).collect();
apply_builtin(self.b, args, self.env.clone())
}
- /// This doesn't break the invariant because we already checked that the appropriate arguments
- /// did not normalize to something that allows evaluation to proceed.
- pub fn normalize(&self) {
- for x in self.args.iter() {
- x.normalize();
- }
- }
pub fn to_hirkind(&self, venv: VarEnv) -> HirKind {
HirKind::Expr(self.args.iter().fold(
ExprKind::Builtin(self.b),
@@ -56,7 +43,7 @@ impl BuiltinClosure<Nir> {
}
}
-pub(crate) fn rc(x: UnspannedExpr) -> Expr {
+pub fn rc(x: UnspannedExpr) -> Expr {
Expr::new(x, Span::Artificial)
}
@@ -116,7 +103,7 @@ macro_rules! make_type {
};
}
-pub(crate) fn type_of_builtin(b: Builtin) -> Hir {
+pub fn type_of_builtin(b: Builtin) -> Hir {
use Builtin::*;
let expr = match b {
Bool | Natural | Integer | Double | Text => make_type!(Type),
@@ -202,7 +189,7 @@ pub(crate) fn type_of_builtin(b: Builtin) -> Hir {
forall (A: Type) -> Optional A
),
};
- skip_resolve(&expr).unwrap()
+ skip_resolve_expr(&expr).unwrap()
}
// Ad-hoc macro to help construct closures
@@ -241,7 +228,7 @@ macro_rules! make_closure {
rc(ExprKind::BinOp(
BinOp::NaturalPlus,
make_closure!($($v)*),
- rc(ExprKind::Lit(LitKind::Natural(1)))
+ rc(ExprKind::Num(NumKind::Natural(1)))
))
};
([ $($head:tt)* ] # $($tail:tt)*) => {{
@@ -257,8 +244,8 @@ macro_rules! make_closure {
#[allow(clippy::cognitive_complexity)]
fn apply_builtin(b: Builtin, args: Vec<Nir>, env: NzEnv) -> NirKind {
- use LitKind::{Bool, Double, Integer, Natural};
use NirKind::*;
+ use NumKind::{Bool, Double, Integer, Natural};
// Small helper enum
enum Ret {
@@ -267,46 +254,54 @@ fn apply_builtin(b: Builtin, args: Vec<Nir>, env: NzEnv) -> NirKind {
DoneAsIs,
}
let make_closure = |e| {
- typecheck(&skip_resolve(&e).unwrap())
+ typecheck(&skip_resolve_expr(&e).unwrap())
.unwrap()
.eval(env.clone())
};
let ret = match (b, args.as_slice()) {
+ (Builtin::Bool, [])
+ | (Builtin::Natural, [])
+ | (Builtin::Integer, [])
+ | (Builtin::Double, [])
+ | (Builtin::Text, []) => Ret::NirKind(BuiltinType(b)),
+ (Builtin::Optional, [t]) => Ret::NirKind(OptionalType(t.clone())),
+ (Builtin::List, [t]) => Ret::NirKind(ListType(t.clone())),
+
(Builtin::OptionalNone, [t]) => {
Ret::NirKind(EmptyOptionalLit(t.clone()))
}
(Builtin::NaturalIsZero, [n]) => match &*n.kind() {
- Lit(Natural(n)) => Ret::NirKind(Lit(Bool(*n == 0))),
+ Num(Natural(n)) => Ret::NirKind(Num(Bool(*n == 0))),
_ => Ret::DoneAsIs,
},
(Builtin::NaturalEven, [n]) => match &*n.kind() {
- Lit(Natural(n)) => Ret::NirKind(Lit(Bool(*n % 2 == 0))),
+ Num(Natural(n)) => Ret::NirKind(Num(Bool(*n % 2 == 0))),
_ => Ret::DoneAsIs,
},
(Builtin::NaturalOdd, [n]) => match &*n.kind() {
- Lit(Natural(n)) => Ret::NirKind(Lit(Bool(*n % 2 != 0))),
+ Num(Natural(n)) => Ret::NirKind(Num(Bool(*n % 2 != 0))),
_ => Ret::DoneAsIs,
},
(Builtin::NaturalToInteger, [n]) => match &*n.kind() {
- Lit(Natural(n)) => Ret::NirKind(Lit(Integer(*n as isize))),
+ Num(Natural(n)) => Ret::NirKind(Num(Integer(*n as isize))),
_ => Ret::DoneAsIs,
},
(Builtin::NaturalShow, [n]) => match &*n.kind() {
- Lit(Natural(n)) => Ret::Nir(Nir::from_text(n)),
+ Num(Natural(n)) => Ret::Nir(Nir::from_text(n)),
_ => Ret::DoneAsIs,
},
(Builtin::NaturalSubtract, [a, b]) => match (&*a.kind(), &*b.kind()) {
- (Lit(Natural(a)), Lit(Natural(b))) => {
- Ret::NirKind(Lit(Natural(if b > a { b - a } else { 0 })))
+ (Num(Natural(a)), Num(Natural(b))) => {
+ Ret::NirKind(Num(Natural(if b > a { b - a } else { 0 })))
}
- (Lit(Natural(0)), _) => Ret::Nir(b.clone()),
- (_, Lit(Natural(0))) => Ret::NirKind(Lit(Natural(0))),
- _ if a == b => Ret::NirKind(Lit(Natural(0))),
+ (Num(Natural(0)), _) => Ret::Nir(b.clone()),
+ (_, Num(Natural(0))) => Ret::NirKind(Num(Natural(0))),
+ _ if a == b => Ret::NirKind(Num(Natural(0))),
_ => Ret::DoneAsIs,
},
(Builtin::IntegerShow, [n]) => match &*n.kind() {
- Lit(Integer(n)) => {
+ Num(Integer(n)) => {
let s = if *n < 0 {
n.to_string()
} else {
@@ -317,30 +312,30 @@ fn apply_builtin(b: Builtin, args: Vec<Nir>, env: NzEnv) -> NirKind {
_ => Ret::DoneAsIs,
},
(Builtin::IntegerToDouble, [n]) => match &*n.kind() {
- Lit(Integer(n)) => {
- Ret::NirKind(Lit(Double(NaiveDouble::from(*n as f64))))
+ Num(Integer(n)) => {
+ Ret::NirKind(Num(Double(NaiveDouble::from(*n as f64))))
}
_ => Ret::DoneAsIs,
},
(Builtin::IntegerNegate, [n]) => match &*n.kind() {
- Lit(Integer(n)) => Ret::NirKind(Lit(Integer(-n))),
+ Num(Integer(n)) => Ret::NirKind(Num(Integer(-n))),
_ => Ret::DoneAsIs,
},
(Builtin::IntegerClamp, [n]) => match &*n.kind() {
- Lit(Integer(n)) => {
- Ret::NirKind(Lit(Natural((*n).try_into().unwrap_or(0))))
+ Num(Integer(n)) => {
+ Ret::NirKind(Num(Natural((*n).try_into().unwrap_or(0))))
}
_ => Ret::DoneAsIs,
},
(Builtin::DoubleShow, [n]) => match &*n.kind() {
- Lit(Double(n)) => Ret::Nir(Nir::from_text(n)),
+ Num(Double(n)) => Ret::Nir(Nir::from_text(n)),
_ => Ret::DoneAsIs,
},
(Builtin::TextShow, [v]) => match &*v.kind() {
TextLit(tlit) => {
if let Some(s) = tlit.as_text() {
// Printing InterpolatedText takes care of all the escaping
- let txt: InterpolatedText<Normalized> =
+ let txt: InterpolatedText<Expr> =
std::iter::once(InterpolatedTextContents::Text(s))
.collect();
Ret::Nir(Nir::from_text(txt))
@@ -351,8 +346,8 @@ fn apply_builtin(b: Builtin, args: Vec<Nir>, env: NzEnv) -> NirKind {
_ => Ret::DoneAsIs,
},
(Builtin::ListLength, [_, l]) => match &*l.kind() {
- EmptyListLit(_) => Ret::NirKind(Lit(Natural(0))),
- NEListLit(xs) => Ret::NirKind(Lit(Natural(xs.len()))),
+ EmptyListLit(_) => Ret::NirKind(Num(Natural(0))),
+ NEListLit(xs) => Ret::NirKind(Num(Natural(xs.len()))),
_ => Ret::DoneAsIs,
},
(Builtin::ListHead, [_, l]) => match &*l.kind() {
@@ -398,7 +393,7 @@ fn apply_builtin(b: Builtin, args: Vec<Nir>, env: NzEnv) -> NirKind {
let mut kvs = HashMap::new();
kvs.insert(
"index".into(),
- Nir::from_kind(Lit(Natural(i))),
+ Nir::from_kind(Num(Natural(i))),
);
kvs.insert("value".into(), e.clone());
Nir::from_kind(RecordLit(kvs))
@@ -466,14 +461,14 @@ fn apply_builtin(b: Builtin, args: Vec<Nir>, env: NzEnv) -> NirKind {
λ(x : Natural) ->
1 + var(x)
)))
- .app(Lit(Natural(0)).into_nir()),
+ .app(Num(Natural(0)).into_nir()),
),
(Builtin::NaturalFold, [n, t, succ, zero]) => match &*n.kind() {
- Lit(Natural(0)) => Ret::Nir(zero.clone()),
- Lit(Natural(n)) => {
+ Num(Natural(0)) => Ret::Nir(zero.clone()),
+ Num(Natural(n)) => {
let fold = Nir::from_builtin(Builtin::NaturalFold)
- .app(Lit(Natural(n - 1)).into_nir())
+ .app(Num(Natural(n - 1)).into_nir())
.app(t.clone())
.app(succ.clone())
.app(zero.clone());
@@ -490,9 +485,9 @@ fn apply_builtin(b: Builtin, args: Vec<Nir>, env: NzEnv) -> NirKind {
}
}
-impl<Nir: std::cmp::PartialEq> std::cmp::PartialEq for BuiltinClosure<Nir> {
+impl std::cmp::PartialEq for BuiltinClosure {
fn eq(&self, other: &Self) -> bool {
self.b == other.b && self.args == other.args
}
}
-impl<Nir: std::cmp::Eq> std::cmp::Eq for BuiltinClosure<Nir> {}
+impl std::cmp::Eq for BuiltinClosure {}
diff --git a/dhall/src/semantics/mod.rs b/dhall/src/semantics/mod.rs
index 87033c9..468d8b1 100644
--- a/dhall/src/semantics/mod.rs
+++ b/dhall/src/semantics/mod.rs
@@ -3,7 +3,7 @@ pub mod nze;
pub mod parse;
pub mod resolve;
pub mod tck;
-pub(crate) use self::builtins::*;
-pub(crate) use self::nze::*;
-pub(crate) use self::resolve::*;
-pub(crate) use self::tck::*;
+pub use self::builtins::*;
+pub use self::nze::*;
+pub use self::resolve::*;
+pub use self::tck::*;
diff --git a/dhall/src/semantics/nze/env.rs b/dhall/src/semantics/nze/env.rs
index ef2bee6..ec99dbe 100644
--- a/dhall/src/semantics/nze/env.rs
+++ b/dhall/src/semantics/nze/env.rs
@@ -1,7 +1,7 @@
use crate::semantics::{AlphaVar, Nir, NirKind};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-pub(crate) enum NzVar {
+pub enum NzVar {
/// Reverse-debruijn index: counts number of binders from the bottom of the stack.
Bound(usize),
/// Fake fresh variable generated for expression equality checking.
@@ -17,11 +17,11 @@ enum EnvItem<Type> {
}
#[derive(Debug, Clone)]
-pub(crate) struct ValEnv<Type> {
+pub struct ValEnv<Type> {
items: Vec<EnvItem<Type>>,
}
-pub(crate) type NzEnv = ValEnv<()>;
+pub type NzEnv = ValEnv<()>;
impl NzVar {
pub fn new(idx: usize) -> Self {
diff --git a/dhall/src/semantics/nze/mod.rs b/dhall/src/semantics/nze/mod.rs
index 2648339..23022e0 100644
--- a/dhall/src/semantics/nze/mod.rs
+++ b/dhall/src/semantics/nze/mod.rs
@@ -3,7 +3,7 @@ pub mod lazy;
pub mod nir;
pub mod normalize;
pub mod var;
-pub(crate) use env::*;
-pub(crate) use nir::*;
-pub(crate) use normalize::*;
-pub(crate) use var::*;
+pub use env::*;
+pub use nir::*;
+pub use normalize::*;
+pub use var::*;
diff --git a/dhall/src/semantics/nze/nir.rs b/dhall/src/semantics/nze/nir.rs
index 32ef590..e0d227e 100644
--- a/dhall/src/semantics/nze/nir.rs
+++ b/dhall/src/semantics/nze/nir.rs
@@ -7,10 +7,10 @@ use crate::semantics::{
BuiltinClosure, Hir, HirKind, NzEnv, NzVar, TyEnv, Type, Universe, VarEnv,
};
use crate::syntax::{
- BinOp, Builtin, Const, ExprKind, InterpolatedTextContents, Label, LitKind,
- Span,
+ BinOp, Builtin, Const, Expr, ExprKind, InterpolatedTextContents, Label,
+ NumKind, Span,
};
-use crate::{NormalizedExpr, ToExprOptions};
+use crate::ToExprOptions;
/// Stores a possibly unevaluated value. Gets (partially) normalized on-demand, sharing computation
/// automatically. Uses a Rc<RefCell> to share computation.
@@ -19,7 +19,7 @@ use crate::{NormalizedExpr, ToExprOptions};
/// normalize as needed.
/// Stands for "Normalized intermediate representation"
#[derive(Clone)]
-pub(crate) struct Nir(Rc<NirInternal>);
+pub struct Nir(Rc<NirInternal>);
#[derive(Debug)]
struct NirInternal {
@@ -28,7 +28,7 @@ struct NirInternal {
/// An unevaluated subexpression
#[derive(Debug, Clone)]
-pub(crate) enum Thunk {
+pub enum Thunk {
/// A completely unnormalized expression.
Thunk { env: NzEnv, body: Hir },
/// A partially normalized expression that may need to go through `normalize_one_layer`.
@@ -37,7 +37,7 @@ pub(crate) enum Thunk {
/// An unevaluated subexpression that takes an argument.
#[derive(Debug, Clone)]
-pub(crate) enum Closure {
+pub enum Closure {
/// Normal closure
Closure { env: NzEnv, body: Hir },
/// Closure that ignores the argument passed
@@ -48,7 +48,7 @@ pub(crate) enum Closure {
// Invariant: this must not contain interpolations that are themselves TextLits, and contiguous
// text values must be merged.
#[derive(Debug, Clone, PartialEq, Eq)]
-pub(crate) struct TextLit(Vec<InterpolatedTextContents<Nir>>);
+pub struct TextLit(Vec<InterpolatedTextContents<Nir>>);
/// This represents a value in Weak Head Normal Form (WHNF). This means that the value is
/// normalized up to the first constructor, but subexpressions may not be fully normalized.
@@ -58,7 +58,7 @@ pub(crate) struct TextLit(Vec<InterpolatedTextContents<Nir>>);
/// In particular, this means that once we get a `NirKind`, it can be considered immutable, and
/// we only need to recursively normalize its sub-`Nir`s to get to the NF.
#[derive(Debug, Clone, PartialEq, Eq)]
-pub(crate) enum NirKind {
+pub enum NirKind {
/// Closures
LamClosure {
binder: Binder,
@@ -70,13 +70,17 @@ pub(crate) enum NirKind {
annot: Nir,
closure: Closure,
},
- AppliedBuiltin(BuiltinClosure<Nir>),
+ AppliedBuiltin(BuiltinClosure),
Var(NzVar),
Const(Const),
- Lit(LitKind),
+ // Must be a number type, Bool or Text
+ BuiltinType(Builtin),
+ Num(NumKind),
+ OptionalType(Nir),
EmptyOptionalLit(Nir),
NEOptionalLit(Nir),
+ ListType(Nir),
// EmptyListLit(t) means `[] : List t`, not `[] : t`
EmptyListLit(Nir),
NEListLit(Vec<Nir>),
@@ -93,34 +97,34 @@ pub(crate) enum NirKind {
impl Nir {
/// Construct a Nir from a completely unnormalized expression.
- pub(crate) fn new_thunk(env: NzEnv, hir: Hir) -> Nir {
+ pub fn new_thunk(env: NzEnv, hir: Hir) -> Nir {
NirInternal::from_thunk(Thunk::new(env, hir)).into_nir()
}
/// Construct a Nir from a partially normalized expression that's not in WHNF.
- pub(crate) fn from_partial_expr(e: ExprKind<Nir>) -> Nir {
+ pub fn from_partial_expr(e: ExprKind<Nir>) -> Nir {
// TODO: env
let env = NzEnv::new();
NirInternal::from_thunk(Thunk::from_partial_expr(env, e)).into_nir()
}
/// Make a Nir from a NirKind
- pub(crate) fn from_kind(v: NirKind) -> Nir {
+ pub fn from_kind(v: NirKind) -> Nir {
NirInternal::from_whnf(v).into_nir()
}
- pub(crate) fn from_const(c: Const) -> Self {
+ pub fn from_const(c: Const) -> Self {
let v = NirKind::Const(c);
NirInternal::from_whnf(v).into_nir()
}
- pub(crate) fn from_builtin(b: Builtin) -> Self {
+ pub fn from_builtin(b: Builtin) -> Self {
Self::from_builtin_env(b, &NzEnv::new())
}
- pub(crate) fn from_builtin_env(b: Builtin, env: &NzEnv) -> Self {
+ pub fn from_builtin_env(b: Builtin, env: &NzEnv) -> Self {
Nir::from_kind(NirKind::from_builtin_env(b, env.clone()))
}
- pub(crate) fn from_text(txt: impl ToString) -> Self {
+ pub fn from_text(txt: impl ToString) -> Self {
Nir::from_kind(NirKind::TextLit(TextLit::from_text(txt.to_string())))
}
- pub(crate) fn as_const(&self) -> Option<Const> {
+ pub fn as_const(&self) -> Option<Const> {
match &*self.kind() {
NirKind::Const(c) => Some(*c),
_ => None,
@@ -128,26 +132,22 @@ impl Nir {
}
/// This is what you want if you want to pattern-match on the value.
- pub(crate) fn kind(&self) -> &NirKind {
+ pub fn kind(&self) -> &NirKind {
self.0.kind()
}
- pub(crate) fn to_type(&self, u: impl Into<Universe>) -> Type {
+ pub fn to_type(&self, u: impl Into<Universe>) -> Type {
Type::new(self.clone(), u.into())
}
/// Converts a value back to the corresponding AST expression.
- pub(crate) fn to_expr(&self, opts: ToExprOptions) -> NormalizedExpr {
+ pub fn to_expr(&self, opts: ToExprOptions) -> Expr {
self.to_hir_noenv().to_expr(opts)
}
- pub(crate) fn to_expr_tyenv(&self, tyenv: &TyEnv) -> NormalizedExpr {
+ pub fn to_expr_tyenv(&self, tyenv: &TyEnv) -> Expr {
self.to_hir(tyenv.as_varenv()).to_expr_tyenv(tyenv)
}
- pub(crate) fn normalize(&self) {
- self.0.normalize()
- }
-
- pub(crate) fn app(&self, v: Nir) -> Nir {
+ pub fn app(&self, v: Nir) -> Nir {
Nir::from_kind(apply_any(self.clone(), v))
}
@@ -188,12 +188,21 @@ impl Nir {
closure.to_hir(venv),
),
NirKind::Const(c) => ExprKind::Const(*c),
- NirKind::Lit(l) => ExprKind::Lit(l.clone()),
+ NirKind::BuiltinType(b) => ExprKind::Builtin(*b),
+ NirKind::Num(l) => ExprKind::Num(l.clone()),
+ NirKind::OptionalType(t) => ExprKind::App(
+ Nir::from_builtin(Builtin::Optional).to_hir(venv),
+ t.to_hir(venv),
+ ),
NirKind::EmptyOptionalLit(n) => ExprKind::App(
Nir::from_builtin(Builtin::OptionalNone).to_hir(venv),
n.to_hir(venv),
),
NirKind::NEOptionalLit(n) => ExprKind::SomeLit(n.to_hir(venv)),
+ NirKind::ListType(t) => ExprKind::App(
+ Nir::from_builtin(Builtin::List).to_hir(venv),
+ t.to_hir(venv),
+ ),
NirKind::EmptyListLit(n) => ExprKind::EmptyListLit(Hir::new(
HirKind::Expr(ExprKind::App(
Nir::from_builtin(Builtin::List).to_hir(venv),
@@ -274,75 +283,18 @@ impl NirInternal {
fn kind(&self) -> &NirKind {
&self.kind
}
- fn normalize(&self) {
- self.kind().normalize();
- }
}
impl NirKind {
- pub(crate) fn into_nir(self) -> Nir {
+ pub fn into_nir(self) -> Nir {
Nir::from_kind(self)
}
- pub(crate) fn normalize(&self) {
- match self {
- NirKind::Var(..) | NirKind::Const(_) | NirKind::Lit(_) => {}
-
- NirKind::EmptyOptionalLit(tth) | NirKind::EmptyListLit(tth) => {
- tth.normalize();
- }
-
- NirKind::NEOptionalLit(th) => {
- th.normalize();
- }
- NirKind::LamClosure { annot, closure, .. }
- | NirKind::PiClosure { annot, closure, .. } => {
- annot.normalize();
- closure.normalize();
- }
- NirKind::AppliedBuiltin(closure) => closure.normalize(),
- NirKind::NEListLit(elts) => {
- for x in elts.iter() {
- x.normalize();
- }
- }
- NirKind::RecordLit(kvs) => {
- for x in kvs.values() {
- x.normalize();
- }
- }
- NirKind::RecordType(kvs) => {
- for x in kvs.values() {
- x.normalize();
- }
- }
- NirKind::UnionType(kts) | NirKind::UnionConstructor(_, kts) => {
- for x in kts.values().flatten() {
- x.normalize();
- }
- }
- NirKind::UnionLit(_, v, kts) => {
- v.normalize();
- for x in kts.values().flatten() {
- x.normalize();
- }
- }
- NirKind::TextLit(tlit) => tlit.normalize(),
- NirKind::Equivalence(x, y) => {
- x.normalize();
- y.normalize();
- }
- NirKind::PartialExpr(e) => {
- e.map_ref(Nir::normalize);
- }
- }
- }
-
- pub(crate) fn from_builtin(b: Builtin) -> NirKind {
+ pub fn from_builtin(b: Builtin) -> NirKind {
NirKind::from_builtin_env(b, NzEnv::new())
}
- pub(crate) fn from_builtin_env(b: Builtin, env: NzEnv) -> NirKind {
- NirKind::AppliedBuiltin(BuiltinClosure::new(b, env))
+ pub fn from_builtin_env(b: Builtin, env: NzEnv) -> NirKind {
+ BuiltinClosure::new(b, env)
}
}
@@ -390,9 +342,6 @@ impl Closure {
}
}
- // TODO: somehow normalize the body. Might require to pass an env.
- pub fn normalize(&self) {}
-
/// Convert this closure to a Hir expression
pub fn to_hir(&self, venv: VarEnv) -> Hir {
self.apply_var(NzVar::new(venv.size()))
@@ -456,13 +405,6 @@ impl TextLit {
pub fn iter(&self) -> impl Iterator<Item = &InterpolatedTextContents<Nir>> {
self.0.iter()
}
- /// Normalize the contained values. This does not break the invariant because we have already
- /// ensured that no contained values normalize to a TextLit.
- pub fn normalize(&self) {
- for x in self.0.iter() {
- x.map_ref(Nir::normalize);
- }
- }
}
impl lazy::Eval<NirKind> for Thunk {
diff --git a/dhall/src/semantics/nze/normalize.rs b/dhall/src/semantics/nze/normalize.rs
index 79d55e8..570e106 100644
--- a/dhall/src/semantics/nze/normalize.rs
+++ b/dhall/src/semantics/nze/normalize.rs
@@ -2,14 +2,10 @@ use itertools::Itertools;
use std::collections::HashMap;
use crate::semantics::NzEnv;
-use crate::semantics::{
- Binder, BuiltinClosure, Closure, Hir, HirKind, Nir, NirKind, TextLit,
-};
-use crate::syntax::{
- BinOp, Builtin, ExprKind, InterpolatedTextContents, LitKind,
-};
+use crate::semantics::{Binder, Closure, Hir, HirKind, Nir, NirKind, TextLit};
+use crate::syntax::{BinOp, ExprKind, InterpolatedTextContents, NumKind};
-pub(crate) fn apply_any(f: Nir, a: Nir) -> NirKind {
+pub fn apply_any(f: Nir, a: Nir) -> NirKind {
match f.kind() {
NirKind::LamClosure { closure, .. } => closure.apply(a).kind().clone(),
NirKind::AppliedBuiltin(closure) => closure.apply(a),
@@ -20,7 +16,7 @@ pub(crate) fn apply_any(f: Nir, a: Nir) -> NirKind {
}
}
-pub(crate) fn squash_textlit(
+pub fn squash_textlit(
elts: impl Iterator<Item = InterpolatedTextContents<Nir>>,
) -> Vec<InterpolatedTextContents<Nir>> {
use std::mem::replace;
@@ -58,7 +54,7 @@ pub(crate) fn squash_textlit(
ret
}
-pub(crate) fn merge_maps<K, V, F>(
+pub fn merge_maps<K, V, F>(
map1: &HashMap<K, V>,
map2: &HashMap<K, V>,
mut f: F,
@@ -99,40 +95,40 @@ fn apply_binop<'a>(o: BinOp, x: &'a Nir, y: &'a Nir) -> Option<Ret<'a>> {
NaturalTimes, RecursiveRecordMerge, RecursiveRecordTypeMerge,
RightBiasedRecordMerge, TextAppend,
};
- use LitKind::{Bool, Natural};
- use NirKind::{EmptyListLit, Lit, NEListLit, RecordLit, RecordType};
+ use NirKind::{EmptyListLit, NEListLit, Num, RecordLit, RecordType};
+ use NumKind::{Bool, Natural};
Some(match (o, x.kind(), y.kind()) {
- (BoolAnd, Lit(Bool(true)), _) => Ret::NirRef(y),
- (BoolAnd, _, Lit(Bool(true))) => Ret::NirRef(x),
- (BoolAnd, Lit(Bool(false)), _) => Ret::NirKind(Lit(Bool(false))),
- (BoolAnd, _, Lit(Bool(false))) => Ret::NirKind(Lit(Bool(false))),
+ (BoolAnd, Num(Bool(true)), _) => Ret::NirRef(y),
+ (BoolAnd, _, Num(Bool(true))) => Ret::NirRef(x),
+ (BoolAnd, Num(Bool(false)), _) => Ret::NirKind(Num(Bool(false))),
+ (BoolAnd, _, Num(Bool(false))) => Ret::NirKind(Num(Bool(false))),
(BoolAnd, _, _) if x == y => Ret::NirRef(x),
- (BoolOr, Lit(Bool(true)), _) => Ret::NirKind(Lit(Bool(true))),
- (BoolOr, _, Lit(Bool(true))) => Ret::NirKind(Lit(Bool(true))),
- (BoolOr, Lit(Bool(false)), _) => Ret::NirRef(y),
- (BoolOr, _, Lit(Bool(false))) => Ret::NirRef(x),
+ (BoolOr, Num(Bool(true)), _) => Ret::NirKind(Num(Bool(true))),
+ (BoolOr, _, Num(Bool(true))) => Ret::NirKind(Num(Bool(true))),
+ (BoolOr, Num(Bool(false)), _) => Ret::NirRef(y),
+ (BoolOr, _, Num(Bool(false))) => Ret::NirRef(x),
(BoolOr, _, _) if x == y => Ret::NirRef(x),
- (BoolEQ, Lit(Bool(true)), _) => Ret::NirRef(y),
- (BoolEQ, _, Lit(Bool(true))) => Ret::NirRef(x),
- (BoolEQ, Lit(Bool(x)), Lit(Bool(y))) => Ret::NirKind(Lit(Bool(x == y))),
- (BoolEQ, _, _) if x == y => Ret::NirKind(Lit(Bool(true))),
- (BoolNE, Lit(Bool(false)), _) => Ret::NirRef(y),
- (BoolNE, _, Lit(Bool(false))) => Ret::NirRef(x),
- (BoolNE, Lit(Bool(x)), Lit(Bool(y))) => Ret::NirKind(Lit(Bool(x != y))),
- (BoolNE, _, _) if x == y => Ret::NirKind(Lit(Bool(false))),
+ (BoolEQ, Num(Bool(true)), _) => Ret::NirRef(y),
+ (BoolEQ, _, Num(Bool(true))) => Ret::NirRef(x),
+ (BoolEQ, Num(Bool(x)), Num(Bool(y))) => Ret::NirKind(Num(Bool(x == y))),
+ (BoolEQ, _, _) if x == y => Ret::NirKind(Num(Bool(true))),
+ (BoolNE, Num(Bool(false)), _) => Ret::NirRef(y),
+ (BoolNE, _, Num(Bool(false))) => Ret::NirRef(x),
+ (BoolNE, Num(Bool(x)), Num(Bool(y))) => Ret::NirKind(Num(Bool(x != y))),
+ (BoolNE, _, _) if x == y => Ret::NirKind(Num(Bool(false))),
- (NaturalPlus, Lit(Natural(0)), _) => Ret::NirRef(y),
- (NaturalPlus, _, Lit(Natural(0))) => Ret::NirRef(x),
- (NaturalPlus, Lit(Natural(x)), Lit(Natural(y))) => {
- Ret::NirKind(Lit(Natural(x + y)))
+ (NaturalPlus, Num(Natural(0)), _) => Ret::NirRef(y),
+ (NaturalPlus, _, Num(Natural(0))) => Ret::NirRef(x),
+ (NaturalPlus, Num(Natural(x)), Num(Natural(y))) => {
+ Ret::NirKind(Num(Natural(x + y)))
}
- (NaturalTimes, Lit(Natural(0)), _) => Ret::NirKind(Lit(Natural(0))),
- (NaturalTimes, _, Lit(Natural(0))) => Ret::NirKind(Lit(Natural(0))),
- (NaturalTimes, Lit(Natural(1)), _) => Ret::NirRef(y),
- (NaturalTimes, _, Lit(Natural(1))) => Ret::NirRef(x),
- (NaturalTimes, Lit(Natural(x)), Lit(Natural(y))) => {
- Ret::NirKind(Lit(Natural(x * y)))
+ (NaturalTimes, Num(Natural(0)), _) => Ret::NirKind(Num(Natural(0))),
+ (NaturalTimes, _, Num(Natural(0))) => Ret::NirKind(Num(Natural(0))),
+ (NaturalTimes, Num(Natural(1)), _) => Ret::NirRef(y),
+ (NaturalTimes, _, Num(Natural(1))) => Ret::NirRef(x),
+ (NaturalTimes, Num(Natural(x)), Num(Natural(y))) => {
+ Ret::NirKind(Num(Natural(x * y)))
}
(ListAppend, EmptyListLit(_), _) => Ret::NirRef(y),
@@ -211,13 +207,13 @@ fn apply_binop<'a>(o: BinOp, x: &'a Nir, y: &'a Nir) -> Option<Ret<'a>> {
}
#[allow(clippy::cognitive_complexity)]
-pub(crate) fn normalize_one_layer(expr: ExprKind<Nir>, env: &NzEnv) -> NirKind {
- use LitKind::Bool;
+pub fn normalize_one_layer(expr: ExprKind<Nir>, env: &NzEnv) -> NirKind {
use NirKind::{
- EmptyListLit, EmptyOptionalLit, Lit, NEListLit, NEOptionalLit,
+ EmptyListLit, EmptyOptionalLit, NEListLit, NEOptionalLit, Num,
PartialExpr, RecordLit, RecordType, UnionConstructor, UnionLit,
UnionType,
};
+ use NumKind::Bool;
let ret = match expr {
ExprKind::Import(..) | ExprKind::Completion(..) => {
@@ -235,15 +231,11 @@ pub(crate) fn normalize_one_layer(expr: ExprKind<Nir>, env: &NzEnv) -> NirKind {
ExprKind::Builtin(b) => Ret::Nir(Nir::from_builtin_env(b, env)),
ExprKind::Assert(_) => Ret::Expr(expr),
ExprKind::App(v, a) => Ret::Nir(v.app(a)),
- ExprKind::Lit(l) => Ret::NirKind(Lit(l)),
+ ExprKind::Num(l) => Ret::NirKind(Num(l)),
ExprKind::SomeLit(e) => Ret::NirKind(NEOptionalLit(e)),
ExprKind::EmptyListLit(t) => {
let arg = match t.kind() {
- NirKind::AppliedBuiltin(BuiltinClosure {
- b: Builtin::List,
- args,
- ..
- }) if args.len() == 1 => args[0].clone(),
+ NirKind::ListType(t) => t.clone(),
_ => panic!("internal type error"),
};
Ret::NirKind(NirKind::EmptyListLit(arg))
@@ -271,12 +263,12 @@ pub(crate) fn normalize_one_layer(expr: ExprKind<Nir>, env: &NzEnv) -> NirKind {
}
ExprKind::BoolIf(ref b, ref e1, ref e2) => {
match b.kind() {
- Lit(Bool(true)) => Ret::NirRef(e1),
- Lit(Bool(false)) => Ret::NirRef(e2),
+ Num(Bool(true)) => Ret::NirRef(e1),
+ Num(Bool(false)) => Ret::NirRef(e2),
_ => {
match (e1.kind(), e2.kind()) {
// Simplify `if b then True else False`
- (Lit(Bool(true)), Lit(Bool(false))) => Ret::NirRef(b),
+ (Num(Bool(true)), Num(Bool(false))) => Ret::NirRef(b),
_ if e1 == e2 => Ret::NirRef(e1),
_ => Ret::Expr(expr),
}
@@ -442,12 +434,8 @@ pub(crate) fn normalize_one_layer(expr: ExprKind<Nir>, env: &NzEnv) -> NirKind {
ExprKind::ToMap(ref v, ref annot) => match v.kind() {
RecordLit(kvs) if kvs.is_empty() => {
match annot.as_ref().map(|v| v.kind()) {
- Some(NirKind::AppliedBuiltin(BuiltinClosure {
- b: Builtin::List,
- args,
- ..
- })) if args.len() == 1 => {
- Ret::NirKind(EmptyListLit(args[0].clone()))
+ Some(NirKind::ListType(t)) => {
+ Ret::NirKind(EmptyListLit(t.clone()))
}
_ => Ret::Expr(expr),
}
@@ -476,7 +464,7 @@ pub(crate) fn normalize_one_layer(expr: ExprKind<Nir>, env: &NzEnv) -> NirKind {
}
/// Normalize Hir into WHNF
-pub(crate) fn normalize_hir_whnf(env: &NzEnv, hir: &Hir) -> NirKind {
+pub fn normalize_hir_whnf(env: &NzEnv, hir: &Hir) -> NirKind {
match hir.kind() {
HirKind::Var(var) => env.lookup_val(*var),
HirKind::Import(hir, _) => normalize_hir_whnf(env, hir),
diff --git a/dhall/src/semantics/nze/var.rs b/dhall/src/semantics/nze/var.rs
index 413c759..302dbb7 100644
--- a/dhall/src/semantics/nze/var.rs
+++ b/dhall/src/semantics/nze/var.rs
@@ -8,10 +8,10 @@ pub struct Binder {
}
impl Binder {
- pub(crate) fn new(name: Label) -> Self {
+ pub fn new(name: Label) -> Self {
Binder { name }
}
- pub(crate) fn to_label(&self) -> Label {
+ pub fn to_label(&self) -> Label {
self.clone().into()
}
}
diff --git a/dhall/src/semantics/parse.rs b/dhall/src/semantics/parse.rs
index 45860d0..2326471 100644
--- a/dhall/src/semantics/parse.rs
+++ b/dhall/src/semantics/parse.rs
@@ -9,33 +9,33 @@ use crate::syntax::binary;
use crate::syntax::parse_expr;
use crate::Parsed;
-pub(crate) fn parse_file(f: &Path) -> Result<Parsed, Error> {
+pub fn parse_file(f: &Path) -> Result<Parsed, Error> {
let text = std::fs::read_to_string(f)?;
let expr = parse_expr(&text)?;
let root = ImportLocation::Local(f.to_owned());
Ok(Parsed(expr, root))
}
-pub(crate) fn parse_remote(url: Url) -> Result<Parsed, Error> {
+pub fn parse_remote(url: Url) -> Result<Parsed, Error> {
let body = reqwest::blocking::get(url.clone()).unwrap().text().unwrap();
let expr = parse_expr(&body)?;
let root = ImportLocation::Remote(url);
Ok(Parsed(expr, root))
}
-pub(crate) fn parse_str(s: &str) -> Result<Parsed, Error> {
+pub fn parse_str(s: &str) -> Result<Parsed, Error> {
let expr = parse_expr(s)?;
let root = ImportLocation::Missing;
Ok(Parsed(expr, root))
}
-pub(crate) fn parse_binary(data: &[u8]) -> Result<Parsed, Error> {
+pub fn parse_binary(data: &[u8]) -> Result<Parsed, Error> {
let expr = binary::decode(data)?;
let root = ImportLocation::Missing;
Ok(Parsed(expr, root))
}
-pub(crate) fn parse_binary_file(f: &Path) -> Result<Parsed, Error> {
+pub fn parse_binary_file(f: &Path) -> Result<Parsed, Error> {
let mut buffer = Vec::new();
File::open(f)?.read_to_end(&mut buffer)?;
let expr = binary::decode(&buffer)?;
diff --git a/dhall/src/semantics/resolve/env.rs b/dhall/src/semantics/resolve/env.rs
index fe8c178..d7ff0ae 100644
--- a/dhall/src/semantics/resolve/env.rs
+++ b/dhall/src/semantics/resolve/env.rs
@@ -5,24 +5,24 @@ use crate::semantics::{AlphaVar, ImportLocation, TypedHir, VarEnv};
use crate::syntax::{Label, V};
/// Environment for resolving names.
-#[derive(Debug, Clone)]
-pub(crate) struct NameEnv {
+#[derive(Debug, Clone, Default)]
+pub struct NameEnv {
names: Vec<Label>,
}
-pub(crate) type ImportCache = HashMap<ImportLocation, TypedHir>;
-pub(crate) type ImportStack = Vec<ImportLocation>;
+pub type ImportCache = HashMap<ImportLocation, TypedHir>;
+pub type ImportStack = Vec<ImportLocation>;
/// Environment for resolving imports
-#[derive(Debug, Clone)]
-pub(crate) struct ImportEnv {
+#[derive(Debug, Clone, Default)]
+pub struct ImportEnv {
cache: ImportCache,
stack: ImportStack,
}
impl NameEnv {
pub fn new() -> Self {
- NameEnv { names: Vec::new() }
+ NameEnv::default()
}
pub fn as_varenv(&self) -> VarEnv {
VarEnv::from_size(self.names.len())
@@ -66,10 +66,7 @@ impl NameEnv {
impl ImportEnv {
pub fn new() -> Self {
- ImportEnv {
- cache: HashMap::new(),
- stack: Vec::new(),
- }
+ ImportEnv::default()
}
pub fn handle_import(
diff --git a/dhall/src/semantics/resolve/hir.rs b/dhall/src/semantics/resolve/hir.rs
index fa2989f..9256425 100644
--- a/dhall/src/semantics/resolve/hir.rs
+++ b/dhall/src/semantics/resolve/hir.rs
@@ -1,7 +1,7 @@
use crate::error::TypeError;
use crate::semantics::{type_with, NameEnv, Nir, NzEnv, Tir, TyEnv, Type};
use crate::syntax::{Expr, ExprKind, Span, V};
-use crate::{NormalizedExpr, ToExprOptions};
+use crate::ToExprOptions;
/// Stores an alpha-normalized variable.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -10,7 +10,7 @@ pub struct AlphaVar {
}
#[derive(Debug, Clone, PartialEq, Eq)]
-pub(crate) enum HirKind {
+pub enum HirKind {
/// A resolved variable (i.e. a DeBruijn index)
Var(AlphaVar),
/// Result of resolving an import.
@@ -21,16 +21,16 @@ pub(crate) enum HirKind {
// An expression with resolved variables and imports.
#[derive(Debug, Clone)]
-pub(crate) struct Hir {
+pub struct Hir {
kind: Box<HirKind>,
span: Span,
}
impl AlphaVar {
- pub(crate) fn new(idx: usize) -> Self {
+ pub fn new(idx: usize) -> Self {
AlphaVar { idx }
}
- pub(crate) fn idx(self) -> usize {
+ pub fn idx(self) -> usize {
self.idx
}
}
@@ -51,15 +51,15 @@ impl Hir {
}
/// Converts a closed Hir expr back to the corresponding AST expression.
- pub fn to_expr(&self, opts: ToExprOptions) -> NormalizedExpr {
+ pub fn to_expr(&self, opts: ToExprOptions) -> Expr {
hir_to_expr(self, opts, &mut NameEnv::new())
}
/// Converts a closed Hir expr back to the corresponding AST expression.
- pub fn to_expr_noopts(&self) -> NormalizedExpr {
+ pub fn to_expr_noopts(&self) -> Expr {
let opts = ToExprOptions { alpha: false };
self.to_expr(opts)
}
- pub fn to_expr_tyenv(&self, env: &TyEnv) -> NormalizedExpr {
+ pub fn to_expr_tyenv(&self, env: &TyEnv) -> Expr {
let opts = ToExprOptions { alpha: false };
let mut env = env.as_nameenv().clone();
hir_to_expr(self, opts, &mut env)
@@ -85,19 +85,9 @@ impl Hir {
pub fn eval_closed_expr(&self) -> Nir {
self.eval(NzEnv::new())
}
- /// Eval a closed Hir fully and recursively;
- pub fn rec_eval_closed_expr(&self) -> Nir {
- let val = self.eval_closed_expr();
- val.normalize();
- val
- }
}
-fn hir_to_expr(
- hir: &Hir,
- opts: ToExprOptions,
- env: &mut NameEnv,
-) -> NormalizedExpr {
+fn hir_to_expr(hir: &Hir, opts: ToExprOptions, env: &mut NameEnv) -> Expr {
let kind = match hir.kind() {
HirKind::Var(v) if opts.alpha => ExprKind::Var(V("_".into(), v.idx())),
HirKind::Var(v) => ExprKind::Var(env.label_var(*v)),
diff --git a/dhall/src/semantics/resolve/mod.rs b/dhall/src/semantics/resolve/mod.rs
index 517907b..33b477e 100644
--- a/dhall/src/semantics/resolve/mod.rs
+++ b/dhall/src/semantics/resolve/mod.rs
@@ -1,6 +1,6 @@
pub mod env;
pub mod hir;
pub mod resolve;
-pub(crate) use env::*;
-pub(crate) use hir::*;
-pub(crate) use resolve::*;
+pub use env::*;
+pub use hir::*;
+pub use resolve::*;
diff --git a/dhall/src/semantics/resolve/resolve.rs b/dhall/src/semantics/resolve/resolve.rs
index f3fda4b..7745e0b 100644
--- a/dhall/src/semantics/resolve/resolve.rs
+++ b/dhall/src/semantics/resolve/resolve.rs
@@ -13,17 +13,17 @@ use crate::syntax::{
BinOp, Builtin, Expr, ExprKind, FilePath, FilePrefix, ImportMode,
ImportTarget, Span, UnspannedExpr, URL,
};
-use crate::{Parsed, ParsedExpr, Resolved};
+use crate::{Parsed, Resolved};
// TODO: evaluate import headers
-pub(crate) type Import = syntax::Import<()>;
+pub type Import = syntax::Import<()>;
/// Owned Hir with a type. Different from Tir because the Hir is owned.
-pub(crate) type TypedHir = (Hir, Type);
+pub type TypedHir = (Hir, Type);
/// The location of some data, usually some dhall code.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub(crate) enum ImportLocation {
+pub enum ImportLocation {
/// Local file
Local(PathBuf),
/// Remote file
@@ -227,7 +227,7 @@ fn resolve_one_import(
}
ImportMode::Location => {
let expr = location.into_location();
- let hir = skip_resolve(&expr)?;
+ let hir = skip_resolve_expr(&expr)?;
let ty = hir.typecheck_noenv()?.ty().clone();
Ok((hir, ty))
}
@@ -329,16 +329,22 @@ fn resolve_with_env(
Ok(Resolved(resolved))
}
-pub(crate) fn resolve(parsed: Parsed) -> Result<Resolved, Error> {
+pub fn resolve(parsed: Parsed) -> Result<Resolved, Error> {
resolve_with_env(&mut ImportEnv::new(), parsed)
}
-pub(crate) fn skip_resolve(expr: &ParsedExpr) -> Result<Hir, Error> {
+pub fn skip_resolve_expr(expr: &Expr) -> Result<Hir, Error> {
traverse_resolve_expr(&mut NameEnv::new(), expr, &mut |import| {
Err(ImportError::UnexpectedImport(import).into())
})
}
+pub fn skip_resolve(parsed: Parsed) -> Result<Resolved, Error> {
+ let Parsed(expr, _) = parsed;
+ let resolved = skip_resolve_expr(&expr)?;
+ Ok(Resolved(resolved))
+}
+
pub trait Canonicalize {
fn canonicalize(&self) -> Self;
}
diff --git a/dhall/src/semantics/tck/env.rs b/dhall/src/semantics/tck/env.rs
index 6dd5076..1fa66f0 100644
--- a/dhall/src/semantics/tck/env.rs
+++ b/dhall/src/semantics/tck/env.rs
@@ -2,21 +2,21 @@ use crate::semantics::{AlphaVar, NameEnv, Nir, NzEnv, NzVar, Type, ValEnv};
use crate::syntax::Label;
/// Environment for indexing variables.
-#[derive(Debug, Clone, Copy)]
-pub(crate) struct VarEnv {
+#[derive(Debug, Clone, Copy, Default)]
+pub struct VarEnv {
size: usize,
}
/// Environment for typing expressions.
#[derive(Debug, Clone)]
-pub(crate) struct TyEnv {
+pub struct TyEnv {
names: NameEnv,
items: ValEnv<Type>,
}
impl VarEnv {
pub fn new() -> Self {
- VarEnv { size: 0 }
+ VarEnv::default()
}
pub fn from_size(size: usize) -> Self {
VarEnv { size }
diff --git a/dhall/src/semantics/tck/mod.rs b/dhall/src/semantics/tck/mod.rs
index 93c8f48..6dddfc5 100644
--- a/dhall/src/semantics/tck/mod.rs
+++ b/dhall/src/semantics/tck/mod.rs
@@ -1,6 +1,6 @@
pub mod env;
pub mod tir;
pub mod typecheck;
-pub(crate) use env::*;
-pub(crate) use tir::*;
-pub(crate) use typecheck::*;
+pub use env::*;
+pub use tir::*;
+pub use typecheck::*;
diff --git a/dhall/src/semantics/tck/tir.rs b/dhall/src/semantics/tck/tir.rs
index aeb7bf9..89a8027 100644
--- a/dhall/src/semantics/tck/tir.rs
+++ b/dhall/src/semantics/tck/tir.rs
@@ -1,15 +1,14 @@
use crate::error::{ErrorBuilder, TypeError};
use crate::semantics::{mkerr, Hir, Nir, NirKind, NzEnv, TyEnv, VarEnv};
-use crate::syntax::{Builtin, Const, Span};
-use crate::NormalizedExpr;
+use crate::syntax::{Builtin, Const, Expr, Span};
/// The type of a type. 0 is `Type`, 1 is `Kind`, etc...
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Default)]
-pub(crate) struct Universe(u8);
+pub struct Universe(u8);
/// An expression representing a type
#[derive(Debug, Clone, PartialEq, Eq)]
-pub(crate) struct Type {
+pub struct Type {
val: Nir,
univ: Universe,
}
@@ -17,7 +16,7 @@ pub(crate) struct Type {
/// A hir expression plus its inferred type.
/// Stands for "Typed intermediate representation"
#[derive(Debug, Clone)]
-pub(crate) struct Tir<'hir> {
+pub struct Tir<'hir> {
hir: &'hir Hir,
ty: Type,
}
@@ -101,7 +100,7 @@ impl Type {
pub fn to_hir(&self, venv: VarEnv) -> Hir {
self.val.to_hir(venv)
}
- pub fn to_expr_tyenv(&self, tyenv: &TyEnv) -> NormalizedExpr {
+ pub fn to_expr_tyenv(&self, tyenv: &TyEnv) -> Expr {
self.val.to_hir(tyenv.as_varenv()).to_expr_tyenv(tyenv)
}
}
@@ -124,7 +123,7 @@ impl<'hir> Tir<'hir> {
pub fn as_hir(&self) -> &Hir {
&self.hir
}
- pub fn to_expr_tyenv(&self, env: &TyEnv) -> NormalizedExpr {
+ pub fn to_expr_tyenv(&self, env: &TyEnv) -> Expr {
self.as_hir().to_expr_tyenv(env)
}
diff --git a/dhall/src/semantics/tck/typecheck.rs b/dhall/src/semantics/tck/typecheck.rs
index 173b76d..c3334b5 100644
--- a/dhall/src/semantics/tck/typecheck.rs
+++ b/dhall/src/semantics/tck/typecheck.rs
@@ -5,11 +5,11 @@ use std::collections::HashMap;
use crate::error::{ErrorBuilder, TypeError, TypeMessage};
use crate::semantics::merge_maps;
use crate::semantics::{
- type_of_builtin, Binder, BuiltinClosure, Closure, Hir, HirKind, Nir,
- NirKind, Tir, TyEnv, Type,
+ type_of_builtin, Binder, Closure, Hir, HirKind, Nir, NirKind, Tir, TyEnv,
+ Type,
};
use crate::syntax::{
- BinOp, Builtin, Const, ExprKind, InterpolatedTextContents, LitKind, Span,
+ BinOp, Builtin, Const, ExprKind, InterpolatedTextContents, NumKind, Span,
};
fn check_rectymerge(
@@ -53,14 +53,11 @@ fn function_check(a: Const, b: Const) -> Const {
}
}
-pub(crate) fn mkerr<T, S: ToString>(msg: S) -> Result<T, TypeError> {
+pub fn mkerr<T, S: ToString>(msg: S) -> Result<T, TypeError> {
Err(TypeError::new(TypeMessage::Custom(msg.to_string())))
}
-pub(crate) fn mk_span_err<T, S: ToString>(
- span: Span,
- msg: S,
-) -> Result<T, TypeError> {
+pub fn mk_span_err<T, S: ToString>(span: Span, msg: S) -> Result<T, TypeError> {
mkerr(
ErrorBuilder::new(msg.to_string())
.span_err(span, msg.to_string())
@@ -96,14 +93,14 @@ fn type_one_layer(
let t_hir = type_of_builtin(*b);
typecheck(&t_hir)?.eval_to_type(env)?
}
- ExprKind::Lit(LitKind::Bool(_)) => Type::from_builtin(Builtin::Bool),
- ExprKind::Lit(LitKind::Natural(_)) => {
+ ExprKind::Num(NumKind::Bool(_)) => Type::from_builtin(Builtin::Bool),
+ ExprKind::Num(NumKind::Natural(_)) => {
Type::from_builtin(Builtin::Natural)
}
- ExprKind::Lit(LitKind::Integer(_)) => {
+ ExprKind::Num(NumKind::Integer(_)) => {
Type::from_builtin(Builtin::Integer)
}
- ExprKind::Lit(LitKind::Double(_)) => {
+ ExprKind::Num(NumKind::Double(_)) => {
Type::from_builtin(Builtin::Double)
}
ExprKind::TextLit(interpolated) => {
@@ -121,11 +118,7 @@ fn type_one_layer(
ExprKind::EmptyListLit(t) => {
let t = t.eval_to_type(env)?;
match t.kind() {
- NirKind::AppliedBuiltin(BuiltinClosure {
- b: Builtin::List,
- args,
- ..
- }) if args.len() == 1 => {}
+ NirKind::ListType(..) => {}
_ => return span_err("InvalidListType"),
};
t
@@ -376,10 +369,7 @@ fn type_one_layer(
}
ExprKind::BinOp(BinOp::ListAppend, l, r) => {
match l.ty().kind() {
- NirKind::AppliedBuiltin(BuiltinClosure {
- b: Builtin::List,
- ..
- }) => {}
+ NirKind::ListType(..) => {}
_ => return span_err("BinOpTypeMismatch"),
}
@@ -435,12 +425,7 @@ fn type_one_layer(
let union_type = union.ty();
let variants = match union_type.kind() {
NirKind::UnionType(kts) => Cow::Borrowed(kts),
- NirKind::AppliedBuiltin(BuiltinClosure {
- b: Builtin::Optional,
- args,
- ..
- }) if args.len() == 1 => {
- let ty = &args[0];
+ NirKind::OptionalType(ty) => {
let mut kts = HashMap::new();
kts.insert("None".into(), None);
kts.insert("Some".into(), Some(ty.clone()));
@@ -595,11 +580,7 @@ fn type_one_layer(
let err_msg = "The type of `toMap x` must be of the form \
`List { mapKey : Text, mapValue : T }`";
let arg = match annot_val.kind() {
- NirKind::AppliedBuiltin(BuiltinClosure {
- b: Builtin::List,
- args,
- ..
- }) if args.len() == 1 => &args[0],
+ NirKind::ListType(t) => t,
_ => return span_err(err_msg),
};
let kts = match arg.kind() {
@@ -704,7 +685,7 @@ fn type_one_layer(
/// `type_with` typechecks an expression in the provided environment. Optionally pass an annotation
/// to compare with.
-pub(crate) fn type_with<'hir>(
+pub fn type_with<'hir>(
env: &TyEnv,
hir: &'hir Hir,
annot: Option<Type>,
@@ -801,15 +782,15 @@ pub(crate) fn type_with<'hir>(
/// Typecheck an expression and return the expression annotated with types if type-checking
/// succeeded, or an error if type-checking failed.
-pub(crate) fn typecheck<'hir>(hir: &'hir Hir) -> Result<Tir<'hir>, TypeError> {
+pub fn typecheck<'hir>(hir: &'hir Hir) -> Result<Tir<'hir>, TypeError> {
type_with(&TyEnv::new(), hir, None)
}
/// Like `typecheck`, but additionally checks that the expression's type matches the provided type.
-pub(crate) fn typecheck_with<'hir>(
+pub fn typecheck_with<'hir>(
hir: &'hir Hir,
- ty: Hir,
+ ty: &Hir,
) -> Result<Tir<'hir>, TypeError> {
- let ty = typecheck(&ty)?.eval_to_type(&TyEnv::new())?;
+ let ty = typecheck(ty)?.eval_to_type(&TyEnv::new())?;
type_with(&TyEnv::new(), hir, Some(ty))
}
diff --git a/dhall/src/syntax/ast/expr.rs b/dhall/src/syntax/ast/expr.rs
index b53e6cb..6ba6649 100644
--- a/dhall/src/syntax/ast/expr.rs
+++ b/dhall/src/syntax/ast/expr.rs
@@ -22,7 +22,7 @@ pub enum Const {
}
impl Const {
- pub(crate) fn to_universe(self) -> Universe {
+ pub fn to_universe(self) -> Universe {
Universe::from_const(self)
}
}
@@ -112,9 +112,9 @@ pub struct Expr {
pub type UnspannedExpr = ExprKind<Expr>;
-/// Simple literals
+/// Numeric literals
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub enum LitKind {
+pub enum NumKind {
/// `True`
Bool(bool),
/// `1`
@@ -132,7 +132,7 @@ pub enum LitKind {
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum ExprKind<SubExpr> {
Const(Const),
- Lit(LitKind),
+ Num(NumKind),
/// `x`
/// `x@n`
Var(V),
@@ -205,7 +205,7 @@ impl<SE> ExprKind<SE> {
})
}
- pub(crate) fn traverse_ref<'a, SE2, Err>(
+ pub fn traverse_ref<'a, SE2, Err>(
&'a self,
mut visit_subexpr: impl FnMut(&'a SE) -> Result<SE2, Err>,
) -> Result<ExprKind<SE2>, Err> {
@@ -239,17 +239,17 @@ impl<SE> ExprKind<SE> {
}
impl Expr {
- pub(crate) fn as_ref(&self) -> &UnspannedExpr {
+ pub fn as_ref(&self) -> &UnspannedExpr {
&self.kind
}
pub fn kind(&self) -> &UnspannedExpr {
&self.kind
}
- pub(crate) fn span(&self) -> Span {
+ pub fn span(&self) -> Span {
self.span.clone()
}
- pub(crate) fn new(kind: UnspannedExpr, span: Span) -> Self {
+ pub fn new(kind: UnspannedExpr, span: Span) -> Self {
Expr {
kind: Box::new(kind),
span,
diff --git a/dhall/src/syntax/ast/mod.rs b/dhall/src/syntax/ast/mod.rs
index 5e20c5d..1950154 100644
--- a/dhall/src/syntax/ast/mod.rs
+++ b/dhall/src/syntax/ast/mod.rs
@@ -5,7 +5,7 @@ pub use import::*;
mod label;
pub use label::*;
mod span;
-pub(crate) use span::*;
+pub use span::*;
mod text;
pub use text::*;
pub mod map;
diff --git a/dhall/src/syntax/ast/span.rs b/dhall/src/syntax/ast/span.rs
index 2e09863..e250602 100644
--- a/dhall/src/syntax/ast/span.rs
+++ b/dhall/src/syntax/ast/span.rs
@@ -2,7 +2,7 @@ use std::rc::Rc;
/// A location in the source text
#[derive(Debug, Clone)]
-pub(crate) struct ParsedSpan {
+pub struct ParsedSpan {
input: Rc<str>,
/// # Safety
///
@@ -15,7 +15,7 @@ pub(crate) struct ParsedSpan {
}
#[derive(Debug, Clone)]
-pub(crate) enum Span {
+pub enum Span {
/// A location in the source text
Parsed(ParsedSpan),
/// Desugarings
@@ -30,12 +30,12 @@ pub(crate) enum Span {
}
impl ParsedSpan {
- pub(crate) fn to_input(&self) -> String {
+ pub fn to_input(&self) -> String {
self.input.to_string()
}
/// Convert to a char range for consumption by annotate_snippets.
/// This compensates for https://github.com/rust-lang/annotate-snippets-rs/issues/24
- pub(crate) fn as_char_range(&self) -> (usize, usize) {
+ pub fn as_char_range(&self) -> (usize, usize) {
(
char_idx_from_byte_idx(&self.input, self.start),
char_idx_from_byte_idx(&self.input, self.end),
@@ -44,7 +44,7 @@ impl ParsedSpan {
}
impl Span {
- pub(crate) fn make(input: Rc<str>, sp: pest::Span) -> Self {
+ pub fn make(input: Rc<str>, sp: pest::Span) -> Self {
Span::Parsed(ParsedSpan {
input,
start: sp.start(),
@@ -55,7 +55,7 @@ impl Span {
/// Takes the union of the two spans, i.e. the range of input covered by the two spans plus any
/// input between them. Assumes that the spans come from the same input. Fails if one of the
/// spans does not point to an input location.
- pub(crate) fn union(&self, other: &Span) -> Self {
+ pub fn union(&self, other: &Span) -> Self {
use std::cmp::{max, min};
use Span::*;
match (self, other) {
diff --git a/dhall/src/syntax/ast/visitor.rs b/dhall/src/syntax/ast/visitor.rs
index c361bc1..0a0c5ef 100644
--- a/dhall/src/syntax/ast/visitor.rs
+++ b/dhall/src/syntax/ast/visitor.rs
@@ -51,7 +51,7 @@ where
.collect()
}
-pub(crate) fn visit_ref<'a, F, SE1, SE2, Err>(
+pub fn visit_ref<'a, F, SE1, SE2, Err>(
input: &'a ExprKind<SE1>,
mut f: F,
) -> Result<ExprKind<SE2>, Err>
@@ -91,7 +91,7 @@ where
Annot(x, t) => Annot(expr!(x)?, expr!(t)?),
Const(k) => Const(*k),
Builtin(v) => Builtin(*v),
- Lit(l) => Lit(l.clone()),
+ Num(n) => Num(n.clone()),
TextLit(t) => TextLit(t.traverse_ref(|e| expr!(e))?),
BinOp(o, x, y) => BinOp(*o, expr!(x)?, expr!(y)?),
BoolIf(b, t, f) => BoolIf(expr!(b)?, expr!(t)?, expr!(f)?),
diff --git a/dhall/src/syntax/binary/decode.rs b/dhall/src/syntax/binary/decode.rs
index 2ecd7e0..3c93419 100644
--- a/dhall/src/syntax/binary/decode.rs
+++ b/dhall/src/syntax/binary/decode.rs
@@ -6,12 +6,12 @@ use crate::error::DecodeError;
use crate::syntax;
use crate::syntax::{
Expr, ExprKind, FilePath, FilePrefix, Hash, ImportMode, ImportTarget,
- Integer, InterpolatedText, Label, LitKind, Natural, Scheme, Span,
+ Integer, InterpolatedText, Label, Natural, NumKind, Scheme, Span,
UnspannedExpr, URL, V,
};
-use crate::DecodedExpr;
+type DecodedExpr = Expr;
-pub(crate) fn decode(data: &[u8]) -> Result<DecodedExpr, DecodeError> {
+pub fn decode(data: &[u8]) -> Result<DecodedExpr, DecodeError> {
match serde_cbor::de::from_slice(data) {
Ok(v) => cbor_value_to_dhall(&v),
Err(e) => Err(DecodeError::CBORError(e)),
@@ -31,8 +31,8 @@ fn cbor_value_to_dhall(data: &cbor::Value) -> Result<DecodedExpr, DecodeError> {
String(s) => match Builtin::parse(s) {
Some(b) => ExprKind::Builtin(b),
None => match s.as_str() {
- "True" => Lit(LitKind::Bool(true)),
- "False" => Lit(LitKind::Bool(false)),
+ "True" => Num(NumKind::Bool(true)),
+ "False" => Num(NumKind::Bool(false)),
"Type" => Const(Const::Type),
"Kind" => Const(Const::Kind),
"Sort" => Const(Const::Sort),
@@ -44,8 +44,8 @@ fn cbor_value_to_dhall(data: &cbor::Value) -> Result<DecodedExpr, DecodeError> {
},
},
U64(n) => Var(V(Label::from("_"), *n as usize)),
- F64(x) => Lit(LitKind::Double((*x).into())),
- Bool(b) => Lit(LitKind::Bool(*b)),
+ F64(x) => Num(NumKind::Double((*x).into())),
+ Bool(b) => Num(NumKind::Bool(*b)),
Array(vec) => match vec.as_slice() {
[String(l), U64(n)] => {
if l.as_str() == "_" {
@@ -224,9 +224,9 @@ fn cbor_value_to_dhall(data: &cbor::Value) -> Result<DecodedExpr, DecodeError> {
let z = cbor_value_to_dhall(&z)?;
BoolIf(x, y, z)
}
- [U64(15), U64(x)] => Lit(LitKind::Natural(*x as Natural)),
- [U64(16), U64(x)] => Lit(LitKind::Integer(*x as Integer)),
- [U64(16), I64(x)] => Lit(LitKind::Integer(*x as Integer)),
+ [U64(15), U64(x)] => Num(NumKind::Natural(*x as Natural)),
+ [U64(16), U64(x)] => Num(NumKind::Integer(*x as Integer)),
+ [U64(16), I64(x)] => Num(NumKind::Integer(*x as Integer)),
[U64(18), String(first), rest @ ..] => {
TextLit(InterpolatedText::from((
first.clone(),
diff --git a/dhall/src/syntax/binary/encode.rs b/dhall/src/syntax/binary/encode.rs
index 9e6948e..8d22a9b 100644
--- a/dhall/src/syntax/binary/encode.rs
+++ b/dhall/src/syntax/binary/encode.rs
@@ -10,7 +10,7 @@ use crate::syntax::{
Scheme, V,
};
-pub(crate) fn encode(expr: &Expr) -> Result<Vec<u8>, EncodeError> {
+pub fn encode(expr: &Expr) -> Result<Vec<u8>, EncodeError> {
serde_cbor::ser::to_vec(&Serialize::Expr(expr))
.map_err(EncodeError::CBORError)
}
@@ -48,7 +48,7 @@ where
use std::iter::once;
use syntax::Builtin;
use syntax::ExprKind::*;
- use syntax::LitKind::*;
+ use syntax::NumKind::*;
use self::Serialize::{RecordDupMap, RecordMap, UnionMap};
fn expr(x: &Expr) -> self::Serialize<'_> {
@@ -63,10 +63,10 @@ where
match e.as_ref() {
Const(c) => ser.serialize_str(&c.to_string()),
Builtin(b) => ser.serialize_str(&b.to_string()),
- Lit(Bool(b)) => ser.serialize_bool(*b),
- Lit(Natural(n)) => ser_seq!(ser; tag(15), U64(*n as u64)),
- Lit(Integer(n)) => ser_seq!(ser; tag(16), I64(*n as i64)),
- Lit(Double(n)) => {
+ Num(Bool(b)) => ser.serialize_bool(*b),
+ Num(Natural(n)) => ser_seq!(ser; tag(15), U64(*n as u64)),
+ Num(Integer(n)) => ser_seq!(ser; tag(16), I64(*n as i64)),
+ Num(Double(n)) => {
let n: f64 = (*n).into();
ser.serialize_f64(n)
}
diff --git a/dhall/src/syntax/binary/mod.rs b/dhall/src/syntax/binary/mod.rs
index 7ed1f6e..98e0520 100644
--- a/dhall/src/syntax/binary/mod.rs
+++ b/dhall/src/syntax/binary/mod.rs
@@ -1,4 +1,4 @@
mod decode;
mod encode;
-pub(crate) use decode::decode;
-pub(crate) use encode::encode;
+pub use decode::decode;
+pub use encode::encode;
diff --git a/dhall/src/syntax/text/parser.rs b/dhall/src/syntax/text/parser.rs
index 03211c7..6f5949f 100644
--- a/dhall/src/syntax/text/parser.rs
+++ b/dhall/src/syntax/text/parser.rs
@@ -9,7 +9,7 @@ use pest_consume::{match_nodes, Parser};
use crate::syntax::map::{DupTreeMap, DupTreeSet};
use crate::syntax::ExprKind::*;
-use crate::syntax::LitKind::*;
+use crate::syntax::NumKind::*;
use crate::syntax::{
Double, Expr, FilePath, FilePrefix, Hash, ImportMode, ImportTarget,
Integer, InterpolatedText, InterpolatedTextContents, Label, NaiveDouble,
@@ -135,7 +135,7 @@ fn insert_recordlit_entry(map: &mut BTreeMap<Label, Expr>, l: Label, e: Expr) {
entry.insert(e);
}
Entry::Occupied(mut entry) => {
- let dummy = Expr::new(Lit(Bool(false)), Span::Artificial);
+ let dummy = Expr::new(Num(Bool(false)), Span::Artificial);
let other = entry.insert(dummy);
entry.insert(Expr::new(
BinOp(RecursiveRecordMerge, other, e),
@@ -390,8 +390,8 @@ impl DhallParser {
let e = match crate::syntax::Builtin::parse(s) {
Some(b) => Builtin(b),
None => match s {
- "True" => Lit(Bool(true)),
- "False" => Lit(Bool(false)),
+ "True" => Num(Bool(true)),
+ "False" => Num(Bool(false)),
"Type" => Const(crate::syntax::Const::Type),
"Kind" => Const(crate::syntax::Const::Kind),
"Sort" => Const(crate::syntax::Const::Sort),
@@ -924,9 +924,9 @@ impl DhallParser {
#[alias(expression, shortcut = true)]
fn primitive_expression(input: ParseInput) -> ParseResult<Expr> {
Ok(match_nodes!(input.children();
- [double_literal(n)] => spanned(input, Lit(Double(n))),
- [natural_literal(n)] => spanned(input, Lit(Natural(n))),
- [integer_literal(n)] => spanned(input, Lit(Integer(n))),
+ [double_literal(n)] => spanned(input, Num(Double(n))),
+ [natural_literal(n)] => spanned(input, Num(Natural(n))),
+ [integer_literal(n)] => spanned(input, Num(Integer(n))),
[double_quote_literal(s)] => spanned(input, TextLit(s)),
[single_quote_literal(s)] => spanned(input, TextLit(s)),
[record_type_or_literal(e)] => spanned(input, e),
diff --git a/dhall/src/syntax/text/printer.rs b/dhall/src/syntax/text/printer.rs
index 2b7bc2e..378f408 100644
--- a/dhall/src/syntax/text/printer.rs
+++ b/dhall/src/syntax/text/printer.rs
@@ -201,7 +201,7 @@ impl<SE: Display + Clone> Display for ExprKind<SE> {
Var(a) => a.fmt(f)?,
Const(k) => k.fmt(f)?,
Builtin(v) => v.fmt(f)?,
- Lit(a) => a.fmt(f)?,
+ Num(a) => a.fmt(f)?,
TextLit(a) => a.fmt(f)?,
RecordType(a) if a.is_empty() => f.write_str("{}")?,
RecordType(a) => fmt_list("{ ", ", ", " }", a, f, |(k, t), f| {
@@ -240,9 +240,9 @@ impl Display for Expr {
}
}
-impl Display for LitKind {
+impl Display for NumKind {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
- use LitKind::*;
+ use NumKind::*;
match self {
Bool(true) => f.write_str("True")?,
Bool(false) => f.write_str("False")?,
diff --git a/dhall/src/tests.rs b/dhall/src/tests.rs
index a5a278c..2cd354f 100644
--- a/dhall/src/tests.rs
+++ b/dhall/src/tests.rs
@@ -10,8 +10,8 @@ use std::io::{Read, Write};
use std::path::PathBuf;
use crate::error::{ErrorKind, Result};
-use crate::syntax::binary;
-use crate::{Normalized, NormalizedExpr, Parsed, Resolved, Typed};
+use crate::syntax::{binary, Expr};
+use crate::{Normalized, Parsed, Resolved, Typed};
macro_rules! assert_eq_display {
($left:expr, $right:expr) => {{
@@ -111,7 +111,7 @@ impl TestFile {
env::var("UPDATE_TEST_FILES") == Ok("1".to_string())
}
/// Write the provided expression to the pointed file.
- fn write_expr(&self, expr: impl Into<NormalizedExpr>) -> Result<()> {
+ fn write_expr(&self, expr: impl Into<Expr>) -> Result<()> {
let expr = expr.into();
let path = self.path();
create_dir_all(path.parent().unwrap())?;
@@ -142,7 +142,7 @@ impl TestFile {
}
/// Check that the provided expression matches the file contents.
- pub fn compare(&self, expr: impl Into<NormalizedExpr>) -> Result<()> {
+ pub fn compare(&self, expr: impl Into<Expr>) -> Result<()> {
let expr = expr.into();
if !self.path().is_file() {
return self.write_expr(expr);
@@ -159,7 +159,7 @@ impl TestFile {
Ok(())
}
/// Check that the provided expression matches the file contents.
- pub fn compare_debug(&self, expr: impl Into<NormalizedExpr>) -> Result<()> {
+ pub fn compare_debug(&self, expr: impl Into<Expr>) -> Result<()> {
let expr = expr.into();
if !self.path().is_file() {
return self.write_expr(expr);
@@ -176,10 +176,7 @@ impl TestFile {
Ok(())
}
/// Check that the provided expression matches the file contents.
- pub fn compare_binary(
- &self,
- expr: impl Into<NormalizedExpr>,
- ) -> Result<()> {
+ pub fn compare_binary(&self, expr: impl Into<Expr>) -> Result<()> {
let expr = expr.into();
match self {
TestFile::Binary(_) => {}
@@ -302,7 +299,7 @@ fn run_test(test: Test) -> Result<()> {
expected.compare(expr)?;
}
ImportFailure(expr, expected) => {
- let err = expr.parse()?.resolve().unwrap_err();
+ let err = expr.resolve().unwrap_err();
expected.compare_ui(err)?;
}
TypeInferenceSuccess(expr, expected) => {
diff --git a/dhall/tests/version_numbers.rs b/dhall/tests/version_numbers.rs
new file mode 100644
index 0000000..9f1d04a
--- /dev/null
+++ b/dhall/tests/version_numbers.rs
@@ -0,0 +1,4 @@
+#[test]
+fn test_html_root_url() {
+ version_sync::assert_html_root_url_updated!("src/lib.rs");
+}
diff --git a/dhall_proc_macros/Cargo.toml b/dhall_proc_macros/Cargo.toml
index 6de2850..48b55e8 100644
--- a/dhall_proc_macros/Cargo.toml
+++ b/dhall_proc_macros/Cargo.toml
@@ -17,3 +17,6 @@ itertools = "0.9.0"
quote = "1.0"
proc-macro2 = "1.0"
syn = "1.0"
+
+[dev-dependencies]
+version-sync = "0.8"
diff --git a/dhall_proc_macros/src/derive.rs b/dhall_proc_macros/src/derive.rs
index 48626a0..e484ec6 100644
--- a/dhall_proc_macros/src/derive.rs
+++ b/dhall_proc_macros/src/derive.rs
@@ -52,9 +52,11 @@ fn derive_for_struct(
let ty = static_type(ty);
quote!( (#name.to_owned(), #ty) )
});
- Ok(quote! { ::serde_dhall::value::Value::make_record_type(
- vec![ #(#entries),* ].into_iter()
- ) })
+ Ok(quote! {
+ ::serde_dhall::SimpleType::Record(
+ vec![ #(#entries),* ].into_iter().collect()
+ )
+ })
}
fn derive_for_enum(
@@ -89,9 +91,11 @@ fn derive_for_enum(
})
.collect::<Result<_, Error>>()?;
- Ok(quote! { ::serde_dhall::value::Value::make_union_type(
- vec![ #(#entries),* ].into_iter()
- ) })
+ Ok(quote! {
+ ::serde_dhall::SimpleType::Union(
+ vec![ #(#entries),* ].into_iter().collect()
+ )
+ })
}
pub fn derive_static_type_inner(
@@ -164,8 +168,7 @@ pub fn derive_static_type_inner(
impl #impl_generics ::serde_dhall::StaticType
for #ident #ty_generics
#where_clause {
- fn static_type() ->
- ::serde_dhall::value::Value {
+ fn static_type() -> ::serde_dhall::SimpleType {
#(#assertions)*
#get_type
}
diff --git a/dhall_proc_macros/tests/version_numbers.rs b/dhall_proc_macros/tests/version_numbers.rs
new file mode 100644
index 0000000..9f1d04a
--- /dev/null
+++ b/dhall_proc_macros/tests/version_numbers.rs
@@ -0,0 +1,4 @@
+#[test]
+fn test_html_root_url() {
+ version_sync::assert_html_root_url_updated!("src/lib.rs");
+}