From d6d1ec80ffcc0b13234b170a91b920371078a027 Mon Sep 17 00:00:00 2001 From: Joel Kronqvist Date: Sun, 10 Aug 2025 19:16:51 +0300 Subject: Added tests for functions --- src/type/check.rs | 50 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) (limited to 'src/type/check.rs') 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)?; -- cgit v1.2.3