1use crate::language::InternSymbol;
2use crate::debug::DebugSymbol;
3use crate::parser::expr::Expr;
4use crate::parser::lvalue::LValue;
5
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8pub struct Label(InternSymbol);
9
10impl Label {
11 pub fn new(name: InternSymbol) -> Self { Label(name) }
12 pub fn name(&self) -> &InternSymbol { &self.0 }
13}
14
15#[derive(Debug, Clone)]
16pub enum Stmt {
17
18 Expression(Expr),
19
20 Loop {
21 label: Option<Label>,
22 body: StmtList,
23 },
24
25 WhileLoop {
26 label: Option<Label>,
27 condition: Expr,
28 body: StmtList,
29 },
30
31 ForLoop {
32 label: Option<Label>,
33 lvalue: LValue,
34 iter: Expr,
35 body: StmtList,
36 },
37
38 Assert(Expr),
39}
40
41
42#[derive(Debug, Clone)]
45pub struct StmtList {
46 suite: Box<[StmtMeta]>,
47 control: Option<ControlFlow>,
48}
49
50#[derive(Debug, Clone)]
51pub enum ControlFlow {
52 Continue {
53 symbol: Option<DebugSymbol>,
54 label: Option<Label>,
55 },
56
57 Break {
58 symbol: Option<DebugSymbol>,
59 label: Option<Label>,
60 expr: Option<Box<Expr>>,
61 },
62
63 Return {
64 symbol: Option<DebugSymbol>,
65 expr: Option<Box<Expr>>,
66 },
67}
68
69impl ControlFlow {
70 pub fn debug_symbol(&self) -> Option<&DebugSymbol> {
71 match self {
72 Self::Continue { symbol, .. } => symbol.as_ref(),
73 Self::Break { symbol, .. } => symbol.as_ref(),
74 Self::Return { symbol, .. } => symbol.as_ref(),
75 }
76 }
77}
78
79
80impl StmtList {
81 pub fn new(suite: Vec<StmtMeta>, control: Option<ControlFlow>) -> Self {
82 Self {
83 suite: suite.into_boxed_slice(),
84 control,
85 }
86 }
87
88 pub fn iter(&self) -> impl Iterator<Item=&StmtMeta> {
89 self.suite.iter()
90 }
91
92 pub fn end_control(&self) -> Option<&ControlFlow> { self.control.as_ref() }
93
94 pub fn take(self) -> (Vec<StmtMeta>, Option<ControlFlow>) {
95 (self.suite.into_vec(), self.control)
96 }
97}
98
99
100#[derive(Debug, Clone)]
102pub struct StmtMeta {
103 variant: Stmt,
104 symbol: DebugSymbol,
105}
106
107impl StmtMeta {
108 pub fn new(variant: Stmt, symbol: DebugSymbol) -> Self {
109 StmtMeta { variant, symbol }
110 }
111
112 pub fn variant(&self) -> &Stmt { &self.variant }
113 pub fn take_variant(self) -> Stmt { self.variant }
114
115 pub fn debug_symbol(&self) -> &DebugSymbol { &self.symbol }
116 pub fn take_symbol(self) -> DebugSymbol { self.symbol }
117
118 pub fn take(self) -> (Stmt, DebugSymbol) { (self.variant, self.symbol) }
119}