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};
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
139 pub fn compile_unary(&mut self, source: &'a str) -> Result<Expression<Unary>, IsolateError> {
140 self.run_internal(source, ExpressionKind::Unary)?;
141 let bytecode = self.compiler.get_bytecode().to_vec();
142
143 Ok(Expression::new_unary(Arc::new(bytecode)))
144 }
145
146 pub fn run_unary(&mut self, source: &'a str) -> Result<bool, IsolateError> {
147 self.run_internal(source, ExpressionKind::Unary)?;
148
149 let bytecode = self.compiler.get_bytecode();
150 let result = self
151 .vm
152 .run(bytecode, self.environment.clone().unwrap_or(Variable::Null))?;
153
154 result.as_bool().ok_or_else(|| IsolateError::ValueCastError)
155 }
156}
157
158#[derive(Debug, Error)]
160pub enum IsolateError {
161 #[error("Lexer error: {source}")]
162 LexerError { source: LexerError },
163
164 #[error("Parser error: {source}")]
165 ParserError { source: ParserError },
166
167 #[error("Compiler error: {source}")]
168 CompilerError { source: CompilerError },
169
170 #[error("VM error: {source}")]
171 VMError { source: VMError },
172
173 #[error("Value cast error")]
174 ValueCastError,
175
176 #[error("Failed to compute reference")]
177 ReferenceError,
178
179 #[error("Missing context reference")]
180 MissingContextReference,
181}
182
183impl Serialize for IsolateError {
184 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
185 where
186 S: Serializer,
187 {
188 let mut map = serializer.serialize_map(None)?;
189
190 match &self {
191 IsolateError::ReferenceError => {
192 map.serialize_entry("type", "referenceError")?;
193 }
194 IsolateError::MissingContextReference => {
195 map.serialize_entry("type", "missingContextReference")?;
196 }
197 IsolateError::ValueCastError => {
198 map.serialize_entry("type", "valueCastError")?;
199 }
200 IsolateError::LexerError { source } => {
201 map.serialize_entry("type", "lexerError")?;
202 map.serialize_entry("source", source.to_string().as_str())?;
203 }
204 IsolateError::ParserError { source } => {
205 map.serialize_entry("type", "parserError")?;
206 map.serialize_entry("source", source.to_string().as_str())?;
207 }
208 IsolateError::CompilerError { source } => {
209 map.serialize_entry("type", "compilerError")?;
210 map.serialize_entry("source", source.to_string().as_str())?;
211 }
212 IsolateError::VMError { source } => {
213 map.serialize_entry("type", "vmError")?;
214 map.serialize_entry("source", source.to_string().as_str())?;
215 }
216 }
217
218 map.end()
219 }
220}
221
222impl From<LexerError> for IsolateError {
223 fn from(source: LexerError) -> Self {
224 IsolateError::LexerError { source }
225 }
226}
227
228impl From<ParserError> for IsolateError {
229 fn from(source: ParserError) -> Self {
230 IsolateError::ParserError { source }
231 }
232}
233
234impl From<VMError> for IsolateError {
235 fn from(source: VMError) -> Self {
236 IsolateError::VMError { source }
237 }
238}
239
240impl From<CompilerError> for IsolateError {
241 fn from(source: CompilerError) -> Self {
242 IsolateError::CompilerError { source }
243 }
244}