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