spwn/
globals.rs

1use internment::Intern;
2
3///types and functions used by the compiler
4use crate::builtin::*;
5use crate::compiler::BUILTIN_STORAGE;
6use crate::compiler::NULL_STORAGE;
7use crate::compiler_info::CodeArea;
8use crate::context::BreakType;
9use crate::context::FullContext;
10use crate::levelstring::GdObj;
11
12use crate::compiler_types::*;
13use crate::value::*;
14
15//use std::boxed::Box;
16use crate::compiler_info::CompilerInfo;
17use crate::value_storage::*;
18use std::collections::HashMap;
19
20use std::path::PathBuf;
21
22use crate::compiler::RuntimeError;
23
24#[allow(non_snake_case)]
25pub struct Globals {
26    //counters for arbitrary groups
27    pub closed_groups: u16,
28    pub closed_colors: u16,
29    pub closed_blocks: u16,
30    pub closed_items: u16,
31
32    pub path: Intern<PathBuf>,
33
34    pub lowest_y: HashMap<u32, u16>,
35    pub stored_values: ValStorage,
36    pub val_id: StoredValue,
37
38    pub type_ids: HashMap<String, (u16, CodeArea)>,
39    pub type_id_count: u16,
40
41    pub func_ids: Vec<FunctionId>,
42    pub objects: Vec<GdObj>,
43
44    pub prev_imports: HashMap<ImportType, (StoredValue, Implementations)>,
45
46    pub trigger_order: usize,
47
48    pub uid_counter: usize,
49    pub implementations: Implementations,
50
51    pub sync_groups: Vec<SyncGroup>,
52    pub includes: Vec<PathBuf>,
53
54    pub TYPE_MEMBER_NAME: Intern<String>,
55    pub SELF_MEMBER_NAME: Intern<String>,
56    pub OR_BUILTIN: Intern<String>,
57    pub AND_BUILTIN: Intern<String>,
58    pub ASSIGN_BUILTIN: Intern<String>,
59    pub OBJ_KEY_ID: Intern<String>,
60    pub OBJ_KEY_PATTERN: Intern<String>,
61}
62
63impl Globals {
64    pub fn get_val_fn_context(
65        &self,
66        p: StoredValue,
67        info: CompilerInfo,
68    ) -> Result<Group, RuntimeError> {
69        match self.stored_values.map.get(&p) {
70            Some(val) => Ok(val.fn_context),
71            None => Err(RuntimeError::CustomError(crate::compiler::create_error(
72                info,
73                "Pointer points to no data! (this is probably a bug, please contact a developer)",
74                &[],
75                None,
76            ))),
77        }
78    }
79    pub fn is_mutable(&self, p: StoredValue) -> bool {
80        match self.stored_values.map.get(&p) {
81            Some(val) => val.mutable,
82            None => unreachable!("{}", p),
83        }
84    }
85
86    pub fn can_mutate(&self, p: StoredValue) -> bool {
87        self.is_mutable(p)
88    }
89
90    // pub fn get_lifetime(&self, p: StoredValue) -> Option<u16> {
91    //     match self.stored_values.map.get(&p) {
92    //         Some(val) => val.lifetime,
93    //         None => unreachable!(),
94    //     }
95    // }
96
97    // pub fn get_fn_context(&self, p: StoredValue) -> Group {
98    //     match self.stored_values.map.get(&p) {
99    //         Some(val) => val.fn_context,
100    //         None => unreachable!(),
101    //     }
102    // }
103
104    pub fn get_area(&self, p: StoredValue) -> CodeArea {
105        match self.stored_values.map.get(&p) {
106            Some(val) => val.def_area,
107            None => unreachable!(),
108        }
109    }
110
111    pub fn get_type_str(&self, p: StoredValue) -> String {
112        let val = &self.stored_values[p];
113        let typ = match val {
114            Value::Dict(d) => {
115                if let Some(s) = d.get(&self.TYPE_MEMBER_NAME) {
116                    match self.stored_values[*s] {
117                        Value::TypeIndicator(t) => t,
118                        _ => unreachable!(),
119                    }
120                } else {
121                    val.to_num(self)
122                }
123            }
124            _ => val.to_num(self),
125        };
126        find_key_for_value(&self.type_ids, typ).unwrap().clone()
127    }
128
129    pub fn new(path: PathBuf) -> Self {
130        let storage = ValStorage::new();
131        let mut globals = Globals {
132            closed_groups: 0,
133            closed_colors: 0,
134            closed_blocks: 0,
135            closed_items: 0,
136            path: Intern::new(path),
137
138            lowest_y: HashMap::new(),
139
140            type_ids: HashMap::new(),
141
142            prev_imports: HashMap::new(),
143            type_id_count: 0,
144            trigger_order: 0,
145            uid_counter: 0,
146
147            val_id: storage.map.len() as StoredValue,
148            stored_values: storage,
149            func_ids: vec![FunctionId {
150                parent: None,
151                width: None,
152                obj_list: Vec::new(),
153            }],
154            objects: Vec::new(),
155            implementations: HashMap::new(),
156            sync_groups: vec![SyncGroup {
157                parts: vec![0],
158                groups_used: Vec::new(),
159            }],
160            includes: Vec::new(),
161            TYPE_MEMBER_NAME: Intern::new(String::from("type")),
162            SELF_MEMBER_NAME: Intern::new(String::from("self")),
163            OR_BUILTIN: Intern::new(String::from("_or_")),
164            AND_BUILTIN: Intern::new(String::from("_and_")),
165            ASSIGN_BUILTIN: Intern::new(String::from("_assign_")),
166            OBJ_KEY_ID: Intern::new(String::from("id")),
167            OBJ_KEY_PATTERN: Intern::new(String::from("pattern")),
168        };
169
170        let mut add_type = |name: &str, id: u16| {
171            globals
172                .type_ids
173                .insert(String::from(name), (id, CodeArea::new()))
174        };
175
176        add_type("group", 0);
177        add_type("color", 1);
178        add_type("block", 2);
179        add_type("item", 3);
180        add_type("number", 4);
181        add_type("bool", 5);
182        add_type("trigger_function", 6);
183        add_type("dictionary", 7);
184        add_type("macro", 8);
185        add_type("string", 9);
186        add_type("array", 10);
187        add_type("object", 11);
188        add_type("spwn", 12);
189        add_type("builtin", 13);
190        add_type("type_indicator", 14);
191        add_type("NULL", 15);
192        add_type("trigger", 16);
193        add_type("range", 17);
194        add_type("pattern", 18);
195        add_type("object_key", 19);
196        add_type("epsilon", 20);
197
198        globals.type_id_count = globals.type_ids.len() as u16;
199
200        globals
201    }
202
203    // pub fn clean_up(&mut self, full_context: &mut FullContext, mut removed: HashSet<usize>) {
204    //     let mut used_values = HashSet::new();
205
206    //     // for l in self.implementations.values() {
207    //     //     for (v, _) in l.values() {
208    //     //         used_values.insert(*v);
209    //     //     }
210    //     // }
211    //     for c in full_context.with_breaks() {
212    //         used_values.extend(c.inner().variables.iter().map(|(_, (a, _))| *a));
213    //         // used_values.insert(c.inner().return_value);
214    //         // used_values.insert(c.inner().return_value2);
215    //         match c.inner().broken {
216    //             Some((BreakType::Macro(Some(v), _), _)) => {
217    //                 used_values.insert(v);
218    //             }
219    //             Some((BreakType::Switch(v), _)) => {
220    //                 used_values.insert(v);
221    //             }
222    //             _ => (),
223    //         };
224    //     }
225    //     let mut all_used_values = HashSet::new();
226    //     for v in used_values {
227    //         all_used_values.extend(get_all_ptrs_used(v, self));
228    //     }
229
230    //     // for v in all_used_values.iter() {
231    //     //     dbg!(v, self.stored_values[*v].clone());
232    //     // }
233    //     all_used_values.insert(BUILTIN_STORAGE);
234    //     all_used_values.insert(NULL_STORAGE);
235
236    //     removed.retain(|a| !all_used_values.contains(a));
237
238    //     self.stored_values
239    //         .map
240    //         .retain(|a, _| -> bool { !removed.contains(a) });
241    // }
242    pub fn push_new_preserved(&mut self) {
243        self.stored_values.preserved_stack.push(Vec::new());
244    }
245
246    pub fn pop_preserved(&mut self) {
247        self.stored_values.preserved_stack.pop();
248    }
249
250    pub fn push_preserved_val(&mut self, val: StoredValue) {
251        self.stored_values
252            .preserved_stack
253            .last_mut()
254            .unwrap()
255            .push(val);
256    }
257
258    pub fn collect_garbage(&mut self, contexts: &mut FullContext) {
259        //gc
260
261        //mark
262        self.stored_values.mark(NULL_STORAGE);
263        self.stored_values.mark(BUILTIN_STORAGE);
264
265        unsafe {
266            let root_context = contexts
267                .with_breaks()
268                .next()
269                .unwrap()
270                .inner()
271                .root_context_ptr
272                .as_mut()
273                .unwrap();
274
275            for c in root_context.with_breaks() {
276                for stack in c.inner().get_variables().values() {
277                    for (v, _) in stack.iter() {
278                        self.stored_values.mark(*v);
279                    }
280                }
281
282                match c.inner().broken {
283                    Some((BreakType::Macro(Some(v), _), _)) | Some((BreakType::Switch(v), _)) => {
284                        self.stored_values.mark(v);
285                    }
286                    _ => (),
287                }
288
289                // for split contexts
290                self.stored_values.mark(c.inner().return_value);
291                self.stored_values.mark(c.inner().return_value2);
292            }
293            for s in self.stored_values.preserved_stack.clone() {
294                for v in s {
295                    self.stored_values.mark(v);
296                }
297            }
298            for imp in self.implementations.values() {
299                for (v, _) in imp.values() {
300                    self.stored_values.mark(*v);
301                }
302            }
303        }
304
305        for (v, imp) in self.prev_imports.values() {
306            for imp in imp.values() {
307                for (v, _) in imp.values() {
308                    self.stored_values.mark(*v);
309                }
310            }
311
312            self.stored_values.mark(*v);
313        }
314        //dbg!(&self.stored_values.map);
315
316        //sweep
317        self.stored_values.sweep();
318
319        self.stored_values.prev_value_count = self.stored_values.map.len() as u32;
320    }
321}