diff --git a/schala-lang/language/src/builtin.rs b/schala-lang/language/src/builtin.rs index 9d8683b..b05a532 100644 --- a/schala-lang/language/src/builtin.rs +++ b/schala-lang/language/src/builtin.rs @@ -30,12 +30,12 @@ impl BinOp { }; Some(BinOp::from_sigil(s)) } - /* + pub fn get_type(&self) -> Result { let s = self.sigil.as_str(); BINOPS.get(s).map(|x| x.0.clone()).ok_or(format!("Binop {} not found", s)) } - */ + pub fn min_precedence() -> i32 { i32::min_value() } diff --git a/schala-lang/language/src/typechecking.rs b/schala-lang/language/src/typechecking.rs index b2d1888..01f39c1 100644 --- a/schala-lang/language/src/typechecking.rs +++ b/schala-lang/language/src/typechecking.rs @@ -250,7 +250,7 @@ impl<'a> TypeContext<'a> { fn prefix(&mut self, op: &PrefixOp, expr: &Expression) -> InferResult { let f = match op.get_type() { Ok(ty) => ty, - Err(e) => return TypeError::new("Couldn't find a type for this prefix op") + Err(e) => return TypeError::new(e) }; let x = self.expr(expr)?; @@ -258,14 +258,22 @@ impl<'a> TypeContext<'a> { } fn binexp(&mut self, op: &BinOp, lhs: &Expression, rhs: &Expression) -> InferResult { - Ok(ty!(Unit)) + let tf = match op.get_type() { + Ok(ty) => ty, + Err(e) => return TypeError::new(e), + }; + + let t_lhs = self.expr(lhs)?; + let t_curried = self.handle_apply(tf, t_lhs)?; + let t_rhs = self.expr(rhs)?; + self.handle_apply(t_curried, t_rhs) } fn handle_apply(&mut self, tf: Type, tx: Type) -> InferResult { Ok(match tf { - Type::Arrow(ref t1, ref t2) => { - let _ = self.unify(*t1.clone(), tx)?; - *t2.clone() + Type::Arrow(box ref t1, box ref t2) => { + let _ = self.unify(t1.clone(), tx)?; + t2.clone() }, _ => return TypeError::new(format!("Not a function")) }) @@ -348,4 +356,10 @@ mod typechecking_tests { assert_type_in_fresh_context!("-1", ty!(Int)); } + #[test] + fn operators() { + assert_type_in_fresh_context!("1 + 2", ty!(Nat)); + assert_type_in_fresh_context!("-2", ty!(Int)); + assert_type_in_fresh_context!("!true", ty!(Bool)); + } }