boa/syntax/ast/node/iteration/while_loop/
mod.rs1use crate::{
2 exec::{Executable, InterpreterState},
3 gc::{Finalize, Trace},
4 syntax::ast::node::Node,
5 Context, JsResult, JsValue,
6};
7use std::fmt;
8
9#[cfg(feature = "deser")]
10use serde::{Deserialize, Serialize};
11
12#[cfg_attr(feature = "deser", derive(Serialize, Deserialize))]
24#[derive(Clone, Debug, Trace, Finalize, PartialEq)]
25pub struct WhileLoop {
26 cond: Box<Node>,
27 body: Box<Node>,
28 label: Option<Box<str>>,
29}
30
31impl WhileLoop {
32 pub fn cond(&self) -> &Node {
33 &self.cond
34 }
35
36 pub fn body(&self) -> &Node {
37 &self.body
38 }
39
40 pub fn label(&self) -> Option<&str> {
41 self.label.as_ref().map(Box::as_ref)
42 }
43
44 pub fn set_label(&mut self, label: Box<str>) {
45 self.label = Some(label);
46 }
47
48 pub fn new<C, B>(condition: C, body: B) -> Self
50 where
51 C: Into<Node>,
52 B: Into<Node>,
53 {
54 Self {
55 cond: Box::new(condition.into()),
56 body: Box::new(body.into()),
57 label: None,
58 }
59 }
60
61 pub(in crate::syntax::ast::node) fn display(
62 &self,
63 f: &mut fmt::Formatter<'_>,
64 indentation: usize,
65 ) -> fmt::Result {
66 if let Some(ref label) = self.label {
67 write!(f, "{}: ", label)?;
68 }
69 write!(f, "while ({}) ", self.cond())?;
70 self.body().display(f, indentation)
71 }
72}
73
74impl Executable for WhileLoop {
75 fn run(&self, context: &mut Context) -> JsResult<JsValue> {
76 let mut result = JsValue::undefined();
77 while self.cond().run(context)?.to_boolean() {
78 result = self.body().run(context)?;
79 match context.executor().get_current_state() {
80 InterpreterState::Break(label) => {
81 handle_state_with_labels!(self, label, context, break);
82 break;
83 }
84 InterpreterState::Continue(label) => {
85 handle_state_with_labels!(self, label, context, continue)
86 }
87 InterpreterState::Return => {
88 return Ok(result);
89 }
90 InterpreterState::Executing => {
91 }
93 }
94 }
95 Ok(result)
96 }
97}
98
99impl fmt::Display for WhileLoop {
100 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
101 self.display(f, 0)
102 }
103}
104
105impl From<WhileLoop> for Node {
106 fn from(while_loop: WhileLoop) -> Self {
107 Self::WhileLoop(while_loop)
108 }
109}