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