1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
use galvan_ast::{DeclModifier, Ident, Ownership, TypeElement};
use std::collections::HashMap;

#[derive(Clone, Debug, Default)]
pub struct Scope<'a> {
    pub parent: Option<&'a Scope<'a>>,
    pub variables: HashMap<Ident, Variable>,
}

impl Scope<'_> {
    pub fn child(parent: &Self) -> Scope {
        Scope {
            parent: Some(parent),
            variables: HashMap::new(),
        }
    }

    pub fn declare_variable(&mut self, variable: Variable) {
        self.variables.insert(variable.ident.clone(), variable);
    }

    pub fn get_variable(&self, ident: &Ident) -> Option<&Variable> {
        self.variables
            .get(ident)
            .or_else(|| self.parent.and_then(|parent| parent.get_variable(ident)))
    }
}

#[derive(Clone, Debug)]
pub struct Variable {
    pub ident: Ident,
    pub modifier: DeclModifier,
    /// If the variable type cannot be identified, this is `None` and type inference will be delegated to Rust
    pub ty: Option<TypeElement>,
    pub ownership: Ownership,
}

impl Variable {
    pub fn is_mut(&self) -> bool {
        matches!(self.modifier, DeclModifier::Mut(_))
    }
}