feat: add support for booleans and comparision operators

This commit is contained in:
2026-04-21 10:56:42 +02:00
parent bad6b9e116
commit eb3663dfbb
11 changed files with 293 additions and 3 deletions
+66 -2
View File
@@ -348,6 +348,25 @@ impl Sema {
}
}
ExprKind::Unary {
op: UnaryOp::Not,
expr,
} => {
let typed_inner = self.analyze_expr(expr);
if let Err(e) = self.unify(&Ty::Bool, &typed_inner.ty) {
self.errors.push(SemanticError::new(e, expr.span));
}
TypedExpr {
kind: TypedExprKind::Unary {
op: UnaryOp::Not,
expr: Box::new(typed_inner),
},
ty: Ty::Bool,
}
}
ExprKind::Binary { op, lhs, rhs } => {
let typed_lhs = self.analyze_expr(lhs);
let typed_rhs = self.analyze_expr(rhs);
@@ -356,8 +375,24 @@ impl Sema {
self.errors.push(SemanticError::new(e, expr.span));
}
let result_ty = typed_lhs.ty.clone();
self.deferred_binary.push((expr.span, result_ty.clone()));
let is_comparison = matches!(
op,
BinaryOp::Eq
| BinaryOp::Neq
| BinaryOp::Lt
| BinaryOp::Le
| BinaryOp::Gt
| BinaryOp::Ge
);
let result_ty = if is_comparison {
Ty::Bool
} else {
typed_lhs.ty.clone()
};
self.deferred_binary.push((expr.span, typed_lhs.ty.clone()));
TypedExpr {
kind: TypedExprKind::Binary {
op: *op,
@@ -628,4 +663,33 @@ mod test {
.contains("unary minus only works on integer types")
}));
}
#[test]
fn valid_logical_not() {
let src = "fn test(a: bool) -> bool { return !a; }";
assert!(analyze(src).is_ok());
}
#[test]
fn invalid_logical_not() {
let src = "fn test(a: i32) -> bool { return !a; }";
let errors = analyze(src).unwrap_err();
assert!(errors.iter().any(|e| e.message.contains("type mismatch")));
}
#[test]
fn valid_comparison() {
let src = "fn test(a: i32, b: i32) -> bool { return a <= b; }";
assert!(analyze(src).is_ok());
}
#[test]
fn invalid_comparison() {
let src = "fn test(a: bool, b: bool) -> bool { return a == b; }";
let errors = analyze(src).unwrap_err();
assert!(errors.iter().any(|e| {
e.message
.contains("binary operators only work on integer types")
}));
}
}