zen_expression/
expression.rs1use crate::compiler::Opcode;
2use crate::vm::VM;
3use crate::{IsolateError, Variable};
4use std::marker::PhantomData;
5use std::sync::Arc;
6
7#[derive(Debug, Clone)]
8pub struct Standard;
9
10#[derive(Debug, Clone)]
11pub struct Unary;
12
13#[derive(Debug, Clone)]
14pub enum ExpressionKind {
15 Standard,
16 Unary,
17}
18
19#[derive(Debug, Clone)]
21pub struct Expression<Kind> {
22 bytecode: Arc<Vec<Opcode>>,
23 _marker: PhantomData<Kind>,
24}
25
26impl<Kind> Expression<Kind> {
27 pub fn bytecode(&self) -> &Arc<Vec<Opcode>> {
28 &self.bytecode
29 }
30}
31
32impl Expression<Standard> {
33 pub fn new_standard(bytecode: Arc<Vec<Opcode>>) -> Self {
34 Expression {
35 bytecode,
36 _marker: PhantomData,
37 }
38 }
39
40 pub fn kind(&self) -> ExpressionKind {
41 ExpressionKind::Standard
42 }
43
44 pub fn evaluate(&self, context: Variable) -> Result<Variable, IsolateError> {
45 let mut vm = VM::new();
46 self.evaluate_with(context, &mut vm)
47 }
48
49 pub fn evaluate_with(&self, context: Variable, vm: &mut VM) -> Result<Variable, IsolateError> {
50 let output = vm.run(self.bytecode.as_slice(), context)?;
51 Ok(output)
52 }
53}
54
55impl Expression<Unary> {
56 pub fn new_unary(bytecode: Arc<Vec<Opcode>>) -> Self {
57 Expression {
58 bytecode,
59 _marker: PhantomData,
60 }
61 }
62
63 pub fn kind(&self) -> ExpressionKind {
64 ExpressionKind::Unary
65 }
66
67 pub fn evaluate(&self, context: Variable) -> Result<bool, IsolateError> {
68 let mut vm = VM::new();
69 self.evaluate_with(context, &mut vm)
70 }
71
72 pub fn evaluate_with(&self, context: Variable, vm: &mut VM) -> Result<bool, IsolateError> {
73 let Some(context_object_ref) = context.as_object() else {
74 return Err(IsolateError::MissingContextReference);
75 };
76
77 let context_object = context_object_ref.borrow();
78 if !context_object.contains_key("$") {
79 return Err(IsolateError::MissingContextReference);
80 }
81
82 let output = vm
83 .run(self.bytecode.as_slice(), context)?
84 .as_bool()
85 .ok_or_else(|| IsolateError::ValueCastError)?;
86 Ok(output)
87 }
88}