feat: add support for booleans and comparision operators
This commit is contained in:
+66
-2
@@ -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")
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user