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