rune/indexing/
scopes.rs

1#![allow(unused)]
2
3use core::cell::RefCell;
4use core::fmt;
5use core::num::NonZeroUsize;
6
7use crate::alloc::{self, BTreeSet, HashMap, Vec};
8use crate::ast::Span;
9use crate::compile::error::{MissingScope, PopError};
10
11#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)]
12#[repr(transparent)]
13pub(crate) struct Scope(usize);
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
16#[repr(transparent)]
17pub(crate) struct Variable(usize);
18
19/// The kind of a layer.
20#[derive(Default)]
21enum LayerKind {
22    #[default]
23    Default,
24    Captures,
25}
26
27#[derive(Default)]
28pub(crate) struct Layer {
29    scope: Scope,
30    parent: Option<NonZeroUsize>,
31    pub(crate) awaits: Vec<Span>,
32    pub(crate) yields: Vec<Span>,
33}
34
35impl Layer {
36    fn parent(&self) -> Option<usize> {
37        Some(self.parent?.get().wrapping_sub(1))
38    }
39}
40
41pub(crate) struct Scopes {
42    scope: Scope,
43    scopes: Vec<Layer>,
44}
45
46impl Scopes {
47    /// Root scope.
48    pub const ROOT: Scope = Scope(0);
49
50    pub(crate) fn new() -> alloc::Result<Self> {
51        let mut scopes = Vec::new();
52        scopes.try_push(Layer::default())?;
53
54        Ok(Self {
55            scope: Scopes::ROOT,
56            scopes,
57        })
58    }
59
60    /// Push a scope.
61    pub(crate) fn push(&mut self) -> alloc::Result<()> {
62        let scope = Scope(self.scopes.len());
63
64        let layer = Layer {
65            scope,
66            parent: Some(NonZeroUsize::new(self.scope.0.wrapping_add(1)).expect("ran out of ids")),
67            awaits: Vec::new(),
68            yields: Vec::new(),
69        };
70
71        self.scopes.try_push(layer)?;
72        self.scope = scope;
73        Ok(())
74    }
75
76    /// Pop the given scope.
77    pub(crate) fn pop(&mut self) -> Result<Layer, PopError> {
78        let Some(layer) = self.scopes.pop() else {
79            return Err(PopError::MissingScope(self.scope.0));
80        };
81
82        if layer.scope.0 != self.scope.0 {
83            return Err(PopError::MissingScope(self.scope.0));
84        }
85
86        let Some(parent) = layer.parent() else {
87            return Err(PopError::MissingParentScope(self.scope.0));
88        };
89
90        self.scope = Scope(parent);
91        Ok(layer)
92    }
93
94    /// Define the given variable.
95    #[tracing::instrument(skip_all)]
96    pub(crate) fn mark(&mut self) -> Result<&mut Layer, MissingScope> {
97        tracing::trace!(?self.scope, "mark await");
98
99        let Some(layer) = self.scopes.get_mut(self.scope.0) else {
100            return Err(MissingScope(self.scope.0));
101        };
102
103        Ok(layer)
104    }
105}