Skip to main content

rl_lang/checker/statements/
mod.rs

1//! Statement-level helpers shared between expression and statement checking.
2
3mod expression;
4mod statement;
5
6use crate::{
7    ast::statements::TypeAnnotation,
8    checker::structs::{CheckType, TypeChecker},
9    utils::span::Span,
10};
11
12impl TypeChecker {
13    /// Returns the expected return type of the current function or lambda, if any.
14    pub fn current_return_type(&self) -> Option<&TypeAnnotation> {
15        self.return_type_stack.last()
16    }
17    /// Pushes `ty` as the expected return type when entering a function or lambda body.
18    pub fn push_return_type(&mut self, ty: TypeAnnotation) {
19        self.return_type_stack.push(ty);
20    }
21    /// Pops the expected return type when exiting a function or lambda body.
22    pub fn pop_return_type(&mut self) {
23        self.return_type_stack.pop();
24    }
25
26    // functions for loops to track `break` and similiar
27    pub fn loop_depth(&self) -> u32 {
28        self.loop_depth
29    }
30    pub fn enter_loop(&mut self) {
31        self.loop_depth += 1;
32    }
33    pub fn exit_loop(&mut self) {
34        self.loop_depth = self.loop_depth.saturating_sub(1);
35    }
36    /// Checks all statements in `statements` inside a fresh scope.
37    pub fn check_block(&mut self, statements: &[crate::ast::statements::Statement]) {
38        self.push_scope();
39        for stmt in statements {
40            self.check_statement(stmt);
41        }
42        self.pop_scope();
43    }
44
45    /// Emits a `"value is null"` error if `item_type` is [`CheckType::Known(Null)`].
46    ///
47    /// Returns `false` if null, `true` otherwise.
48    pub fn check_is_null(&mut self, item_type: &CheckType, span: Span) -> bool {
49        if item_type.is_null() {
50            self.error("value is null", span);
51            false
52        } else {
53            true
54        }
55    }
56
57    /// Converts a [`CheckType`] to a [`TypeAnnotation`], mapping `Unknown` to `Null`.
58    pub(crate) fn to_type_annotation(item_type: &CheckType) -> TypeAnnotation {
59        match item_type {
60            CheckType::Known(t) => t.clone(),
61            CheckType::Function { .. } => TypeAnnotation::Fn,
62            CheckType::Unknown => TypeAnnotation::Null,
63        }
64    }
65
66    pub(crate) fn is_hashable_key_type(ty: &TypeAnnotation) -> bool {
67        matches!(
68            ty,
69            TypeAnnotation::Int
70                | TypeAnnotation::CInt
71                | TypeAnnotation::String
72                | TypeAnnotation::CString
73                | TypeAnnotation::Bool
74                | TypeAnnotation::CBool
75                | TypeAnnotation::Byte
76                | TypeAnnotation::CByte
77                | TypeAnnotation::Char
78                | TypeAnnotation::CChar
79                | TypeAnnotation::Null
80        )
81    }
82}