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