Skip to main content

compiler/
symbol.rs

1use dynamic::{ConstIntOp, Dynamic, Type};
2use parser::Stmt;
3use smol_str::SmolStr;
4use std::{collections::BTreeMap, rc::Rc, sync::Arc};
5
6use super::Capture;
7
8#[derive(Debug, Clone, Default)]
9pub enum Symbol {
10    #[default]
11    Null,
12    Const {
13        value: Dynamic,
14        ty: Type,
15        is_pub: bool,
16    },
17    Static {
18        value: Option<Dynamic>,
19        ty: Type,
20        is_pub: bool,
21    },
22    Struct(Type, bool),
23    Fn {
24        ty: Type,
25        args: Vec<SmolStr>,
26        generic_params: Vec<Type>,
27        cap: Capture,
28        body: Arc<Stmt>,
29        is_pub: bool,
30    },
31    Native(Type),
32}
33
34impl Symbol {
35    pub fn native(tys: Vec<Type>, ret: Type) -> Self {
36        Self::Native(Type::Fn { tys, ret: Rc::new(ret) })
37    }
38
39    pub fn is_pub(&self) -> bool {
40        match self {
41            Self::Const { value: _, ty: _, is_pub } => *is_pub,
42            Self::Static { value: _, ty: _, is_pub } => *is_pub,
43            Self::Struct(_, is_pub) => *is_pub,
44            Self::Fn { ty: _, args: _, generic_params: _, cap: _, body: _, is_pub } => *is_pub,
45            _ => true,
46        }
47    }
48
49    pub fn is_fn(&self) -> bool {
50        match self {
51            Self::Fn { ty: _, args: _, generic_params: _, cap: _, body: _, is_pub: _ } => true,
52            Self::Native(_) => true,
53            _ => false,
54        }
55    }
56}
57
58use anyhow::{Result, anyhow};
59use indexmap::IndexMap;
60
61pub fn eval_const_int_type(ty: &Type) -> Option<i64> {
62    match ty {
63        Type::ConstInt(value) => Some(*value),
64        Type::ConstBinary { op, left, right } => {
65            let left = eval_const_int_type(left)?;
66            let right = eval_const_int_type(right)?;
67            match op {
68                ConstIntOp::Add => Some(left + right),
69                ConstIntOp::Sub => Some(left - right),
70                ConstIntOp::Mul => Some(left * right),
71                ConstIntOp::Div => (right != 0).then_some(left / right),
72                ConstIntOp::Mod => (right != 0).then_some(left % right),
73            }
74        }
75        _ => None,
76    }
77}
78
79pub fn substitute_type(ty: &Type, params: &[Type], args: &[Type]) -> Type {
80    match ty {
81        Type::Ident { name, params: nested } if nested.is_empty() => {
82            params.iter().position(|param| matches!(param, Type::Ident { name: param_name, params } if params.is_empty() && param_name == name)).map(|idx| args[idx].clone()).unwrap_or_else(|| ty.clone())
83        }
84        Type::Ident { name, params: nested } => Type::Ident { name: name.clone(), params: nested.iter().map(|param| substitute_type(param, params, args)).collect() },
85        Type::Struct { params: struct_params, fields } => Type::Struct {
86            params: struct_params.iter().map(|param| substitute_type(param, params, args)).collect(),
87            fields: fields.iter().map(|(name, field_ty)| (name.clone(), substitute_type(field_ty, params, args))).collect(),
88        },
89        Type::Vec(elem, len) => Type::Vec(Rc::new(substitute_type(elem, params, args)), *len),
90        Type::Array(elem, len) => Type::Array(Rc::new(substitute_type(elem, params, args)), *len),
91        Type::ArrayParam(elem, len) => Type::ArrayParam(Rc::new(substitute_type(elem, params, args)), Rc::new(substitute_type(len, params, args))),
92        Type::ConstBinary { op, left, right } => {
93            let left = substitute_type(left, params, args);
94            let right = substitute_type(right, params, args);
95            let ty = Type::ConstBinary { op: *op, left: Rc::new(left), right: Rc::new(right) };
96            eval_const_int_type(&ty).map(Type::ConstInt).unwrap_or(ty)
97        }
98        Type::Fn { tys, ret } => Type::Fn { tys: tys.iter().map(|ty| substitute_type(ty, params, args)).collect(), ret: Rc::new(substitute_type(ret, params, args)) },
99        Type::Symbol { id, params: nested } => Type::Symbol { id: *id, params: nested.iter().map(|param| substitute_type(param, params, args)).collect() },
100        Type::Tuple(items) => Type::Tuple(items.iter().map(|item| substitute_type(item, params, args)).collect()),
101        _ => ty.clone(),
102    }
103}
104
105#[derive(Clone, Default)]
106pub struct SymbolTable {
107    pub symbols: IndexMap<SmolStr, Symbol>,
108    modules: BTreeMap<SmolStr, BTreeMap<SmolStr, u32>>,
109    pub roots: Vec<SmolStr>,
110}
111
112impl SymbolTable {
113    pub fn add_to_module(&mut self, module: &str, name: SmolStr, s: Symbol) -> Result<u32> {
114        let full_name: SmolStr = format!("{}::{}", module, name).into();
115        let id = self.symbols.insert_full(full_name, s).0 as u32;
116        let module_symbols = self.modules.get_mut(module).ok_or_else(|| anyhow!("模块 {} 不存在", module))?;
117        module_symbols.insert(name, id);
118        Ok(id)
119    }
120    pub fn get_symbol(&self, idx: u32) -> Result<(&SmolStr, &Symbol)> {
121        self.symbols.get_index(idx as usize).ok_or(anyhow!("未发现符号 {}", idx))
122    }
123
124    pub fn get_symbol_mut(&mut self, idx: u32) -> Option<(&SmolStr, &mut Symbol)> {
125        self.symbols.get_index_mut(idx as usize)
126    }
127
128    pub fn symbol(&self, name: &str) -> Vec<(SmolStr, u32)> {
129        self.modules.get(name).map(|m| m.iter().map(|(name, id)| (name.clone(), *id)).collect()).unwrap_or(Vec::new())
130    }
131
132    pub fn disassemble(&self, name: &str) -> Result<String> {
133        let id = self.get_id(name)?;
134        let (name, s) = self.get_symbol(id)?;
135        if let Symbol::Fn { ty, args, generic_params: _, cap, body, is_pub } = s {
136            if *is_pub { Ok(format!("pub {} {:?} {:?} {:?}\n{}", name, ty, args, cap, body)) } else { Ok(format!("{} {:?} {:?} {:?}\n{}", name, ty, args, cap, body)) }
137        } else {
138            Err(anyhow!("未发现符号 {}", name))
139        }
140    }
141
142    pub fn get_field(&self, ty: &Type, name: &str) -> Result<(usize, Type)> {
143        //原生类型的函数 is_map is_list 或者 sqrt
144        let id = match ty {
145            Type::Any => {
146                if let Ok(id) = self.get_id("Any")
147                    && let Ok((_, Symbol::Struct(any_ty, _))) = self.get_symbol(id)
148                    && let Ok((idx, field_ty)) = any_ty.get_field(name)
149                {
150                    return Ok((idx, field_ty.clone()));
151                }
152                match name {
153                    "is_map" | "is_list" | "is_string" | "is_null" | "contains" | "starts_with" => return Ok((usize::MAX, Type::Bool)),
154                    "len" => return Ok((usize::MAX, Type::I32)),
155                    _ => return Ok((usize::MAX, Type::Any)),
156                }
157            }
158            Type::Struct { params: _, fields: _ } => {
159                return ty.get_field(name).map(|(idx, ty)| (idx, ty.clone()));
160            }
161            Type::Str => {
162                let any_method = match name {
163                    "len" | "contains" | "split" | "starts_with" | "is_string" | "is_null" => format!("Any::{}", name),
164                    _ => return Err(anyhow!("未发现 symbol {:?} {}", ty, name)),
165                };
166                return Ok((usize::MAX, Type::Symbol { id: self.get_id(&any_method)?, params: Vec::new() }));
167            }
168            Type::Symbol { id, params: _ } => *id,
169            Type::Vec(_, _) => self.get_id("Vec")?,
170            Type::Fn { tys: _, ret } => {
171                return self.get_field(ret, name);
172            }
173            _ => {
174                //增加一个外部函数定义
175                if matches!(name, "is_map" | "is_list" | "is_string" | "is_null") {
176                    return Ok((usize::MAX, Type::Symbol { id: self.get_id(&format!("Any::{}", name))?, params: Vec::new() }));
177                }
178                return Err(anyhow!("未发现 symbol {:?} {}", ty, name));
179            }
180        };
181        let (_, s) = self.get_symbol(id)?;
182        if let Symbol::Struct(s, _) = s {
183            return s.get_field(name).and_then(|(idx, ty)| Ok((idx, ty.clone())));
184        };
185        Err(anyhow!("未发现 field {:?} {}", ty, name))
186    }
187
188    pub fn get_type(&self, ty: &Type) -> Result<Type> {
189        match ty {
190            Type::Ident { name, params } => {
191                let params = params.iter().map(|param| self.get_type(param)).collect::<Result<Vec<_>>>()?;
192                if name.as_str() == "Vec" && params.len() == 1 {
193                    return Ok(Type::Vec(Rc::new(params[0].clone()), 0));
194                }
195                let id = self.get_id(&name)?;
196                if let (_, Symbol::Struct(ty, _)) = self.get_symbol(id)? {
197                    if let Type::Struct { params: generic_params, .. } = ty
198                        && !generic_params.is_empty()
199                        && generic_params.len() == params.len()
200                    {
201                        return self.get_type(&substitute_type(ty, generic_params, &params));
202                    }
203                    return self.get_type(ty);
204                }
205                return Ok(Type::Symbol { id, params });
206            }
207            Type::Symbol { id, params } => {
208                return match self.get_symbol(*id)? {
209                    (_, Symbol::Fn { ty, args: _, generic_params: _, cap: _, body: _, is_pub: _ }) => self.get_type(ty),
210                    (_, Symbol::Native(ty)) => self.get_type(ty),
211                    (_, Symbol::Struct(ty, _)) => {
212                        let params = params.iter().map(|param| self.get_type(param)).collect::<Result<Vec<_>>>()?;
213                        if let Type::Struct { params: generic_params, .. } = ty
214                            && !generic_params.is_empty()
215                            && generic_params.len() == params.len()
216                        {
217                            self.get_type(&substitute_type(ty, generic_params, &params))
218                        } else {
219                            self.get_type(ty)
220                        }
221                    }
222                    (_, s) => {
223                        println!("s-> {:?}", s);
224                        Ok(Type::Symbol { id: *id, params: params.clone() })
225                    }
226                };
227            }
228            Type::Vec(elem, len) => {
229                return Ok(Type::Vec(Rc::new(self.get_type(elem)?), *len));
230            }
231            Type::Array(elem, len) => {
232                return Ok(Type::Array(Rc::new(self.get_type(elem)?), *len));
233            }
234            Type::ArrayParam(elem, len) => {
235                let elem = self.get_type(elem)?;
236                let len = self.get_type(len)?;
237                if let Some(len) = eval_const_int_type(&len) {
238                    let len = u32::try_from(len).map_err(|_| anyhow!("数组长度超出 u32 范围"))?;
239                    return Ok(Type::Array(Rc::new(elem), len));
240                }
241                return Ok(Type::ArrayParam(Rc::new(elem), Rc::new(len)));
242            }
243            Type::ConstBinary { op, left, right } => {
244                let left = self.get_type(left)?;
245                let right = self.get_type(right)?;
246                let ty = Type::ConstBinary { op: *op, left: Rc::new(left), right: Rc::new(right) };
247                return Ok(eval_const_int_type(&ty).map(Type::ConstInt).unwrap_or(ty));
248            }
249            Type::Fn { tys, ret } => {
250                return Ok(Type::Fn { tys: tys.iter().map(|ty| self.get_type(ty)).collect::<Result<Vec<_>>>()?, ret: Rc::new(self.get_type(ret)?) });
251            }
252            Type::Struct { params, fields } => {
253                return Ok(Type::Struct {
254                    params: params.iter().map(|param| self.get_type(param)).collect::<Result<Vec<_>>>()?,
255                    fields: fields.iter().map(|(name, ty)| if matches!(ty, Type::Symbol { .. }) { Ok((name.clone(), ty.clone())) } else { self.get_type(ty).map(|ty| (name.clone(), ty)) }).collect::<Result<Vec<_>>>()?,
256                });
257            }
258            _ => {}
259        }
260        Ok(ty.clone())
261    }
262
263    pub fn add_module(&mut self, name: SmolStr) {
264        let len = self.roots.len();
265        if let Some(pos) = self.roots.iter().position(|r| r.as_str() == name.as_str()) {
266            if pos != len - 1 {
267                self.roots.swap(pos, len - 1);
268            }
269        } else {
270            self.roots.push(name.clone());
271        }
272        self.modules.insert(name, BTreeMap::new());
273    }
274
275    pub fn pop_module(&mut self) {
276        //如果不想模块成为全局的 add_module 之后调用 pop_module
277        if let Some(last) = self.roots.pop() {
278            if let Some(names) = self.modules.get(&last).map(|m| {
279                let kvs: Vec<(SmolStr, u32)> = m.iter().map(|kv| (kv.0.clone(), *kv.1)).collect();
280                kvs.iter().filter_map(|kv| if !self.get_symbol(kv.1).map(|s| s.1.is_pub()).unwrap_or(false) { Some(kv.0.clone()) } else { None }).collect::<Vec<_>>()
281            }) {
282                if let Some(m) = self.modules.get_mut(&last) {
283                    for name in names {
284                        m.remove(&name); //删除非 pub 的符号
285                    }
286                }
287            }
288        }
289    }
290
291    pub fn get_id(&self, name: &str) -> Result<u32> {
292        if let Some(idx) = self.symbols.get_index_of(name) {
293            return Ok(idx as u32);
294        }
295        if let Some(id) = self.roots.iter().rev().find_map(|r| self.modules.get(r).and_then(|m| m.get(name))) {
296            return Ok(*id);
297        }
298        if let Some(id) = self.modules.values().find_map(|m| m.get(name)) {
299            return Ok(*id);
300        }
301        if let Some((mod_name, symbol_name)) = name.split_once("::") {
302            if let Some(m) = self.modules.get(mod_name) {
303                return m.get(symbol_name).copied().ok_or(anyhow!("{} 未发现", name));
304            }
305        }
306        self.roots.iter().find_map(|r| self.modules.get(r).and_then(|m| m.get(name))).copied().ok_or(anyhow!("{} 未发现", name))
307    }
308
309    pub fn add(&mut self, name: SmolStr, s: Symbol) -> u32 {
310        let root = self.roots.last().cloned().unwrap();
311        let id = self.symbols.insert_full(format!("{}::{}", root, name).into(), s).0 as u32;
312        self.modules.get_mut(&root).map(|m| m.insert(name, id));
313        id
314    }
315
316    pub fn add_global(&mut self, name: SmolStr, s: Symbol) -> u32 {
317        if let Some(idx) = self.symbols.get_index_of(name.as_str()) {
318            return idx as u32;
319        }
320        if let Some((mod_name, symbol_name)) = name.as_str().split_once("::") {
321            if let Some(m) = self.modules.get_mut(mod_name) {
322                if let Some(&id) = m.get(symbol_name) {
323                    return id;
324                }
325            }
326        }
327        let id = self.symbols.insert_full(name.clone(), s).0 as u32;
328        if let Some((mod_name, symbol_name)) = name.as_str().split_once("::") {
329            if let Some(m) = self.modules.get_mut(mod_name) {
330                m.insert(symbol_name.into(), id);
331            }
332        }
333        id
334    }
335
336    pub fn take(&mut self, id: u32) -> Option<Symbol> {
337        self.symbols.get_index_mut(id as usize).map(|(_, s)| std::mem::take(s))
338    }
339}