summaryrefslogtreecommitdiff
path: root/dhall
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dhall/src/core/context.rs34
-rw-r--r--dhall/src/core/value.rs68
-rw-r--r--dhall/src/core/valuef.rs14
-rw-r--r--dhall/src/phase/normalize.rs72
-rw-r--r--dhall/src/phase/typecheck.rs33
5 files changed, 113 insertions, 108 deletions
diff --git a/dhall/src/core/context.rs b/dhall/src/core/context.rs
index 851e4c4..deabe44 100644
--- a/dhall/src/core/context.rs
+++ b/dhall/src/core/context.rs
@@ -3,7 +3,7 @@ use std::rc::Rc;
use dhall_syntax::{Label, V};
-use crate::core::value::{TypedValue, Value};
+use crate::core::value::TypedValue;
use crate::core::valuef::ValueF;
use crate::core::var::{AlphaVar, Shift, Subst};
use crate::error::TypeError;
@@ -11,7 +11,7 @@ use crate::error::TypeError;
#[derive(Debug, Clone)]
enum CtxItem {
Kept(AlphaVar, TypedValue),
- Replaced(Value, TypedValue),
+ Replaced(TypedValue),
}
#[derive(Debug, Clone)]
@@ -32,10 +32,7 @@ impl TypecheckContext {
e: TypedValue,
) -> Result<Self, TypeError> {
let mut vec = self.0.as_ref().clone();
- vec.push((
- x.clone(),
- CtxItem::Replaced(e.to_value(), e.get_type()?.into_owned()),
- ));
+ vec.push((x.clone(), CtxItem::Replaced(e)));
Ok(TypecheckContext(Rc::new(vec)))
}
pub fn lookup(&self, var: &V<Label>) -> Option<TypedValue> {
@@ -45,13 +42,15 @@ impl TypecheckContext {
match var.over_binder(l) {
None => {
let i = i.under_multiple_binders(&shift_map);
- let (th, t) = match i {
+ return Some(match i {
CtxItem::Kept(newvar, t) => {
- (ValueF::Var(newvar).into_value(), t)
+ TypedValue::from_valuef_and_type(
+ ValueF::Var(newvar),
+ t,
+ )
}
- CtxItem::Replaced(th, t) => (th, t),
- };
- return Some(TypedValue::from_value_and_type(th, t));
+ CtxItem::Replaced(v) => v,
+ });
}
Some(newvar) => var = newvar,
};
@@ -114,9 +113,7 @@ impl Shift for CtxItem {
CtxItem::Kept(v, t) => {
CtxItem::Kept(v.shift(delta, var)?, t.shift(delta, var)?)
}
- CtxItem::Replaced(e, t) => {
- CtxItem::Replaced(e.shift(delta, var)?, t.shift(delta, var)?)
- }
+ CtxItem::Replaced(e) => CtxItem::Replaced(e.shift(delta, var)?),
})
}
}
@@ -130,14 +127,9 @@ impl Shift for TypecheckContext {
impl Subst<TypedValue> for CtxItem {
fn subst_shift(&self, var: &AlphaVar, val: &TypedValue) -> Self {
match self {
- CtxItem::Replaced(e, t) => CtxItem::Replaced(
- e.subst_shift(var, val),
- t.subst_shift(var, val),
- ),
+ CtxItem::Replaced(e) => CtxItem::Replaced(e.subst_shift(var, val)),
CtxItem::Kept(v, t) => match v.shift(-1, var) {
- None => {
- CtxItem::Replaced(val.to_value(), t.subst_shift(var, val))
- }
+ None => CtxItem::Replaced(val.clone()),
Some(newvar) => CtxItem::Kept(newvar, t.subst_shift(var, val)),
},
}
diff --git a/dhall/src/core/value.rs b/dhall/src/core/value.rs
index f4cb6b6..c4e3831 100644
--- a/dhall/src/core/value.rs
+++ b/dhall/src/core/value.rs
@@ -2,7 +2,7 @@ use std::borrow::Cow;
use std::cell::{Ref, RefCell, RefMut};
use std::rc::Rc;
-use dhall_syntax::{Const, ExprF};
+use dhall_syntax::Const;
use crate::core::context::TypecheckContext;
use crate::core::valuef::ValueF;
@@ -10,7 +10,7 @@ use crate::core::var::{AlphaVar, Shift, Subst};
use crate::error::{TypeError, TypeMessage};
use crate::phase::normalize::{apply_any, normalize_whnf, OutputSubExpr};
use crate::phase::typecheck::type_of_const;
-use crate::phase::{Normalized, NormalizedSubExpr, Typed};
+use crate::phase::{NormalizedSubExpr, Typed};
#[derive(Debug, Clone, Copy)]
enum Form {
@@ -28,7 +28,7 @@ enum Form {
}
use Form::{Unevaled, NF, WHNF};
-#[derive(Debug, Clone)]
+#[derive(Debug)]
/// Partially normalized value.
/// Invariant: if `form` is `WHNF`, `value` must be in Weak Head Normal Form
/// Invariant: if `form` is `NF`, `value` must be fully normalized
@@ -108,7 +108,7 @@ impl ValueInternal {
}
impl Value {
- pub(crate) fn from_valuef(v: ValueF) -> Value {
+ pub(crate) fn from_valuef_untyped(v: ValueF) -> Value {
ValueInternal {
form: Unevaled,
value: v,
@@ -124,18 +124,8 @@ impl Value {
}
.into_value()
}
- pub(crate) fn from_partial_expr(e: ExprF<Value, Normalized>) -> Value {
- Value::from_valuef(ValueF::PartialExpr(e))
- }
- // TODO: avoid using this function
- pub(crate) fn with_type(self, t: TypedValue) -> Value {
- let vint = self.as_internal();
- ValueInternal {
- form: vint.form,
- value: vint.value.clone(),
- ty: Some(t),
- }
- .into_value()
+ pub(crate) fn from_valuef_simple_type(v: ValueF) -> Value {
+ Value::from_valuef_and_type(v, TypedValue::from_const(Const::Type))
}
/// Mutates the contents. If no one else shares this thunk,
@@ -214,7 +204,7 @@ impl Value {
}
pub(crate) fn app_valuef(&self, val: ValueF) -> ValueF {
- self.app_value(val.into_value())
+ self.app_value(val.into_value_untyped())
}
pub(crate) fn app_value(&self, th: Value) -> ValueF {
@@ -227,41 +217,39 @@ impl Value {
}
impl TypedValue {
- pub(crate) fn from_valuef(v: ValueF) -> TypedValue {
- TypedValue::from_value_untyped(Value::from_valuef(v))
- }
-
- pub(crate) fn normalize_nf(&self) -> ValueF {
- self.0.normalize_nf().clone()
- }
-
- pub(crate) fn normalize_to_expr_maybe_alpha(
- &self,
- alpha: bool,
- ) -> OutputSubExpr {
- self.normalize_nf().normalize_to_expr_maybe_alpha(alpha)
+ pub fn from_value(th: Value) -> Self {
+ TypedValue(th)
}
-
- pub(crate) fn from_value_and_type(th: Value, t: TypedValue) -> Self {
- TypedValue(th.with_type(t))
+ pub(crate) fn from_valuef_untyped(v: ValueF) -> TypedValue {
+ TypedValue::from_value(Value::from_valuef_untyped(v))
}
- pub fn from_value_simple_type(th: Value) -> Self {
- TypedValue::from_value_and_type(th, TypedValue::const_type())
+ pub(crate) fn from_valuef_and_type(v: ValueF, t: TypedValue) -> Self {
+ TypedValue(Value::from_valuef_and_type(v, t))
}
- pub(crate) fn from_value_untyped(th: Value) -> Self {
- TypedValue(th)
+ // TODO: do something with the info that the type is Type. Maybe check
+ // is a type is present ?
+ pub(crate) fn from_value_simple_type(th: Value) -> Self {
+ TypedValue::from_value(th)
}
pub(crate) fn from_const(c: Const) -> Self {
match type_of_const(c) {
Ok(t) => TypedValue::from_valuef_and_type(ValueF::Const(c), t),
- Err(_) => TypedValue::from_valuef(ValueF::Const(c)),
+ Err(_) => TypedValue::from_valuef_untyped(ValueF::Const(c)),
}
}
pub fn const_type() -> Self {
TypedValue::from_const(Const::Type)
}
- pub(crate) fn from_valuef_and_type(v: ValueF, t: TypedValue) -> Self {
- TypedValue(Value::from_valuef_and_type(v, t))
+
+ pub(crate) fn normalize_nf(&self) -> ValueF {
+ self.0.normalize_nf().clone()
+ }
+
+ pub(crate) fn normalize_to_expr_maybe_alpha(
+ &self,
+ alpha: bool,
+ ) -> OutputSubExpr {
+ self.normalize_nf().normalize_to_expr_maybe_alpha(alpha)
}
/// WARNING: drop this ref before normalizing the same value or you will run into BorrowMut
diff --git a/dhall/src/core/valuef.rs b/dhall/src/core/valuef.rs
index b948eb1..de55d2f 100644
--- a/dhall/src/core/valuef.rs
+++ b/dhall/src/core/valuef.rs
@@ -48,8 +48,14 @@ pub enum ValueF {
}
impl ValueF {
- pub(crate) fn into_value(self) -> Value {
- Value::from_valuef(self)
+ pub(crate) fn into_value_untyped(self) -> Value {
+ Value::from_valuef_untyped(self)
+ }
+ pub(crate) fn into_value_with_type(self, t: TypedValue) -> Value {
+ Value::from_valuef_and_type(self, t)
+ }
+ pub(crate) fn into_value_simple_type(self) -> Value {
+ Value::from_valuef_simple_type(self)
}
/// Convert the value to a fully normalized syntactic expression
@@ -258,12 +264,12 @@ impl ValueF {
/// Apply to a value
pub(crate) fn app_valuef(self, val: ValueF) -> ValueF {
- self.app_value(val.into_value())
+ self.app_value(val.into_value_untyped())
}
/// Apply to a thunk
pub fn app_value(self, th: Value) -> ValueF {
- Value::from_valuef(self).app_value(th)
+ Value::from_valuef_untyped(self).app_value(th)
}
pub fn from_builtin(b: Builtin) -> ValueF {
diff --git a/dhall/src/phase/normalize.rs b/dhall/src/phase/normalize.rs
index dabfe87..27858d8 100644
--- a/dhall/src/phase/normalize.rs
+++ b/dhall/src/phase/normalize.rs
@@ -20,7 +20,7 @@ macro_rules! make_closure {
Label::from(stringify!($var)).into(),
$n
);
- ValueF::Var(var).into_value()
+ ValueF::Var(var).into_value_untyped()
}};
// Warning: assumes that $ty, as a dhall value, has type `Type`
(λ($var:ident : $($ty:tt)*) -> $($rest:tt)*) => {
@@ -30,30 +30,40 @@ macro_rules! make_closure {
make_closure!($($ty)*),
),
make_closure!($($rest)*),
- ).into_value()
+ ).into_value_untyped()
+ };
+ (Natural) => {
+ ValueF::from_builtin(Builtin::Natural)
+ .into_value_simple_type()
};
- (Natural) => { ValueF::from_builtin(Builtin::Natural).into_value() };
(List $($rest:tt)*) => {
ValueF::from_builtin(Builtin::List)
.app_value(make_closure!($($rest)*))
- .into_value()
+ .into_value_simple_type()
};
- (Some $($rest:tt)*) => {
- ValueF::NEOptionalLit(make_closure!($($rest)*)).into_value()
+ (Some($($rest:tt)*)) => {
+ ValueF::NEOptionalLit(make_closure!($($rest)*))
+ .into_value_untyped()
};
(1 + $($rest:tt)*) => {
ValueF::PartialExpr(ExprF::BinOp(
dhall_syntax::BinOp::NaturalPlus,
make_closure!($($rest)*),
- Value::from_valuef(ValueF::NaturalLit(1)),
- )).into_value()
+ Value::from_valuef_and_type(
+ ValueF::NaturalLit(1),
+ TypedValue::from_value(make_closure!(Natural))
+ ),
+ )).into_value_with_type(
+ TypedValue::from_value(make_closure!(Natural))
+ )
};
([ $($head:tt)* ] # $($tail:tt)*) => {
ValueF::PartialExpr(ExprF::BinOp(
dhall_syntax::BinOp::ListAppend,
- ValueF::NEListLit(vec![make_closure!($($head)*)]).into_value(),
+ ValueF::NEListLit(vec![make_closure!($($head)*)])
+ .into_value_untyped(),
make_closure!($($tail)*),
- )).into_value()
+ )).into_value_untyped()
};
}
@@ -189,10 +199,17 @@ pub(crate) fn apply_builtin(b: Builtin, args: Vec<Value>) -> ValueF {
let mut kts = HashMap::new();
kts.insert(
"index".into(),
- TypedValue::from_valuef(ValueF::from_builtin(Natural)),
+ TypedValue::from_valuef_untyped(ValueF::from_builtin(
+ Natural,
+ )),
);
kts.insert("value".into(), t.clone());
- Ok((r, EmptyListLit(TypedValue::from_valuef(RecordType(kts)))))
+ Ok((
+ r,
+ EmptyListLit(TypedValue::from_valuef_untyped(RecordType(
+ kts,
+ ))),
+ ))
}
NEListLit(xs) => {
let xs = xs
@@ -201,9 +218,12 @@ pub(crate) fn apply_builtin(b: Builtin, args: Vec<Value>) -> ValueF {
.map(|(i, e)| {
let i = NaturalLit(i);
let mut kvs = HashMap::new();
- kvs.insert("index".into(), Value::from_valuef(i));
+ kvs.insert(
+ "index".into(),
+ Value::from_valuef_untyped(i),
+ );
kvs.insert("value".into(), e.clone());
- Value::from_valuef(RecordLit(kvs))
+ Value::from_valuef_untyped(RecordLit(kvs))
})
.collect();
Ok((r, NEListLit(xs)))
@@ -246,7 +266,7 @@ pub(crate) fn apply_builtin(b: Builtin, args: Vec<Value>) -> ValueF {
.clone()
.app_value(x.clone())
.app_value(v)
- .into_value();
+ .into_value_untyped();
}
Ok((r, v.to_whnf()))
}
@@ -267,7 +287,7 @@ pub(crate) fn apply_builtin(b: Builtin, args: Vec<Value>) -> ValueF {
f.app_valuef(
ValueF::from_builtin(Optional).app_value(t.clone()),
)
- .app_value(make_closure!(λ(x: #t) -> Some var(x, 0)))
+ .app_value(make_closure!(λ(x: #t) -> Some(var(x, 0))))
.app_valuef(EmptyOptionalLit(
TypedValue::from_value_simple_type(t.clone()),
)),
@@ -327,7 +347,7 @@ pub(crate) fn apply_any(f: Value, a: Value) -> ValueF {
let f_borrow = f.as_whnf();
match &*f_borrow {
ValueF::Lam(x, _, e) => {
- let val = TypedValue::from_value_untyped(a);
+ let val = TypedValue::from_value(a);
e.subst_shift(&x.into(), &val).to_whnf()
}
ValueF::AppliedBuiltin(b, args) => {
@@ -602,11 +622,11 @@ fn apply_binop<'a>(o: BinOp, x: &'a Value, y: &'a Value) -> Option<Ret<'a>> {
}
(RecursiveRecordMerge, RecordLit(kvs1), RecordLit(kvs2)) => {
let kvs = merge_maps(kvs1, kvs2, |v1, v2| {
- Value::from_partial_expr(ExprF::BinOp(
+ Value::from_valuef_untyped(ValueF::PartialExpr(ExprF::BinOp(
RecursiveRecordMerge,
v1.clone(),
v2.clone(),
- ))
+ )))
});
Ret::ValueF(RecordLit(kvs))
}
@@ -619,7 +639,7 @@ fn apply_binop<'a>(o: BinOp, x: &'a Value, y: &'a Value) -> Option<Ret<'a>> {
}
(RecursiveRecordTypeMerge, RecordType(kvs1), RecordType(kvs2)) => {
let kvs = merge_maps(kvs1, kvs2, |v1, v2| {
- TypedValue::from_value_untyped(Value::from_partial_expr(
+ TypedValue::from_valuef_untyped(ValueF::PartialExpr(
ExprF::BinOp(
RecursiveRecordTypeMerge,
v1.to_value(),
@@ -655,15 +675,15 @@ pub(crate) fn normalize_one_layer(expr: ExprF<Value, Normalized>) -> ValueF {
ExprF::Annot(x, _) => Ret::Value(x),
ExprF::Assert(_) => Ret::Expr(expr),
ExprF::Lam(x, t, e) => {
- Ret::ValueF(Lam(x.into(), TypedValue::from_value_untyped(t), e))
+ Ret::ValueF(Lam(x.into(), TypedValue::from_value(t), e))
}
ExprF::Pi(x, t, e) => Ret::ValueF(Pi(
x.into(),
- TypedValue::from_value_untyped(t),
- TypedValue::from_value_untyped(e),
+ TypedValue::from_value(t),
+ TypedValue::from_value(e),
)),
ExprF::Let(x, _, v, b) => {
- let v = TypedValue::from_value_untyped(v);
+ let v = TypedValue::from_value(v);
Ret::Value(b.subst_shift(&x.into(), &v))
}
ExprF::App(v, a) => Ret::ValueF(v.app_value(a)),
@@ -697,12 +717,12 @@ pub(crate) fn normalize_one_layer(expr: ExprF<Value, Normalized>) -> ValueF {
}
ExprF::RecordType(kts) => Ret::ValueF(RecordType(
kts.into_iter()
- .map(|(k, t)| (k, TypedValue::from_value_untyped(t)))
+ .map(|(k, t)| (k, TypedValue::from_value(t)))
.collect(),
)),
ExprF::UnionType(kts) => Ret::ValueF(UnionType(
kts.into_iter()
- .map(|(k, t)| (k, t.map(|t| TypedValue::from_value_untyped(t))))
+ .map(|(k, t)| (k, t.map(|t| TypedValue::from_value(t))))
.collect(),
)),
ExprF::TextLit(elts) => {
diff --git a/dhall/src/phase/typecheck.rs b/dhall/src/phase/typecheck.rs
index 07c4ad8..e24f5a3 100644
--- a/dhall/src/phase/typecheck.rs
+++ b/dhall/src/phase/typecheck.rs
@@ -5,7 +5,7 @@ use dhall_syntax::{
};
use crate::core::context::TypecheckContext;
-use crate::core::value::{TypedValue, Value};
+use crate::core::value::TypedValue;
use crate::core::valuef::ValueF;
use crate::core::var::{Shift, Subst};
use crate::error::{TypeError, TypeMessage};
@@ -37,8 +37,8 @@ fn tck_pi_type(
let k = function_check(ka, kb);
- Ok(TypedValue::from_value_and_type(
- ValueF::Pi(x.into(), tx, te).into_value(),
+ Ok(TypedValue::from_valuef_and_type(
+ ValueF::Pi(x.into(), tx, te),
TypedValue::from_const(k),
))
}
@@ -70,8 +70,8 @@ fn tck_record_type(
// An empty record type has type Type
let k = k.unwrap_or(Const::Type);
- Ok(TypedValue::from_value_and_type(
- ValueF::RecordType(new_kts).into_value(),
+ Ok(TypedValue::from_valuef_and_type(
+ ValueF::RecordType(new_kts),
TypedValue::from_const(k),
))
}
@@ -115,8 +115,8 @@ where
// an union type with only unary variants also has type Type
let k = k.unwrap_or(Const::Type);
- Ok(TypedValue::from_value_and_type(
- ValueF::UnionType(new_kts).into_value(),
+ Ok(TypedValue::from_valuef_and_type(
+ ValueF::UnionType(new_kts),
TypedValue::from_const(k),
))
}
@@ -281,6 +281,7 @@ fn type_of_builtin<E>(b: Builtin) -> Expr<E> {
}
}
+// TODO: this can't fail in practise
pub(crate) fn builtin_to_type(b: Builtin) -> Result<TypedValue, TypeError> {
type_with(&TypecheckContext::new(), SubExpr::from_builtin(b))
}
@@ -351,8 +352,8 @@ fn type_with(
match ret {
RetTypeOnly(typ) => {
let expr = expr.map_ref(|typed| typed.to_value());
- TypedValue::from_value_and_type(
- Value::from_partial_expr(expr),
+ TypedValue::from_valuef_and_type(
+ ValueF::PartialExpr(expr),
typ,
)
}
@@ -465,10 +466,9 @@ fn type_last_layer(
));
}
- Ok(RetTypeOnly(TypedValue::from_value_and_type(
+ Ok(RetTypeOnly(TypedValue::from_valuef_and_type(
ValueF::from_builtin(dhall_syntax::Builtin::List)
- .app_value(t.to_value())
- .into_value(),
+ .app_value(t.to_value()),
TypedValue::from_const(Type),
)))
}
@@ -478,10 +478,9 @@ fn type_last_layer(
return Err(TypeError::new(ctx, InvalidOptionalType(t)));
}
- Ok(RetTypeOnly(TypedValue::from_value_and_type(
+ Ok(RetTypeOnly(TypedValue::from_valuef_and_type(
ValueF::from_builtin(dhall_syntax::Builtin::Optional)
- .app_value(t.to_value())
- .into_value(),
+ .app_value(t.to_value()),
TypedValue::from_const(Type),
)))
}
@@ -942,8 +941,8 @@ fn type_last_layer(
};
}
- Ok(RetTypeOnly(TypedValue::from_value_and_type(
- ValueF::RecordType(new_kts).into_value(),
+ Ok(RetTypeOnly(TypedValue::from_valuef_and_type(
+ ValueF::RecordType(new_kts),
record_type.get_type()?.into_owned(),
)))
}