py_ast/semantic/
scope.rs

1use super::mangle::*;
2use py_declare::*;
3
4use std::collections::HashMap;
5use terl::*;
6
7pub struct Defines<M: Mangle = DefaultMangler> {
8    pub defs: Defs,
9    pub mangler: Mangler<M>,
10}
11
12impl<M: Mangle> Defines<M> {
13    /// # Return
14    ///
15    /// mangled_name
16    pub fn regist_fn(
17        &mut self,
18        fn_define: &crate::parse::FnDefine,
19        fn_sign: defs::FnSign,
20    ) -> Result<String> {
21        let mangled_name = self.mangler.mangle_fn(&fn_define.name, &fn_sign);
22
23        if let Some(previous) = self.defs.try_get_mangled(&mangled_name) {
24            let previous_define = previous
25                .sign_span
26                .make_message(format!("funcion {} has been definded here", fn_define.name));
27            let mut err = fn_sign
28                .sign_span
29                .make_error(format!("double define for function {}", fn_define.name))
30                .append(previous_define);
31            if previous.ty != fn_sign.ty {
32                err += "note: overload which only return type is differnet is not allowed";
33            }
34            err += format!("note: if you want to overload funcion {}, you can define them with different parameters",fn_define.name);
35            return Err(err);
36        }
37
38        self.defs.new_fn(&fn_define.name, &mangled_name, fn_sign);
39        Ok(mangled_name)
40    }
41}
42
43impl<M: Mangle> Default for Defines<M> {
44    fn default() -> Self {
45        Self {
46            defs: Default::default(),
47            mangler: Default::default(),
48        }
49    }
50}
51
52impl<M: Mangle> Defines<M> {
53    pub fn new(defs: Defs, mangler: Mangler<M>) -> Self {
54        Self { defs, mangler }
55    }
56}
57
58/// a scope that represents a fn's local scope
59///
60/// [`DeclareMap`] is used to picking overloads, declare var's types, etc
61///
62/// un processed ast move into this struct and then become [`mir::Statements`], mir misses
63/// a part of type information, and fn_call is not point to monomorphic fn
64///
65///
66/// then [`DeclareMap`] will declare them and output [`py_ir::Statements`],  or a [`Error`] will be thrown
67#[derive(Default)]
68pub struct FnScope {
69    // mangled
70    pub fn_name: String,
71    // a counter
72    temps: usize,
73    parameters: HashMap<String, GroupIdx>,
74    pub declare_map: DeclareGraph,
75}
76
77impl FnScope {
78    pub fn new<'p, PI, SI>(fn_name: impl ToString, params: PI, spans: SI) -> Self
79    where
80        PI: IntoIterator<Item = &'p defs::Parameter>,
81        SI: IntoIterator<Item = Span>,
82    {
83        let mut declare_map = DeclareGraph::default();
84        let parameters = spans
85            .into_iter()
86            .zip(params)
87            .map(|(at, param)| {
88                (
89                    param.name.clone(),
90                    declare_map.new_static_group(at, std::iter::once(param.ty.clone().into())),
91                )
92            })
93            .collect();
94
95        Self {
96            fn_name: fn_name.to_string(),
97            parameters,
98            declare_map,
99            ..Default::default()
100        }
101    }
102
103    #[inline]
104    pub fn temp_name(&mut self) -> String {
105        // whitespace to make temp name will not be accessed
106        (format!("_{}", self.temps), self.temps += 1).0
107    }
108
109    #[inline]
110    pub fn search_parameter(&mut self, name: &str) -> Option<defs::VarDef> {
111        self.parameters.get(name).map(|ty| defs::VarDef {
112            ty: *ty,
113            mutable: false,
114        })
115    }
116}
117
118#[derive(Default)]
119pub struct BasicScope {
120    // defines
121    pub vars: HashMap<String, defs::VarDef>,
122}
123
124pub struct BasicScopes {
125    // defines
126    scopes: Vec<BasicScope>,
127}
128
129impl std::ops::DerefMut for BasicScopes {
130    fn deref_mut(&mut self) -> &mut Self::Target {
131        &mut self.scopes
132    }
133}
134
135impl std::ops::Deref for BasicScopes {
136    type Target = Vec<BasicScope>;
137
138    fn deref(&self) -> &Self::Target {
139        &self.scopes
140    }
141}
142
143impl Default for BasicScopes {
144    fn default() -> Self {
145        Self {
146            scopes: vec![BasicScope::default()],
147        }
148    }
149}
150
151impl BasicScopes {
152    #[inline]
153    pub fn search_variable(&mut self, name: &str) -> Option<defs::VarDef> {
154        for scope in self.scopes.iter().rev() {
155            if let Some(var) = scope.vars.get(name) {
156                return Some(var.clone());
157            }
158        }
159        None
160    }
161
162    fn current_scope(&mut self) -> &mut BasicScope {
163        self.scopes.last_mut().unwrap()
164    }
165
166    pub fn regist_variable(&mut self, name: impl ToString, def: defs::VarDef) {
167        let name = name.to_string();
168        let current = self.current_scope();
169        current.vars.insert(name, def);
170    }
171}