logicaffeine_language/
scope.rs

1//! Scope stack for variable binding during code generation.
2//!
3//! This module provides a stack-based scope tracker for the code generator,
4//! maintaining variable bindings and ownership states across nested scopes.
5//! Used primarily in LOGOS mode for imperative code generation.
6
7use std::collections::HashMap;
8use crate::drs::OwnershipState;
9
10/// A single variable binding in a scope.
11#[derive(Debug, Clone)]
12pub struct ScopeEntry {
13    pub symbol: String,
14    pub ownership: OwnershipState,
15}
16
17impl ScopeEntry {
18    pub fn variable(name: &str) -> Self {
19        Self {
20            symbol: name.to_string(),
21            ownership: OwnershipState::Owned,
22        }
23    }
24}
25
26#[derive(Debug, Default)]
27pub struct ScopeStack {
28    scopes: Vec<HashMap<String, ScopeEntry>>,
29}
30
31impl ScopeStack {
32    pub fn new() -> Self {
33        Self::default()
34    }
35
36    pub fn push_scope(&mut self) {
37        self.scopes.push(HashMap::new());
38    }
39
40    pub fn pop_scope(&mut self) {
41        self.scopes.pop();
42    }
43
44    pub fn bind(&mut self, name: &str, entry: ScopeEntry) {
45        if let Some(scope) = self.scopes.last_mut() {
46            scope.insert(name.to_string(), entry);
47        }
48    }
49
50    pub fn lookup(&self, name: &str) -> Option<&ScopeEntry> {
51        for scope in self.scopes.iter().rev() {
52            if let Some(entry) = scope.get(name) {
53                return Some(entry);
54            }
55        }
56        None
57    }
58
59    pub fn lookup_mut(&mut self, name: &str) -> Option<&mut ScopeEntry> {
60        for scope in self.scopes.iter_mut().rev() {
61            if let Some(entry) = scope.get_mut(name) {
62                return Some(entry);
63            }
64        }
65        None
66    }
67}