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::scope::Scope;
12use crate::variable::Variable;
13use crate::vm::{VMError, VM};
14use crate::{Expression, ExpressionKind};
15use bumpalo::Bump;
16use zen_types::symbol::Symbol;
17
18#[derive(Debug)]
24pub struct Isolate {
25 lexer: Lexer,
26 compiler: Compiler,
27 vm: VM,
28
29 bump: Bump,
30
31 scope: Scope,
32 references: HashMap<String, Variable>,
33 cache: Option<Arc<OpcodeCache>>,
34}
35
36impl Isolate {
37 pub fn new() -> Self {
38 Self {
39 lexer: Lexer::new(),
40 compiler: Compiler::new(),
41 vm: VM::new(),
42
43 bump: Bump::new(),
44
45 scope: Scope::default(),
46 references: Default::default(),
47 cache: None,
48 }
49 }
50
51 pub fn with_environment(variable: Variable) -> Self {
52 let mut isolate = Isolate::new();
53 isolate.set_environment(variable);
54
55 isolate
56 }
57
58 pub fn with_cache(mut self, cache: Option<Arc<OpcodeCache>>) -> Self {
59 self.cache = cache;
60 self
61 }
62
63 pub fn set_environment(&mut self, variable: Variable) {
64 self.scope.set_base(variable);
65 self.references.clear();
66 }
67
68 pub fn set_cache(&mut self, cache: Arc<OpcodeCache>) {
69 self.cache = Some(cache);
70 }
71
72 pub fn scope(&self) -> &Scope {
73 &self.scope
74 }
75
76 pub fn set_local(&mut self, name: Symbol, value: Variable) {
77 self.scope.set_local(name, value);
78 }
79
80 pub fn insert_dollar(&mut self, path: &str, value: Variable) {
81 let dollar = match self.scope.local(&Variable::dollar_key()) {
82 Some(existing @ Variable::Object(_)) => existing.shallow_clone(),
83 _ => {
84 let created = Variable::empty_object();
85 self.scope
86 .set_local(Variable::dollar_key(), created.clone());
87 created
88 }
89 };
90
91 let _ = dollar.dot_insert(path, value);
92 }
93
94 pub fn set_reference(&mut self, reference: &str) -> Result<(), IsolateError> {
95 let reference_value = match self.references.get(reference) {
96 Some(value) => value.clone(),
97 None => {
98 let result = self.run_standard(reference)?;
99 self.references
100 .insert(reference.to_string(), result.clone());
101 result
102 }
103 };
104
105 self.set_reference_value(reference_value)
106 }
107
108 pub fn set_reference_value(&mut self, value: Variable) -> Result<(), IsolateError> {
109 self.scope.set_local(Variable::dollar_key(), value);
110
111 Ok(())
112 }
113
114 pub fn get_reference(&self, reference: &str) -> Option<Variable> {
115 self.references.get(reference).cloned()
116 }
117
118 fn run_internal(&mut self, source: &str, kind: ExpressionKind) -> Result<(), IsolateError> {
119 self.bump.reset();
120 let bump = &self.bump;
121
122 let tokens = self.lexer.tokenize(bump, source)?;
123
124 let base_parser = Parser::try_new(&tokens, bump)?;
125 let parser_result = match kind {
126 ExpressionKind::Unary => base_parser.unary().parse(),
127 ExpressionKind::Standard => base_parser.standard().parse(),
128 };
129
130 parser_result.error()?;
131
132 self.compiler.compile(parser_result.root)?;
133
134 Ok(())
135 }
136
137 pub fn compile_standard(&mut self, source: &str) -> Result<Expression<Standard>, IsolateError> {
138 self.run_internal(source, ExpressionKind::Standard)?;
139 let bytecode = self.compiler.get_bytecode().to_vec();
140
141 Ok(Expression::new_standard(Arc::from(bytecode)))
142 }
143
144 pub fn run_standard(&mut self, source: &str) -> Result<Variable, IsolateError> {
145 let cached = self
146 .cache
147 .as_ref()
148 .and_then(|c| c.standard.get(source).cloned());
149 if let Some(codes) = cached {
150 return self.run_compiled(codes.as_ref());
151 }
152
153 self.run_internal(source, ExpressionKind::Standard)?;
154
155 let bytecode = self.compiler.get_bytecode();
156 let result = self.vm.run(bytecode, &self.scope)?;
157
158 Ok(result)
159 }
160 pub fn run_compiled(&mut self, source: &[Opcode]) -> Result<Variable, IsolateError> {
161 let result = self.vm.run(source, &self.scope)?;
162
163 Ok(result)
164 }
165
166 pub fn compile_unary(&mut self, source: &str) -> Result<Expression<Unary>, IsolateError> {
167 self.run_internal(source, ExpressionKind::Unary)?;
168 let bytecode = self.compiler.get_bytecode().to_vec();
169
170 Ok(Expression::new_unary(Arc::from(bytecode)))
171 }
172
173 pub fn run_unary(&mut self, source: &str) -> Result<bool, IsolateError> {
174 let cached = self
175 .cache
176 .as_ref()
177 .and_then(|c| c.unary.get(source).cloned());
178 if let Some(codes) = cached {
179 return self.run_unary_compiled(codes.as_ref());
180 }
181
182 self.run_internal(source, ExpressionKind::Unary)?;
183
184 let bytecode = self.compiler.get_bytecode();
185 let result = self.vm.run(bytecode, &self.scope)?;
186
187 result.as_bool().ok_or_else(|| IsolateError::ValueCastError)
188 }
189
190 pub fn run_unary_compiled(&mut self, code: &[Opcode]) -> Result<bool, IsolateError> {
191 let result = self.vm.run(code, &self.scope)?;
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}