mtots_core/base/gl/
mod.rs1use crate::annotate;
2use crate::compile;
3use crate::ArgSpec;
4use crate::Behavior;
5use crate::Class;
6use crate::ConstVal;
7use crate::DocStr;
8use crate::Error;
9use crate::Handle;
10use crate::HandleBehaviorBuilder;
11use crate::Key;
12use crate::LexErrorKind;
13use crate::Lexer;
14use crate::List;
15use crate::Map;
16use crate::Mark;
17use crate::Module;
18use crate::ModuleDisplay;
19use crate::NativeFunction;
20use crate::NativeGenerator;
21use crate::Parser;
22use crate::RcStr;
23use crate::Result;
24use crate::ResumeResult;
25use crate::Set;
26use crate::Source;
27use crate::Value;
28use std::any::Any;
29use std::any::TypeId;
30use std::cell::Ref;
31use std::cell::RefCell;
32use std::cell::RefMut;
33use std::cmp;
34use std::collections::hash_map::Entry;
35use std::collections::HashMap;
36use std::collections::HashSet;
37use std::convert::TryFrom;
38use std::path::PathBuf;
39use std::rc::Rc;
40mod bltn;
41mod clss;
42mod ge;
43mod hist;
44mod hnd;
45mod load;
46mod nm;
47mod parse;
48mod stash;
49mod trampoline;
50pub use clss::*;
51pub use ge::*;
52pub use nm::*;
53pub use stash::*;
54
55pub struct Globals {
57 trace: Vec<Mark>,
59
60 lexer: Lexer,
62 parser: Parser,
63
64 module_map: HashMap<RcStr, Rc<Module>>,
66 native_modules: HashMap<RcStr, NativeModule>,
67 source_roots: Vec<RcStr>,
68 main_module: Option<RcStr>,
69
70 class_manager: ClassManager,
72 builtins: HashMap<RcStr, Value>,
73 repl_scope: Option<HashMap<RcStr, Rc<RefCell<Value>>>>,
74
75 handle_class_map: HashMap<TypeId, Rc<Class>>,
77
78 stash: Stash,
82
83 trampoline: Option<Box<dyn FnOnce(Globals)>>,
88
89 argv: Option<Vec<RcStr>>,
91
92 #[cfg(feature = "line")]
95 line: rustyline::Editor<()>,
96}
97
98impl Globals {
99 pub fn new() -> Self {
100 let class_manager = ClassManager::new();
101 let builtins = Self::bootstrap_new_builtins(&class_manager);
102 #[cfg(feature = "line")]
103 let line = Self::new_line_editor();
104 let mut globals = Self {
105 trace: vec![],
106 lexer: Lexer::new(),
107 parser: Parser::new(),
108 module_map: HashMap::new(),
109 native_modules: HashMap::new(),
110 source_roots: vec![],
111 main_module: None,
112 class_manager,
113 builtins,
114 repl_scope: None,
115 handle_class_map: HashMap::new(),
116 stash: Default::default(),
117 trampoline: None,
118 argv: None,
119 #[cfg(feature = "line")]
120 line,
121 };
122 globals.add_builtin_native_libraries();
123 globals
124 }
125 pub fn trace(&self) -> &Vec<Mark> {
126 &self.trace
127 }
128 pub fn trace_unwind(&mut self, len: usize) {
129 self.trace.truncate(len);
130 }
131 pub(crate) fn trace_push(&mut self, mark: Mark) {
132 self.trace.push(mark);
133 }
134 pub(crate) fn trace_pop(&mut self) {
135 self.trace.pop().unwrap();
136 }
137 pub fn register_module(&mut self, module: Rc<Module>) -> Result<()> {
138 let name = module.name().clone();
139 if self.module_map.contains_key(&name) {
140 return Err(rterr!("Module {:?} registered twice", name));
141 }
142 self.module_map.insert(name, module);
143 Ok(())
144 }
145 pub fn class_manager(&self) -> &ClassManager {
146 &self.class_manager
147 }
148 pub fn get_main(&self) -> &Option<RcStr> {
149 &self.main_module
150 }
151 pub fn set_main(&mut self, main_module_name: RcStr) {
152 self.main_module = Some(main_module_name);
153 }
154 pub fn exec(&mut self, source: Rc<Source>) -> Result<Rc<Module>> {
155 let name = source.name().clone();
156 let path = source.path().clone();
157 let mut display = self.parse(source)?;
158 annotate(&mut display)?;
159 let code = compile(&display)?;
160 let mut map = self.builtins.clone();
161 map.insert("__name".into(), name.into());
162 if let Some(path) = path {
163 if let Some(pathstr) = path.to_str() {
164 map.insert("__file".into(), pathstr.into());
165 }
166 }
167 code.apply_for_module(self, &map)
168 }
169 pub fn exec_str(&mut self, name: &str, path: Option<&str>, data: &str) -> Result<Rc<Module>> {
170 self.exec(
171 Source::new(
172 name.into(),
173 path.map(PathBuf::from).map(Rc::from),
174 data.into(),
175 )
176 .into(),
177 )
178 }
179 pub fn exec_repl(&mut self, data: &str) -> Result<Value> {
180 let mut display = self.parse(Rc::new(Source::new("[repl]".into(), None, data.into())))?;
181 annotate(&mut display)?;
182 let code = compile(&display)?;
183 code.apply_for_repl(self)
184 }
185 pub(super) fn repl_scope_mut(&mut self) -> &mut HashMap<RcStr, Rc<RefCell<Value>>> {
186 if self.repl_scope.is_none() {
187 let mut scope = HashMap::new();
188 for (key, val) in &self.builtins {
189 scope.insert(key.clone(), Rc::new(RefCell::new(val.clone())));
190 }
191 self.repl_scope = Some(scope);
192 }
193 self.repl_scope.as_mut().unwrap()
194 }
195 pub fn argv(&self) -> &Option<Vec<RcStr>> {
196 &self.argv
197 }
198 pub fn set_argv(&mut self, argv: Vec<RcStr>) {
199 self.argv = Some(argv);
200 }
201}