Skip to content

Commit 8f0b00f

Browse files
committed
Fix parsing of repeated label definitions
1 parent cf40845 commit 8f0b00f

File tree

3 files changed

+93
-4
lines changed

3 files changed

+93
-4
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2828
`pasfmt.toml` file. It is now an error to provide a path to a directory.
2929
- Detection of decoding errors when reading from stdin.
3030
- Silent ignoral of non-existent paths (were being treated as globs matching no files).
31+
- Parsing of repeated label definitions.
3132

3233
## [0.3.0] - 2024-05-29
3334

core/datatests/generators/logical_line_parser.rs

+67-2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ macro_rules! generate_test_cases {
3333
std::fs::create_dir_all(&dir)
3434
.expect(&format!("failed to create all directories: {}", &dir.display()));
3535
let file_name = dir.join(stringify!($name));
36+
if file_name.exists() {
37+
panic!("Test with name {} already exists at {}", stringify!($name), file_name.display());
38+
}
3639
std::fs::write(&file_name, $input)
3740
.expect(&format!("failed to write file `{}` for test", &file_name.display()));
3841
}
@@ -2509,8 +2512,70 @@ mod statements {
25092512
root_dir,
25102513
test_group,
25112514
goto_i = "goto Foo",
2512-
goto_n = "goto 1",
2513-
label = "Foo:"
2515+
goto_d = "goto 1",
2516+
goto_h = "goto $1",
2517+
goto_b = "goto %1",
2518+
label_i = "Foo:",
2519+
label_d = "1111:",
2520+
label_h = "$1111:",
2521+
label_b = "%1111:",
2522+
);
2523+
generate_test_cases!(
2524+
root_dir,
2525+
multi_label = "
2526+
_|begin
2527+
_| Foo:
2528+
_| 111:
2529+
_| $111:
2530+
_| %111:
2531+
_|end
2532+
",
2533+
i_label_statement = "
2534+
_|begin
2535+
_| Foo:
2536+
_| Bar();
2537+
_|end
2538+
",
2539+
d_label_statement = "
2540+
_|begin
2541+
_| 111:
2542+
_| Bar();
2543+
_|end
2544+
",
2545+
b_label_statement = "
2546+
_|begin
2547+
_| $111:
2548+
_| Bar();
2549+
_|end
2550+
",
2551+
h_label_statement = "
2552+
_|begin
2553+
_| %111:
2554+
_| Bar();
2555+
_|end
2556+
",
2557+
other_contexts = "
2558+
_|begin
2559+
_| repeat
2560+
_| 111:
2561+
_| until True;
2562+
_| try
2563+
_| 111:
2564+
_| except
2565+
_| 111:
2566+
_| end;
2567+
_|end;
2568+
_|initialization
2569+
_| Foo:
2570+
_| 111:
2571+
_| $111:
2572+
_| %111:
2573+
_|finalization
2574+
_| Foo:
2575+
_| 111:
2576+
_| $111:
2577+
_| %111:
2578+
",
25142579
);
25152580
}
25162581
}

core/src/defaults/parser.rs

+25-2
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ impl<'a, 'b> InternalDelphiLogicalLineParser<'a, 'b> {
309309
);
310310
self.finish_logical_line();
311311
}
312-
TT::Op(OK::LBrack) if self.get_current_logical_line().tokens.is_empty() => {
312+
TT::Op(OK::LBrack) if self.is_at_start_of_line() => {
313313
// If there is a `[` at the start of a line, it must be an attribute
314314
self.skip_pair();
315315
self.set_logical_line_type(LogicalLineType::Attribute);
@@ -911,6 +911,25 @@ impl<'a, 'b> InternalDelphiLogicalLineParser<'a, 'b> {
911911
self.take_until(no_more_separators());
912912
self.finish_logical_line();
913913
}
914+
TT::Identifier | TT::NumberLiteral(_) | TT::IdentifierOrKeyword(_)
915+
if self.is_at_start_of_line()
916+
&& self.get_next_token_type() == Some(TT::Op(OK::Colon))
917+
&& !matches!(
918+
self.get_last_context_type(),
919+
Some(
920+
ContextType::DeclarationBlock
921+
| ContextType::VisibilityBlock
922+
| ContextType::CaseStatement
923+
| ContextType::TypeDeclaration
924+
)
925+
) =>
926+
{
927+
// Labels can only occur at the start of a line within a compound statement
928+
self.next_token(); // Label specifier
929+
self.next_token(); // Colon
930+
self.take_until(no_more_separators());
931+
self.finish_logical_line();
932+
}
914933
_ => self.next_token(),
915934
}
916935
}
@@ -1364,8 +1383,12 @@ impl<'a, 'b> InternalDelphiLogicalLineParser<'a, 'b> {
13641383
{}
13651384
}
13661385

1386+
fn is_at_start_of_line(&self) -> bool {
1387+
self.get_current_logical_line().tokens.is_empty()
1388+
}
1389+
13671390
fn finish_logical_line(&mut self) {
1368-
if self.get_current_logical_line().tokens.is_empty() {
1391+
if self.is_at_start_of_line() {
13691392
self.get_current_logical_line_mut().line_type = LLT::Unknown;
13701393
return;
13711394
}

0 commit comments

Comments
 (0)