1use alloc::{boxed::Box, string::String, vec::Vec};
4
5use crate::Span;
6use super::common::{Identifier, Block, Parameter, TypeAnnotation};
7use super::expr::Expr;
8use crate::ast::VariableName;
9
10#[derive(Debug, Clone, PartialEq)]
15pub struct Stmt {
16 pub kind: StmtKind,
18 pub span: Span,
20}
21
22impl Stmt {
23 pub fn new(kind: StmtKind, span: Span) -> Self {
24 Self { kind, span }
25 }
26
27 pub fn synthetic(kind: StmtKind) -> Self {
28 Self { kind, span: 0..0 }
29 }
30}
31
32#[derive(Debug, Clone, PartialEq)]
34pub enum StmtKind {
35 LocalDeclaration(LocalDeclaration),
37 FunctionDeclaration(FunctionDeclaration),
39 LocalFunctionDeclaration(LocalFunctionDeclaration),
41
42 Assignment(Assignment),
44 CompoundAssignment(CompoundAssignment),
46
47 IfStatement(IfStatement),
49 WhileLoop(WhileLoop),
51 RepeatLoop(RepeatLoop),
53 NumericForLoop(NumericForLoop),
55 GenericForLoop(GenericForLoop),
57 DoBlock(Block),
59
60 ReturnStatement(ReturnStatement),
62 BreakStatement,
64 ContinueStatement,
66
67 CallStatement(Expr),
69
70 TypeDeclaration(TypeDeclaration),
72 ExportStatement(Box<Stmt>),
74
75 GotoStatement(GotoStatement),
77 LabelStatement(LabelStatement),
79}
80
81#[derive(Debug, Clone, PartialEq)]
85pub struct LocalDeclaration {
86 pub names: Vec<VariableName>,
88 pub values: Option<Vec<Expr>>,
90 pub is_const: bool,
92 pub span: Span,
94}
95
96impl LocalDeclaration {
97 pub fn new(names: Vec<VariableName>, values: Option<Vec<Expr>>, span: Span) -> Self {
98 Self { names, values, is_const: false, span }
99 }
100
101 pub fn new_const(names: Vec<VariableName>, values: Vec<Expr>, span: Span) -> Self {
102 Self { names, values: Some(values), is_const: true, span }
103 }
104}
105
106#[derive(Debug, Clone, PartialEq)]
111pub struct FunctionDeclaration {
112 pub attributes: Vec<Attribute>,
114 pub name: FunctionName,
116 pub parameters: Vec<Parameter>,
118 pub return_type: Option<TypeAnnotation>,
120 pub body: Block,
122 pub span: Span,
124}
125
126impl FunctionDeclaration {
127 pub fn new(
128 attributes: Vec<Attribute>,
129 name: FunctionName,
130 parameters: Vec<Parameter>,
131 return_type: Option<TypeAnnotation>,
132 body: Block,
133 span: Span,
134 ) -> Self {
135 Self {
136 attributes,
137 name,
138 parameters,
139 return_type,
140 body,
141 span,
142 }
143 }
144}
145
146#[derive(Debug, Clone, PartialEq)]
148pub struct LocalFunctionDeclaration {
149 pub attributes: Vec<Attribute>,
151 pub name: Identifier,
153 pub parameters: Vec<Parameter>,
155 pub return_type: Option<TypeAnnotation>,
157 pub body: Block,
159 pub span: Span,
161}
162
163impl LocalFunctionDeclaration {
164 pub fn new(
165 attributes: Vec<Attribute>,
166 name: Identifier,
167 parameters: Vec<Parameter>,
168 return_type: Option<TypeAnnotation>,
169 body: Block,
170 span: Span,
171 ) -> Self {
172 Self {
173 attributes,
174 name,
175 parameters,
176 return_type,
177 body,
178 span,
179 }
180 }
181}
182
183#[derive(Debug, Clone, PartialEq)]
187pub struct FunctionName {
188 pub segments: Vec<Identifier>,
190 pub method: Option<Identifier>,
192}
193
194impl FunctionName {
195 pub fn new(segments: Vec<Identifier>, method: Option<Identifier>) -> Self {
196 Self { segments, method }
197 }
198
199 pub fn simple(name: Identifier) -> Self {
200 Self {
201 segments: vec![name],
202 method: None,
203 }
204 }
205}
206
207#[derive(Debug, Clone, PartialEq)]
209pub struct Assignment {
210 pub targets: Vec<AssignmentTarget>,
212 pub values: Vec<Expr>,
214 pub span: Span,
216}
217
218impl Assignment {
219 pub fn new(targets: Vec<AssignmentTarget>, values: Vec<Expr>, span: Span) -> Self {
220 Self {
221 targets,
222 values,
223 span,
224 }
225 }
226}
227
228#[derive(Debug, Clone, PartialEq)]
230pub struct CompoundAssignment {
231 pub target: AssignmentTarget,
233 pub operator: CompoundOperator,
235 pub value: Expr,
237 pub span: Span,
239}
240
241impl CompoundAssignment {
242 pub fn new(
243 target: AssignmentTarget,
244 operator: CompoundOperator,
245 value: Expr,
246 span: Span,
247 ) -> Self {
248 Self {
249 target,
250 operator,
251 value,
252 span,
253 }
254 }
255}
256
257#[derive(Debug, Clone, PartialEq)]
259pub enum AssignmentTarget {
260 Identifier(Identifier),
262 FieldAccess {
264 base: Box<Expr>,
265 field: Identifier,
266 span: Span,
267 },
268 IndexAccess {
270 base: Box<Expr>,
271 index: Box<Expr>,
272 span: Span,
273 },
274}
275
276impl AssignmentTarget {
277 pub fn span(&self) -> &Span {
278 match self {
279 AssignmentTarget::Identifier(id) => &id.span,
280 AssignmentTarget::FieldAccess { span, .. } => span,
281 AssignmentTarget::IndexAccess { span, .. } => span,
282 }
283 }
284}
285
286#[derive(Debug, Clone, Copy, PartialEq, Eq)]
288pub enum CompoundOperator {
289 Add,
291 Subtract,
293 Multiply,
295 Divide,
297 FloorDiv,
299 Modulo,
301 Power,
303 Concat,
305}
306
307#[derive(Debug, Clone, PartialEq)]
309pub struct IfStatement {
310 pub condition: Expr,
312 pub then_block: Block,
314 pub elseif_branches: Vec<ElseIfBranch>,
316 pub else_block: Option<Block>,
318 pub span: Span,
320}
321
322impl IfStatement {
323 pub fn new(
324 condition: Expr,
325 then_block: Block,
326 elseif_branches: Vec<ElseIfBranch>,
327 else_block: Option<Block>,
328 span: Span,
329 ) -> Self {
330 Self {
331 condition,
332 then_block,
333 elseif_branches,
334 else_block,
335 span,
336 }
337 }
338}
339
340#[derive(Debug, Clone, PartialEq)]
342pub struct ElseIfBranch {
343 pub condition: Expr,
345 pub then_block: Block,
347}
348
349impl ElseIfBranch {
350 pub fn new(condition: Expr, then_block: Block) -> Self {
351 Self {
352 condition,
353 then_block,
354 }
355 }
356}
357
358#[derive(Debug, Clone, PartialEq)]
360pub struct WhileLoop {
361 pub condition: Expr,
363 pub body: Block,
365 pub span: Span,
367}
368
369impl WhileLoop {
370 pub fn new(condition: Expr, body: Block, span: Span) -> Self {
371 Self {
372 condition,
373 body,
374 span,
375 }
376 }
377}
378
379#[derive(Debug, Clone, PartialEq)]
381pub struct RepeatLoop {
382 pub body: Block,
384 pub condition: Expr,
386 pub span: Span,
388}
389
390impl RepeatLoop {
391 pub fn new(body: Block, condition: Expr, span: Span) -> Self {
392 Self {
393 body,
394 condition,
395 span,
396 }
397 }
398}
399
400#[derive(Debug, Clone, PartialEq)]
402pub struct NumericForLoop {
403 pub variable: Identifier,
405 pub start: Expr,
407 pub end: Expr,
409 pub step: Option<Expr>,
411 pub body: Block,
413 pub span: Span,
415}
416
417impl NumericForLoop {
418 pub fn new(
419 variable: Identifier,
420 start: Expr,
421 end: Expr,
422 step: Option<Expr>,
423 body: Block,
424 span: Span,
425 ) -> Self {
426 Self {
427 variable,
428 start,
429 end,
430 step,
431 body,
432 span,
433 }
434 }
435}
436
437#[derive(Debug, Clone, PartialEq)]
439pub struct GenericForLoop {
440 pub variables: Vec<Identifier>,
442 pub expressions: Vec<Expr>,
444 pub body: Block,
446 pub span: Span,
448}
449
450impl GenericForLoop {
451 pub fn new(
452 variables: Vec<Identifier>,
453 expressions: Vec<Expr>,
454 body: Block,
455 span: Span,
456 ) -> Self {
457 Self {
458 variables,
459 expressions,
460 body,
461 span,
462 }
463 }
464}
465
466#[derive(Debug, Clone, PartialEq)]
468pub struct ReturnStatement {
469 pub values: Vec<Expr>,
471 pub span: Span,
473}
474
475impl ReturnStatement {
476 pub fn new(values: Vec<Expr>, span: Span) -> Self {
477 Self { values, span }
478 }
479}
480
481#[derive(Debug, Clone, PartialEq)]
483pub struct Attribute {
484 pub name: Identifier,
486 pub fields: Option<Vec<AttributeField>>,
488 pub span: Span,
490}
491
492impl Attribute {
493 pub fn new(name: Identifier, fields: Option<Vec<AttributeField>>, span: Span) -> Self {
494 Self { name, fields, span }
495 }
496}
497
498#[derive(Debug, Clone, PartialEq)]
500pub struct AttributeField {
501 pub key: Option<Identifier>,
503 pub value: AttributeValue,
505}
506
507impl AttributeField {
508 pub fn new(key: Option<Identifier>, value: AttributeValue) -> Self {
509 Self { key, value }
510 }
511}
512
513#[derive(Debug, Clone, PartialEq)]
515pub enum AttributeValue {
516 String(String),
518 Number(String),
520 Boolean(bool),
522 Identifier(Identifier),
524}
525
526#[derive(Debug, Clone, PartialEq)]
531pub struct TypeDeclaration {
532 pub exported: bool,
534 pub name: Identifier,
536 pub generics_span: Option<Span>,
538 pub type_span: Span,
540 pub span: Span,
542}
543
544impl TypeDeclaration {
545 pub fn new(
546 exported: bool,
547 name: Identifier,
548 generics_span: Option<Span>,
549 type_span: Span,
550 span: Span,
551 ) -> Self {
552 Self {
553 exported,
554 name,
555 generics_span,
556 type_span,
557 span,
558 }
559 }
560}
561
562#[derive(Debug, Clone, PartialEq)]
564pub struct GotoStatement {
565 pub label: Identifier,
567 pub span: Span,
569}
570
571impl GotoStatement {
572 pub fn new(label: Identifier, span: Span) -> Self {
573 Self { label, span }
574 }
575}
576
577#[derive(Debug, Clone, PartialEq)]
579pub struct LabelStatement {
580 pub name: Identifier,
582 pub span: Span,
584}
585
586impl LabelStatement {
587 pub fn new(name: Identifier, span: Span) -> Self {
588 Self { name, span }
589 }
590}