aboutsummaryrefslogtreecommitdiff
path: root/src/type/check.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/type/check.rs')
-rw-r--r--src/type/check.rs50
1 files changed, 48 insertions, 2 deletions
diff --git a/src/type/check.rs b/src/type/check.rs
index 24c255d..1712446 100644
--- a/src/type/check.rs
+++ b/src/type/check.rs
@@ -78,7 +78,7 @@ impl SExp {
/// assert_eq!(Atom(And).type_check(), Ok(arr(List(vec![Boolean, Boolean]), Boolean)));
/// assert_eq!(Atom(Or) .type_check(), Ok(arr(List(vec![Boolean, Boolean]), Boolean)));
/// assert_eq!(Atom(Xor).type_check(), Ok(arr(List(vec![Boolean, Boolean]), Boolean)));
- /// assert_eq!(Atom(Not).type_check(), Ok(arr(List(vec![Boolean]), Boolean)));
+ /// assert_eq!(Atom(Not).type_check(), Ok(arr(Boolean, Boolean)));
/// ```
///
///
@@ -101,6 +101,50 @@ impl SExp {
/// );
/// ```
///
+ /// **Functions**
+ ///
+ /// One variable:
+ /// ```rust
+ /// use myslip::{
+ /// r#type::{*, Type::*, TypeError::*, util::*},
+ /// sexp::{SExp::*, SLeaf::*, util::*},
+ /// };
+ ///
+ /// let varlist = scons(var("a"), Nil);
+ /// let typelist = scons(Ty(Integer), Nil);
+ /// let ret = Atom(Ty(Integer));
+ /// let body = scons(var("a"), Nil);
+ /// assert_eq!(
+ /// scons(Fun, scons(varlist, scons(typelist, scons(ret, scons(body, Nil))))).type_check(),
+ /// Ok(arr(List(vec![Integer]), Integer))
+ /// );
+ /// ```
+ /// Two-variable:
+ /// ```rust
+ /// use myslip::{
+ /// r#type::{*, Type::*, TypeError::*, util::*},
+ /// sexp::{SExp::*, SLeaf::*, util::*},
+ /// };
+ ///
+ /// let varlist = scons(var("a"), scons(var("b"), Nil));
+ /// let typelist = scons(Ty(List(vec![Integer])), Nil);
+ /// let ret = Atom(Ty(Boolean));
+ /// let body = scons(Eq, varlist.clone());
+ /// assert_eq!(
+ /// scons(Fun, scons(varlist, scons(typelist, scons(ret, scons(body, Nil))))).type_check(),
+ /// Ok(arr(List(vec![Integer, Integer]), Boolean))
+ /// );
+ /// ```
+ /// Only keyword shouldnt panic:
+ /// ```rust
+ /// use myslip::{
+ /// r#type::{*, Type::*, TypeError::*, util::*},
+ /// sexp::{SExp::*, SLeaf::*, util::*},
+ /// };
+ /// Atom(Fun).type_check();
+ /// ```
+ ///
+ ///
/// Though perhaps the most important task of the type system
/// is to increase safety by being able to warn about errors
/// before evaluation. Here are some failing examples:
@@ -174,7 +218,7 @@ impl SExp {
Atom(Eq | Neq | Lt | Gt | Le | Ge) =>
Ok(arr(List(vec![Integer, Integer]), Boolean)),
Atom(Or | And | Xor) => Ok(arr(List(vec![Boolean, Boolean]), Boolean)),
- Atom(Not) => Ok(arr(List(vec!(Boolean)), Boolean)),
+ Atom(Not) => Ok(arr(Boolean, Boolean)),
Atom(Nil) => Ok(NilType),
Atom(Quote) => Ok(arr(
vt("T"),
@@ -188,6 +232,7 @@ impl SExp {
Atom(Print) => Ok(arr(vt("_"), List(vec![]))),
Atom(Ty(_)) => Ok(TypeLit),
Atom(Arr) => Ok(arr(List(vec![TypeLit, TypeLit]), TypeLit)),
+ Atom(Fun) => todo!(),
SCons(op, l) => {
@@ -204,6 +249,7 @@ impl SExp {
return Err(LetAsOperator(scons(op.clone(), l.clone())));
}
+
// Normal operation
let opertype = (*op).infer_type(ctx.clone())?;
let argstype = (*l).infer_list_type(ctx)?;