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