Skip to content

Commit d4d0f53

Browse files
committed
refactor: Improve encapsulation of CaseBlock struct
1 parent 17f5856 commit d4d0f53

7 files changed

Lines changed: 57 additions & 46 deletions

File tree

rusty_basic/src/instruction_generator/select_case.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,12 @@ impl InstructionGenerator {
3232
// where to jump out from here if the case block isn't matching
3333
let next_case_label =
3434
labels::next_case_label(case_blocks_len, has_else, case_block_index);
35-
let is_multi_expr = case_block.expression_list.len() > 1;
35+
36+
let (expression_list, statements) = case_block.into();
37+
38+
let is_multi_expr = expression_list.len() > 1;
3639
self.generate_case_expressions(
37-
case_block.expression_list,
40+
expression_list,
3841
next_case_label.as_str(),
3942
pos,
4043
case_block_index,
@@ -45,7 +48,7 @@ impl InstructionGenerator {
4548
self.label(&labels::case_statements(case_block_index), pos);
4649
}
4750
// run matched CASE block statements
48-
self.visit(case_block.statements);
51+
self.visit(statements);
4952
// jump out of SELECT
5053
self.jump(labels::end_select(), pos);
5154
}

rusty_linter/src/converter/statement/select_case.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,10 @@ impl Convertible for SelectCase {
2121

2222
impl Convertible for CaseBlock {
2323
fn convert(self, ctx: &mut Context) -> Result<Self, LintErrorPos> {
24-
let expression_list = self.expression_list.convert(ctx)?;
25-
let statements = self.statements.convert(ctx)?;
26-
Ok(Self {
27-
expression_list,
28-
statements,
29-
})
24+
let (expression_list, statements) = self.into();
25+
let expression_list = expression_list.convert(ctx)?;
26+
let statements = statements.convert(ctx)?;
27+
Ok(Self::new(expression_list, statements))
3028
}
3129
}
3230

rusty_linter/src/core/visitor.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,8 @@ where
186186
P: Visitor<Statement> + SetPosition,
187187
{
188188
fn visit(&mut self, element: &CaseBlock) -> VisitResult {
189-
self.visit(&element.statements)
189+
let (_, statements) = element.into();
190+
self.visit(statements)
190191
}
191192
}
192193

rusty_linter/src/post_linter/expression_reducer.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -203,18 +203,15 @@ pub trait ExpressionReducer {
203203
}
204204

205205
fn visit_case_block(&mut self, s: CaseBlock) -> Result<CaseBlock, LintErrorPos> {
206-
let CaseBlock {
207-
expression_list,
208-
statements,
209-
} = s;
206+
let (expression_list, statements) = s.into();
210207
let expression_list: Vec<CaseExpression> = expression_list
211208
.into_iter()
212209
.map(|case_expr| self.visit_case_expression(case_expr))
213210
.collect::<Result<Vec<CaseExpression>, LintErrorPos>>()?;
214-
Ok(CaseBlock {
211+
Ok(CaseBlock::new(
215212
expression_list,
216-
statements: self.visit_statements(statements)?,
217-
})
213+
self.visit_statements(statements)?,
214+
))
218215
}
219216

220217
fn visit_case_expression(&mut self, s: CaseExpression) -> Result<CaseExpression, LintErrorPos> {

rusty_linter/src/post_linter/post_conversion_linter.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,10 +197,11 @@ pub trait PostConversionLinter {
197197
case_block: &CaseBlock,
198198
select_expr: &ExpressionPos,
199199
) -> Result<(), LintErrorPos> {
200-
for case_expr in &case_block.expression_list {
200+
let (expression_list, statements) = case_block.into();
201+
for case_expr in expression_list {
201202
self.visit_case_expression(case_expr, select_expr)?;
202203
}
203-
self.visit_statements(&case_block.statements)
204+
self.visit_statements(statements)
204205
}
205206

206207
fn visit_case_expression(

rusty_parser/src/specific/core/select_case.rs

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,15 @@ pub fn select_case_p() -> impl Parser<RcStringView, Output = Statement> {
2929
let case_blocks = all_case_blocks
3030
.clone()
3131
.into_iter()
32-
.filter(|x| !x.expression_list.is_empty())
32+
.filter(|x| x.has_conditions())
3333
.collect();
3434
let else_block = all_case_blocks
3535
.into_iter()
36-
.find(|x| x.expression_list.is_empty())
37-
.map(|x| x.statements);
36+
.find(|x| !x.has_conditions())
37+
.map(|x| {
38+
let (_, right) = x.into();
39+
right
40+
});
3841
Statement::SelectCase(SelectCase {
3942
expr,
4043
case_blocks,
@@ -91,10 +94,7 @@ fn continue_after_case() -> impl Parser<RcStringView, Output = CaseBlock> {
9194
Box::new(case_expression_list()),
9295
]),
9396
ZeroOrMoreStatements::new_multi(vec![Keyword::Case, Keyword::End]),
94-
|expression_list, statements| CaseBlock {
95-
expression_list,
96-
statements,
97-
},
97+
CaseBlock::new,
9898
),
9999
)
100100
}
@@ -175,15 +175,15 @@ mod tests {
175175
GlobalStatement::Statement(Statement::SelectCase(SelectCase {
176176
expr: "X".as_var_expr(2, 21),
177177
inline_comments: vec![" testing for x".to_string().at_rc(2, 23)],
178-
case_blocks: vec![CaseBlock {
179-
expression_list: vec![CaseExpression::Simple(1.as_lit_expr(3, 14))],
180-
statements: vec![
178+
case_blocks: vec![CaseBlock::new(
179+
vec![CaseExpression::Simple(1.as_lit_expr(3, 14))],
180+
vec![
181181
Statement::Comment(" is it one?".to_string()).at_rc(3, 23),
182182
Statement::sub_call("Flint".into(), vec!["One".as_lit_expr(4, 15)])
183183
.at_rc(4, 9),
184184
Statement::Comment(" print it".to_string()).at_rc(4, 23),
185185
]
186-
}],
186+
)],
187187
else_block: Some(vec![
188188
Statement::Comment(" something else?".to_string()).at_rc(5, 23),
189189
Statement::sub_call("Flint".into(), vec!["Nope".as_lit_expr(6, 15)])
@@ -238,15 +238,15 @@ mod tests {
238238
" testing for x".to_string().at_rc(2, 23),
239239
" first case".to_string().at_rc(3, 9)
240240
],
241-
case_blocks: vec![CaseBlock {
242-
expression_list: vec![CaseExpression::Simple(1.as_lit_expr(4, 14))],
243-
statements: vec![
241+
case_blocks: vec![CaseBlock::new(
242+
vec![CaseExpression::Simple(1.as_lit_expr(4, 14))],
243+
vec![
244244
Statement::Comment(" is it one?".to_string()).at_rc(4, 23),
245245
Statement::sub_call("Flint".into(), vec!["One".as_lit_expr(5, 15)])
246246
.at_rc(5, 9),
247247
Statement::Comment(" print it".to_string()).at_rc(5, 23),
248248
]
249-
}],
249+
)],
250250
else_block: None
251251
}))
252252
.at_rc(2, 9)
@@ -271,31 +271,31 @@ mod tests {
271271
expr: paren_exp!( bin_exp!( int_lit!(5 at 2:21) ; plus int_lit!(2 at 2:23) ; at 2:22 ) ; at 2:20 ),
272272
inline_comments: vec![],
273273
case_blocks: vec![
274-
CaseBlock {
275-
expression_list: vec![CaseExpression::Simple(
274+
CaseBlock::new(
275+
vec![CaseExpression::Simple(
276276
paren_exp!( bin_exp!( int_lit!(6 at 3:14) ; plus int_lit!(5 at 3:16) ; at 3:15 ) ; at 3:13 )
277277
)],
278-
statements: vec![Statement::Print(Print {
278+
vec![Statement::Print(Print {
279279
file_number: None,
280280
lpt1: false,
281281
format_string: None,
282282
args: vec![PrintArg::Expression(11.as_lit_expr(4, 19))]
283283
})
284284
.at_rc(4, 13)]
285-
},
286-
CaseBlock {
287-
expression_list: vec![CaseExpression::Range(
285+
),
286+
CaseBlock::new(
287+
vec![CaseExpression::Range(
288288
Expression::Parenthesis(Box::new(2.as_lit_expr(5, 14))).at_rc(5, 13),
289289
Expression::Parenthesis(Box::new(5.as_lit_expr(5, 19))).at_rc(5, 18)
290290
)],
291-
statements: vec![Statement::Print(Print {
291+
vec![Statement::Print(Print {
292292
file_number: None,
293293
lpt1: false,
294294
format_string: None,
295295
args: vec![PrintArg::Expression(2.as_lit_expr(6, 19))]
296296
})
297297
.at_rc(6, 13)]
298-
},
298+
),
299299
],
300300
else_block: None
301301
})

rusty_parser/src/specific/core/statement.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -265,10 +265,21 @@ pub struct SelectCase {
265265
pub inline_comments: Vec<Positioned<String>>,
266266
}
267267

268-
#[derive(Clone, Debug, PartialEq)]
269-
pub struct CaseBlock {
270-
pub expression_list: Vec<CaseExpression>,
271-
pub statements: Statements,
268+
bi_tuple!(
269+
/// A case block can have one or more condition expressions and
270+
/// the statements to execute if the condition is met.
271+
CaseBlock(Vec<CaseExpression>, Statements)
272+
);
273+
274+
impl CaseBlock {
275+
pub fn conditions(&self) -> &Vec<CaseExpression> {
276+
&self.0
277+
}
278+
279+
pub fn has_conditions(&self) -> bool {
280+
// the CASE ELSE block does not have conditions
281+
!self.conditions().is_empty()
282+
}
272283
}
273284

274285
#[derive(Clone, Debug, PartialEq)]

0 commit comments

Comments
 (0)