Skip to main content

rl_lang/checker/operators/
unary.rs

1//! Unary operator type checking.
2//!
3//! | Operator | Operand         | Result |
4//! |----------|-----------------|--------|
5//! | `!`      | bool            | bool   |
6//! | `-`      | int             | int    |
7//! | `-`      | float           | float  |
8
9use crate::{
10    ast::statements::TypeAnnotation,
11    checker::structs::{CheckType, TypeChecker},
12    lexer::tokentypes::TokenType,
13    utils::span::Span,
14};
15
16impl TypeChecker {
17    pub fn check_unary_operator(
18        &mut self,
19        operand: CheckType,
20        _operand_span: Span,
21        op: &TokenType,
22        span: Span,
23    ) -> CheckType {
24        if operand.is_unknown() {
25            return CheckType::Unknown;
26        }
27        match op {
28            // is it correct bang unary?
29            TokenType::Bang => match &operand {
30                CheckType::Known(TypeAnnotation::Bool | TypeAnnotation::CBool) => {
31                    CheckType::Known(TypeAnnotation::Bool)
32                }
33                _ => {
34                    self.error(format!("type mismatch on !: got {}", operand.info()), span);
35                    CheckType::Unknown
36                }
37            },
38            // is it correect minus unary?
39            TokenType::Minus => match &operand {
40                CheckType::Known(TypeAnnotation::Int | TypeAnnotation::CInt) => {
41                    CheckType::Known(TypeAnnotation::Int)
42                }
43                CheckType::Known(TypeAnnotation::Float | TypeAnnotation::CFloat) => {
44                    CheckType::Known(TypeAnnotation::Float)
45                }
46                _ => {
47                    self.error(
48                        format!("type mismatch on unary -: got {}", operand.info()),
49                        span,
50                    );
51                    CheckType::Unknown
52                }
53            },
54            // undefined unary
55            _ => {
56                self.error(format!("unknown unary operator {:?}", op), span);
57                CheckType::Unknown
58            }
59        }
60    }
61}