Skip to main content

syn_sem/semantic/
basic_traits.rs

1use crate::{semantic::tree::ArrayLen, TriResult};
2
3// === Scoping ===
4
5pub(crate) trait Scoping {
6    fn on_enter_scope(&mut self, scope: Scope);
7    fn on_exit_scope(&mut self, scope: Scope);
8}
9
10#[macro_export]
11macro_rules! impl_empty_scoping {
12    ($ty:ty) => {
13        impl $crate::semantic::basic_traits::Scoping for $ty {
14            fn on_enter_scope(&mut self, _: $crate::semantic::basic_traits::Scope) {}
15            fn on_exit_scope(&mut self, _: $crate::semantic::basic_traits::Scope) {}
16        }
17    };
18}
19
20#[derive(Clone, Copy)]
21pub(crate) enum Scope<'a> {
22    Mod(&'a syn::ItemMod),
23    ItemFn(&'a syn::ItemFn),
24    Block(&'a syn::Block),
25}
26
27impl Scope<'_> {
28    pub(crate) fn from_raw(raw: RawScope) -> Self {
29        unsafe {
30            match raw {
31                RawScope::Mod(ptr) => Self::Mod(ptr.as_ref().unwrap()),
32                RawScope::ItemFn(ptr) => Self::ItemFn(ptr.as_ref().unwrap()),
33                RawScope::Block(ptr) => Self::Block(ptr.as_ref().unwrap()),
34            }
35        }
36    }
37
38    pub(crate) fn into_raw(self) -> RawScope {
39        match self {
40            Self::Mod(ref_) => RawScope::Mod(ref_ as *const _),
41            Self::ItemFn(ref_) => RawScope::ItemFn(ref_ as *const _),
42            Self::Block(ref_) => RawScope::Block(ref_ as *const _),
43        }
44    }
45}
46
47#[derive(Clone, Copy)]
48pub(crate) enum RawScope {
49    Mod(*const syn::ItemMod),
50    ItemFn(*const syn::ItemFn),
51    Block(*const syn::Block),
52}
53
54// === EvaluateArrayLength ===
55
56pub(crate) trait EvaluateArrayLength<'gcx> {
57    fn eval_array_len(&mut self, expr: &syn::Expr) -> TriResult<ArrayLen, ()>;
58}
59
60#[cfg(test)]
61pub(crate) mod test_help {
62    use super::EvaluateArrayLength;
63    use crate::{err, semantic::tree::ArrayLen, TriResult};
64
65    pub(crate) struct TestUsizeEvaluator;
66
67    impl EvaluateArrayLength<'static> for TestUsizeEvaluator {
68        fn eval_array_len(&mut self, expr: &syn::Expr) -> TriResult<ArrayLen, ()> {
69            let syn::Expr::Lit(expr_lit) = expr else {
70                return err!(hard, "test logic host cannot evaluate complex exprs");
71            };
72            let syn::Lit::Int(int) = &expr_lit.lit else {
73                return err!(hard, "test logic host cannot evaluate complex exprs");
74            };
75            match int.base10_parse() {
76                Ok(n) => Ok(ArrayLen::Fixed(n)),
77                Err(e) => err!(hard, "{e:?}"),
78            }
79        }
80    }
81}