1use ahash::HashMap;
2use serde::ser::SerializeMap;
3use serde::{Serialize, Serializer};
4use std::sync::Arc;
5use thiserror::Error;
6
7use crate::compiler::{Compiler, CompilerError, Opcode};
8use crate::expression::{OpcodeCache, Standard, Unary};
9use crate::lexer::{Lexer, LexerError};
10use crate::parser::{Parser, ParserError};
11use crate::variable::Variable;
12use crate::vm::{VMError, VM};
13use crate::{Expression, ExpressionKind};
14use bumpalo::Bump;
15
16#[derive(Debug)]
22pub struct Isolate {
23 lexer: Lexer,
24 compiler: Compiler,
25 vm: VM,
26
27 bump: Bump,
28
29 environment: Option<Variable>,
30 references: HashMap<String, Variable>,
31 cache: Option<Arc<OpcodeCache>>,
32}
33
34impl Isolate {
35 pub fn new() -> Self {
36 Self {
37 lexer: Lexer::new(),
38 compiler: Compiler::new(),
39 vm: VM::new(),
40
41 bump: Bump::new(),
42
43 environment: None,
44 references: Default::default(),
45 cache: None,
46 }
47 }
48
49 pub fn with_environment(variable: Variable) -> Self {
50 let mut isolate = Isolate::new();
51 isolate.set_environment(variable);
52
53 isolate
54 }
55
56 pub fn with_cache(mut self, cache: Option<Arc<OpcodeCache>>) -> Self {
57 self.cache = cache;
58 self
59 }
60
61 pub fn set_environment(&mut self, variable: Variable) {
62 self.environment.replace(variable);
63 self.references.clear();
64 }
65
66 pub fn set_cache(&mut self, cache: Arc<OpcodeCache>) {
67 self.cache = Some(cache);
68 }
69
70 pub fn update_environment<F>(&mut self, mut updater: F)
71 where
72 F: FnMut(Option<&mut Variable>),
73 {
74 updater(self.environment.as_mut());
75 }
76
77 pub fn set_reference(&mut self, reference: &str) -> Result<(), IsolateError> {
78 let reference_value = match self.references.get(reference) {
79 Some(value) => value.clone(),
80 None => {
81 let result = self.run_standard(reference)?;
82 self.references
83 .insert(reference.to_string(), result.clone());
84 result
85 }
86 };
87
88 self.set_reference_value(reference_value)
89 }
90
91 pub fn set_reference_value(&mut self, value: Variable) -> Result<(), IsolateError> {
92 if !matches!(&mut self.environment, Some(Variable::Object(_))) {
93 self.environment.replace(Variable::empty_object());
94 }
95
96 let Some(Variable::Object(environment_object_ref)) = &self.environment else {
97 return Err(IsolateError::ReferenceError);
98 };
99
100 let mut environment_object = environment_object_ref.borrow_mut();
101 environment_object.insert(Variable::dollar_key(), value);
102
103 Ok(())
104 }
105
106 pub fn get_reference(&self, reference: &str) -> Option<Variable> {
107 self.references.get(reference).cloned()
108 }
109
110 fn run_internal(&mut self, source: &str, kind: ExpressionKind) -> Result<(), IsolateError> {
111 self.bump.reset();
112 let bump = &self.bump;
113
114 let tokens = self.lexer.tokenize(bump, source)?;
115
116 let base_parser = Parser::try_new(&tokens, bump)?;
117 let parser_result = match kind {
118 ExpressionKind::Unary => base_parser.unary().parse(),
119 ExpressionKind::Standard => base_parser.standard().parse(),
120 };
121
122 parser_result.error()?;
123
124 self.compiler.compile(parser_result.root)?;
125
126 Ok(())
127 }
128
129 pub fn compile_standard(&mut self, source: &str) -> Result<Expression<Standard>, IsolateError> {
130 self.run_internal(source, ExpressionKind::Standard)?;
131 let bytecode = self.compiler.get_bytecode().to_vec();
132
133 Ok(Expression::new_standard(Arc::from(bytecode)))
134 }
135
136 pub fn run_standard(&mut self, source: &str) -> Result<Variable, IsolateError> {
137 let cached = self
138 .cache
139 .as_ref()
140 .and_then(|c| c.standard.get(source).cloned());
141 if let Some(codes) = cached {
142 return self.run_compiled(codes.as_ref());
143 }
144
145 self.run_internal(source, ExpressionKind::Standard)?;
146
147 let bytecode = self.compiler.get_bytecode();
148 let result = self
149 .vm
150 .run(bytecode, self.environment.clone().unwrap_or(Variable::Null))?;
151
152 Ok(result)
153 }
154 pub fn run_compiled(&mut self, source: &[Opcode]) -> Result<Variable, IsolateError> {
155 let result = self
156 .vm
157 .run(source, self.environment.clone().unwrap_or(Variable::Null))?;
158
159 Ok(result)
160 }
161
162 pub fn compile_unary(&mut self, source: &str) -> Result<Expression<Unary>, IsolateError> {
163 self.run_internal(source, ExpressionKind::Unary)?;
164 let bytecode = self.compiler.get_bytecode().to_vec();
165
166 Ok(Expression::new_unary(Arc::from(bytecode)))
167 }
168
169 pub fn run_unary(&mut self, source: &str) -> Result<bool, IsolateError> {
170 let cached = self
171 .cache
172 .as_ref()
173 .and_then(|c| c.unary.get(source).cloned());
174 if let Some(codes) = cached {
175 return self.run_unary_compiled(codes.as_ref());
176 }
177
178 self.run_internal(source, ExpressionKind::Unary)?;
179
180 let bytecode = self.compiler.get_bytecode();
181 let result = self
182 .vm
183 .run(bytecode, self.environment.clone().unwrap_or(Variable::Null))?;
184
185 result.as_bool().ok_or_else(|| IsolateError::ValueCastError)
186 }
187
188 pub fn run_unary_compiled(&mut self, code: &[Opcode]) -> Result<bool, IsolateError> {
189 let result = self
190 .vm
191 .run(code, self.environment.clone().unwrap_or(Variable::Null))?;
192
193 result.as_bool().ok_or_else(|| IsolateError::ValueCastError)
194 }
195}
196
197#[derive(Debug, Error)]
199pub enum IsolateError {
200 #[error("Lexer error: {source}")]
201 LexerError { source: LexerError },
202
203 #[error("Parser error: {source}")]
204 ParserError { source: ParserError },
205
206 #[error("Compiler error: {source}")]
207 CompilerError { source: CompilerError },
208
209 #[error("VM error: {source}")]
210 VMError { source: VMError },
211
212 #[error("Value cast error")]
213 ValueCastError,
214
215 #[error("Failed to compute reference")]
216 ReferenceError,
217
218 #[error("Missing context reference")]
219 MissingContextReference,
220}
221
222impl Serialize for IsolateError {
223 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
224 where
225 S: Serializer,
226 {
227 let mut map = serializer.serialize_map(None)?;
228
229 match &self {
230 IsolateError::ReferenceError => {
231 map.serialize_entry("type", "referenceError")?;
232 }
233 IsolateError::MissingContextReference => {
234 map.serialize_entry("type", "missingContextReference")?;
235 }
236 IsolateError::ValueCastError => {
237 map.serialize_entry("type", "valueCastError")?;
238 }
239 IsolateError::LexerError { source } => {
240 map.serialize_entry("type", "lexerError")?;
241 map.serialize_entry("source", source.to_string().as_str())?;
242 }
243 IsolateError::ParserError { source } => {
244 map.serialize_entry("type", "parserError")?;
245 map.serialize_entry("source", source.to_string().as_str())?;
246 }
247 IsolateError::CompilerError { source } => {
248 map.serialize_entry("type", "compilerError")?;
249 map.serialize_entry("source", source.to_string().as_str())?;
250 }
251 IsolateError::VMError { source } => {
252 map.serialize_entry("type", "vmError")?;
253 map.serialize_entry("source", source.to_string().as_str())?;
254 }
255 }
256
257 map.end()
258 }
259}
260
261impl From<LexerError> for IsolateError {
262 fn from(source: LexerError) -> Self {
263 IsolateError::LexerError { source }
264 }
265}
266
267impl From<ParserError> for IsolateError {
268 fn from(source: ParserError) -> Self {
269 IsolateError::ParserError { source }
270 }
271}
272
273impl From<VMError> for IsolateError {
274 fn from(source: VMError) -> Self {
275 IsolateError::VMError { source }
276 }
277}
278
279impl From<CompilerError> for IsolateError {
280 fn from(source: CompilerError) -> Self {
281 IsolateError::CompilerError { source }
282 }
283}