just_engine/runner/eval/
types.rs1use crate::runner::ds::error::JErrorType;
4use crate::runner::ds::value::JsValue;
5
6#[derive(Debug, Clone, PartialEq)]
9pub enum CompletionType {
10 Normal,
12 Return,
14 Throw,
16 Break,
18 Continue,
20 Yield,
22}
23
24pub struct Completion {
27 pub completion_type: CompletionType,
29 pub value: Option<JsValue>,
31 pub target: Option<String>,
33}
34
35impl Completion {
36 pub fn normal() -> Self {
38 Completion {
39 completion_type: CompletionType::Normal,
40 value: None,
41 target: None,
42 }
43 }
44
45 pub fn normal_with_value(value: JsValue) -> Self {
47 Completion {
48 completion_type: CompletionType::Normal,
49 value: Some(value),
50 target: None,
51 }
52 }
53
54 pub fn return_value(value: JsValue) -> Self {
56 Completion {
57 completion_type: CompletionType::Return,
58 value: Some(value),
59 target: None,
60 }
61 }
62
63 pub fn return_undefined() -> Self {
65 Completion {
66 completion_type: CompletionType::Return,
67 value: Some(JsValue::Undefined),
68 target: None,
69 }
70 }
71
72 pub fn throw(error: JErrorType) -> Self {
74 Completion {
75 completion_type: CompletionType::Throw,
76 value: Some(JsValue::String(error.to_string())),
77 target: None,
78 }
79 }
80
81 pub fn break_completion(target: Option<String>) -> Self {
83 Completion {
84 completion_type: CompletionType::Break,
85 value: None,
86 target,
87 }
88 }
89
90 pub fn continue_completion(target: Option<String>) -> Self {
92 Completion {
93 completion_type: CompletionType::Continue,
94 value: None,
95 target,
96 }
97 }
98
99 pub fn yield_value(value: JsValue) -> Self {
101 Completion {
102 completion_type: CompletionType::Yield,
103 value: Some(value),
104 target: None,
105 }
106 }
107
108 pub fn is_normal(&self) -> bool {
110 matches!(self.completion_type, CompletionType::Normal)
111 }
112
113 pub fn is_abrupt(&self) -> bool {
115 !self.is_normal()
116 }
117
118 pub fn get_value(&self) -> JsValue {
120 self.value.clone().unwrap_or(JsValue::Undefined)
121 }
122
123 pub fn update_empty(self, value: JsValue) -> Self {
125 if self.is_normal() && self.value.is_none() {
126 Completion {
127 value: Some(value),
128 ..self
129 }
130 } else {
131 self
132 }
133 }
134}
135
136#[derive(Clone)]
139pub enum ReferenceBase {
140 Object(JsValue),
142 Environment(EnvironmentRef),
144 Unresolvable,
146}
147
148#[derive(Clone)]
150pub struct EnvironmentRef {
151 pub name: String,
153}
154
155#[derive(Clone)]
158pub struct Reference {
159 pub base: ReferenceBase,
161 pub referenced_name: String,
163 pub strict: bool,
165 pub this_value: Option<JsValue>,
167}
168
169impl Reference {
170 pub fn property(base: JsValue, name: impl Into<String>, strict: bool) -> Self {
172 Reference {
173 base: ReferenceBase::Object(base),
174 referenced_name: name.into(),
175 strict,
176 this_value: None,
177 }
178 }
179
180 pub fn environment(env_name: impl Into<String>, binding_name: impl Into<String>, strict: bool) -> Self {
182 Reference {
183 base: ReferenceBase::Environment(EnvironmentRef { name: env_name.into() }),
184 referenced_name: binding_name.into(),
185 strict,
186 this_value: None,
187 }
188 }
189
190 pub fn unresolvable(name: impl Into<String>, strict: bool) -> Self {
192 Reference {
193 base: ReferenceBase::Unresolvable,
194 referenced_name: name.into(),
195 strict,
196 this_value: None,
197 }
198 }
199
200 pub fn has_primitive_base(&self) -> bool {
202 match &self.base {
203 ReferenceBase::Object(v) => matches!(v, JsValue::Boolean(_) | JsValue::String(_) | JsValue::Number(_)),
204 _ => false,
205 }
206 }
207
208 pub fn is_property_reference(&self) -> bool {
210 matches!(self.base, ReferenceBase::Object(_)) || self.has_primitive_base()
211 }
212
213 pub fn is_unresolvable(&self) -> bool {
215 matches!(self.base, ReferenceBase::Unresolvable)
216 }
217
218 pub fn is_super_reference(&self) -> bool {
220 self.this_value.is_some()
221 }
222
223 pub fn get_base(&self) -> Option<&JsValue> {
225 match &self.base {
226 ReferenceBase::Object(v) => Some(v),
227 _ => None,
228 }
229 }
230
231 pub fn get_this_value(&self) -> JsValue {
233 if let Some(ref this) = self.this_value {
234 this.clone()
235 } else if let ReferenceBase::Object(ref base) = self.base {
236 base.clone()
237 } else {
238 JsValue::Undefined
239 }
240 }
241}
242
243pub type EvalResult = Result<Completion, JErrorType>;
245
246pub type ValueResult = Result<JsValue, JErrorType>;
248
249pub type ReferenceResult = Result<Reference, JErrorType>;