rl_lang/checker/scope/
mod.rs1mod assign;
4mod call;
5mod declare;
6
7use crate::{
8 checker::structs::{CheckType, TypeChecker},
9 utils::{span::Span, suggest::closest_match},
10};
11use std::collections::HashMap;
12
13impl TypeChecker {
14 pub fn push_scope(&mut self) {
16 self.scopes.push(HashMap::new());
17 }
18 pub fn pop_scope(&mut self) {
20 self.scopes.pop();
21 }
22
23 pub fn lookup(&mut self, name: &str, span: Span) -> CheckType {
29 let found = self.scopes.iter().rev().find_map(|scope| {
30 scope
31 .get(name)
32 .map(|item| (item.type_annotation.clone(), item.is_const))
33 });
34
35 if let Some((item_type, is_const)) = found {
36 let kind = if is_const { "const" } else { "variable" };
37 self.push_hover(
38 span,
39 format!("```rl\n{} {}: {}\n```", kind, name, item_type.info()),
40 );
41 return item_type;
42 }
43
44 let all_keys: Vec<String> = self
45 .scopes
46 .iter()
47 .flat_map(|s| s.keys().cloned().collect::<Vec<_>>())
48 .collect();
49 let suggestion = closest_match(name, all_keys.iter().map(|s| s.as_str()));
50 self.error_with_help(format!("undefined variable {}", name), span, suggestion);
51 CheckType::Unknown
52 }
53}