aboutsummaryrefslogtreecommitdiff
path: root/src/type
diff options
context:
space:
mode:
authorJoel Kronqvist <joel.kronqvist@iki.fi>2025-08-04 23:50:46 +0300
committerJoel Kronqvist <joel.kronqvist@iki.fi>2025-08-04 23:50:46 +0300
commitfdae943090463526423f5e43e72cd2f0e8147a1b (patch)
tree5a7212555d8511df16fe6bbcc54b863ec9463b46 /src/type
parent36d2818d39e61b752923e253f8455f50510cb428 (diff)
downloadmyslip-fdae943090463526423f5e43e72cd2f0e8147a1b.tar.gz
myslip-fdae943090463526423f5e43e72cd2f0e8147a1b.zip
Added repl and some documentation. Improved error messages. Removed dead code.
* Removed same_variant in parse::parsetree * Added SExp::multistep (for use of the repl) Improved error messages: * Added parenthesis around types * Changed how errors propagate inferring generics: added the error variant ArgumentsDontMatchGeneric, implemented the displaying of it, added tests for it. * Had to change some tests to match for the new changes
Diffstat (limited to 'src/type')
-rw-r--r--src/type/check.rs17
-rw-r--r--src/type/display.rs20
-rw-r--r--src/type/mod.rs5
3 files changed, 32 insertions, 10 deletions
diff --git a/src/type/check.rs b/src/type/check.rs
index 647ec4d..80cc974 100644
--- a/src/type/check.rs
+++ b/src/type/check.rs
@@ -192,7 +192,14 @@ impl Type {
match self {
Arrow(from, to) => {
- let generics = (*from).infer_generics_ctx(argtype, Vec::new())?;
+ let generics = match (*from).infer_generics_ctx(argtype, Vec::new()) {
+ Ok(x) => Ok(x),
+ Err(None) => Err(ArgumentsDontMatchGeneric {
+ argtype: argtype.clone(),
+ generictype: self.clone(),
+ }),
+ Err(Some(e)) => Err(e),
+ }?;
let mut restype = (**to).clone();
for (name, ty) in generics {
restype = restype.subst(&name, &ty);
@@ -211,7 +218,7 @@ impl Type {
&self,
argtype: &Type,
ctx: Vec<(String, Type)>
- ) -> Result<Vec<(String, Type)>, TypeError> {
+ ) -> Result<Vec<(String, Type)>, Option<TypeError>> {
match (self, argtype) {
(a, b) if a == b => Ok(ctx),
@@ -239,11 +246,7 @@ impl Type {
Ok(res)
},
- (_a, _b) => Err(InvalidArgList {
- arglist: Atom(Var("undefined".to_string())), // TODO: hacky as heck
- expected: self.clone(),
- found: argtype.clone(),
- }),
+ (_a, _b) => Err(None),
}
}
diff --git a/src/type/display.rs b/src/type/display.rs
index be51858..68d7fec 100644
--- a/src/type/display.rs
+++ b/src/type/display.rs
@@ -11,13 +11,13 @@ impl fmt::Display for Type {
/// ```rust
/// use melisp::r#type::{Type::*, util::*};
/// assert_eq!(Integer.to_string(), "Int".to_string());
- /// assert_eq!(arr(Integer, Integer).to_string(), "Int -> Int".to_string());
+ /// assert_eq!(arr(Integer, Integer).to_string(), "(Int -> Int)".to_string());
/// assert_eq!(List(vec![Integer, Integer, Integer]).to_string(), "(Int Int Int)".to_string());
/// ```
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Integer => write!(f, "{}", "Int"),
- Arrow(a, b) => write!(f, "{} -> {}", a, b),
+ Arrow(a, b) => write!(f, "({} -> {})", a, b),
List(types) => write!(
f,
"({})",
@@ -50,7 +50,7 @@ impl fmt::Display for TypeError {
/// expected: arr(VarType("?".to_string()), VarType("?".to_string())),
/// found: Integer
/// }.to_string(),
- /// "invalid operator: '1'\nexpected: '? -> ?'\nfound: 'Int'".to_string()
+ /// "invalid operator: '1'\nexpected: '(? -> ?)'\nfound: 'Int'".to_string()
/// );
/// assert_eq!(
/// InvalidArgList {
@@ -64,6 +64,13 @@ impl fmt::Display for TypeError {
/// UnboundGeneric(String::from("?")).to_string(),
/// "unbound generic type: '?'".to_string()
/// );
+ /// assert_eq!(
+ /// ArgumentsDontMatchGeneric {
+ /// argtype: Integer,
+ /// generictype: arr(VarType("T".to_string()), Integer)
+ /// }.to_string(),
+ /// "incompatible argument type 'Int' and generic operator type '(T -> Int)'".to_string()
+ /// );
/// ```
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
@@ -83,6 +90,13 @@ impl fmt::Display for TypeError {
arglist, expected, found
)
},
+ ArgumentsDontMatchGeneric { argtype, generictype } => {
+ write!(
+ f,
+ "incompatible argument type '{}' and generic operator type '{}'",
+ argtype, generictype
+ )
+ },
OtherError => write!(f, "uncategorized error"),
}
}
diff --git a/src/type/mod.rs b/src/type/mod.rs
index aeeff93..2454f31 100644
--- a/src/type/mod.rs
+++ b/src/type/mod.rs
@@ -45,6 +45,11 @@ pub enum TypeError {
found: Type,
},
+ ArgumentsDontMatchGeneric {
+ argtype: Type,
+ generictype: Type,
+ },
+
OtherError
}