sphinx/parser/
stmt.rs

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// Statement blocks 
43// (called "statement lists" in Sphinx so as not to be confused with "block expressions")
44#[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// Stmt + DebugSymbol
101#[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}