normalize_surface_syntax/ir/
stmt.rs1use crate::Expr;
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
8pub enum Stmt {
9 Expr(Expr),
11
12 Let {
14 name: String,
15 init: Option<Expr>,
16 mutable: bool,
17 },
18
19 Block(Vec<Stmt>),
21
22 If {
24 test: Expr,
25 consequent: Box<Stmt>,
26 alternate: Option<Box<Stmt>>,
27 },
28
29 While { test: Expr, body: Box<Stmt> },
31
32 For {
34 init: Option<Box<Stmt>>,
35 test: Option<Expr>,
36 update: Option<Expr>,
37 body: Box<Stmt>,
38 },
39
40 ForIn {
42 variable: String,
43 iterable: Expr,
44 body: Box<Stmt>,
45 },
46
47 Return(Option<Expr>),
49
50 Break,
52
53 Continue,
55
56 TryCatch {
58 body: Box<Stmt>,
59 catch_param: Option<String>,
60 catch_body: Option<Box<Stmt>>,
61 finally_body: Option<Box<Stmt>>,
62 },
63
64 Function(crate::Function),
66}
67
68impl Stmt {
70 pub fn expr(e: Expr) -> Self {
71 Stmt::Expr(e)
72 }
73
74 pub fn let_decl(name: impl Into<String>, init: Option<Expr>) -> Self {
75 Stmt::Let {
76 name: name.into(),
77 init,
78 mutable: true,
79 }
80 }
81
82 pub fn const_decl(name: impl Into<String>, init: Expr) -> Self {
83 Stmt::Let {
84 name: name.into(),
85 init: Some(init),
86 mutable: false,
87 }
88 }
89
90 pub fn block(stmts: Vec<Stmt>) -> Self {
91 Stmt::Block(stmts)
92 }
93
94 pub fn if_stmt(test: Expr, consequent: Stmt, alternate: Option<Stmt>) -> Self {
95 Stmt::If {
96 test,
97 consequent: Box::new(consequent),
98 alternate: alternate.map(Box::new),
99 }
100 }
101
102 pub fn while_loop(test: Expr, body: Stmt) -> Self {
103 Stmt::While {
104 test,
105 body: Box::new(body),
106 }
107 }
108
109 pub fn for_loop(
110 init: Option<Stmt>,
111 test: Option<Expr>,
112 update: Option<Expr>,
113 body: Stmt,
114 ) -> Self {
115 Stmt::For {
116 init: init.map(Box::new),
117 test,
118 update,
119 body: Box::new(body),
120 }
121 }
122
123 pub fn for_in(variable: impl Into<String>, iterable: Expr, body: Stmt) -> Self {
124 Stmt::ForIn {
125 variable: variable.into(),
126 iterable,
127 body: Box::new(body),
128 }
129 }
130
131 pub fn return_stmt(expr: Option<Expr>) -> Self {
132 Stmt::Return(expr)
133 }
134
135 pub fn break_stmt() -> Self {
136 Stmt::Break
137 }
138
139 pub fn continue_stmt() -> Self {
140 Stmt::Continue
141 }
142
143 pub fn try_catch(
144 body: Stmt,
145 catch_param: Option<String>,
146 catch_body: Option<Stmt>,
147 finally_body: Option<Stmt>,
148 ) -> Self {
149 Stmt::TryCatch {
150 body: Box::new(body),
151 catch_param,
152 catch_body: catch_body.map(Box::new),
153 finally_body: finally_body.map(Box::new),
154 }
155 }
156
157 pub fn function(f: crate::Function) -> Self {
158 Stmt::Function(f)
159 }
160}