Skip to content

Commit

Permalink
Merge pull request #645 from HigherOrderCO/464-improve-error-message-…
Browse files Browse the repository at this point in the history
…when-program-is-missing-arm-of-branching-statement

#464 Improve error message when program is missing arm of branching statement
  • Loading branch information
imaqtkatt authored Jul 25, 2024
2 parents 2232a70 + 477f143 commit 67640d5
Show file tree
Hide file tree
Showing 13 changed files with 84 additions and 8 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ and this project does not currently adhere to a particular versioning scheme.
### Changed

- Change tuple syntax to not require parentheses in some cases. ([#554][gh-554])
- Improve error messages in branching statements. ([#464][gh-464])

## [0.2.36] - 2024-07-04

Expand Down Expand Up @@ -369,6 +370,7 @@ and this project does not currently adhere to a particular versioning scheme.
[gh-444]: https://github.com/HigherOrderCO/Bend/issues/444
[gh-451]: https://github.com/HigherOrderCO/Bend/issues/451
[gh-463]: https://github.com/HigherOrderCO/Bend/issues/463
[gh-464]: https://github.com/HigherOrderCO/Bend/issues/464
[gh-465]: https://github.com/HigherOrderCO/Bend/issues/465
[gh-466]: https://github.com/HigherOrderCO/Bend/issues/466
[gh-467]: https://github.com/HigherOrderCO/Bend/issues/467
Expand Down
1 change: 1 addition & 0 deletions src/fun/transform/float_combinators.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ impl Term {
/// - An application or numeric operation where all arguments are safe.
/// - A safe Lambda, e.g. a nullary constructor or a lambda with safe body.
/// - A Reference with a safe body.
///
/// A reference to a recursive definition (or mutually recursive) is not safe.
fn is_safe(&self, ctx: &mut FloatCombinatorsCtx) -> bool {
maybe_grow(|| match self {
Expand Down
22 changes: 15 additions & 7 deletions src/imp/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,9 @@ impl<'a> PyParser<'a> {
indent.exit_level();

if nxt_indent != *indent {
return self.expected_indent(*indent, nxt_indent);
return self
.expected_indent(*indent, nxt_indent)
.or(self.expected_spanned("'else' or 'elif'", self.index..self.index + 1));
}
let mut elifs = Vec::new();
while self.try_parse_keyword("elif") {
Expand All @@ -588,7 +590,9 @@ impl<'a> PyParser<'a> {
indent.exit_level();

if nxt_indent != *indent {
return self.expected_indent(*indent, nxt_indent);
return self
.expected_indent(*indent, nxt_indent)
.or(self.expected_spanned("'else' or 'elif'", self.index..self.index + 1));
}
elifs.push((cond, then));
}
Expand Down Expand Up @@ -630,7 +634,7 @@ impl<'a> PyParser<'a> {
self.consume_new_line()?;
indent.enter_level();

self.consume_indent_exactly(*indent)?;
self.consume_indent_exactly(*indent).or(self.expected_spanned("'case'", self.index..self.index + 1))?;
let (case, mut nxt_indent) = self.parse_match_case(indent)?;
let mut arms = vec![case];
while nxt_indent == *indent {
Expand Down Expand Up @@ -728,7 +732,9 @@ impl<'a> PyParser<'a> {
let mut expected_num = 1;
while should_continue {
if nxt_indent != *indent {
return self.expected_indent(*indent, nxt_indent);
return self
.expected_indent(*indent, nxt_indent)
.or(self.expected_spanned("'case'", self.index..self.index + 1));
}
let (case, stmt, nxt_indent_) = self.parse_switch_case(indent)?;
nxt_indent = nxt_indent_;
Expand Down Expand Up @@ -793,7 +799,7 @@ impl<'a> PyParser<'a> {
self.consume_new_line()?;
indent.enter_level();

self.consume_indent_exactly(*indent)?;
self.consume_indent_exactly(*indent).or(self.expected_spanned("'case'", self.index..self.index + 1))?;
let (case, mut nxt_indent) = self.parse_match_case(indent)?;
let mut arms = vec![case];
while nxt_indent == *indent {
Expand Down Expand Up @@ -824,7 +830,7 @@ impl<'a> PyParser<'a> {
self.consume_new_line()?;
indent.enter_level();

self.consume_indent_exactly(*indent)?;
self.consume_indent_exactly(*indent).or(self.expected_spanned("'when'", self.index..self.index + 1))?;
self.parse_keyword("when")?;
let cond = self.parse_expr(true, false)?;
self.skip_trivia_inline()?;
Expand All @@ -837,7 +843,9 @@ impl<'a> PyParser<'a> {
indent.exit_level();

if nxt_indent != *indent {
return self.expected_indent(*indent, nxt_indent);
return self
.expected_indent(*indent, nxt_indent)
.or(self.expected_spanned("'else'", self.index..self.index + 1));
}
self.parse_keyword("else")?;
self.skip_trivia_inline()?;
Expand Down
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ use diagnostics::{Diagnostics, DiagnosticsConfig, ERR_INDENT_SIZE};
use net::hvm_to_net::hvm_to_net;

pub mod diagnostics;
// `Name` triggers this warning, but it's safe because we're not using its internal mutability.
#[allow(clippy::mutable_key_type)]
pub mod fun;
pub mod hvm;
pub mod imp;
Expand Down Expand Up @@ -197,6 +199,7 @@ pub fn readback_hvm_net(
let mut diags = Diagnostics::default();
let net = hvm_to_net(net);
let mut term = net_to_term(&net, book, labels, linear, &mut diags);
#[allow(clippy::mutable_key_type)] // Safe to allow, we know how `Name` works.
let recursive_defs = book.recursive_defs();
term.expand_generated(book, &recursive_defs);
term.resugar_strings(adt_encoding);
Expand Down
15 changes: 15 additions & 0 deletions tests/golden_tests/parse_file/bend_missing_else.bend
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
def is_even(n):
if n % 2 == 0:
return 1
else:
return 0

def get_even_sum_under_if(this_number):
bend current = 0:
when current < this_number:
new_num = fork(current + is_even(current))

return new_num

def main():
return get_even_sum_under_if(1000)
3 changes: 3 additions & 0 deletions tests/golden_tests/parse_file/fold_missing_case.bend
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
def main:
fold [] with x = 1:

4 changes: 4 additions & 0 deletions tests/golden_tests/parse_file/if_missing_else.bend
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
def main:
if 1 == 1:
return "true"

3 changes: 3 additions & 0 deletions tests/golden_tests/parse_file/match_missing_case.bend
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
def main:
match []:

3 changes: 2 additions & 1 deletion tests/snapshots/compile_file__elif_no_else.bend.snap
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ input_file: tests/golden_tests/compile_file/elif_no_else.bend
---
Errors:
In tests/golden_tests/compile_file/elif_no_else.bend :
Indentation error. Expected 2 spaces, got end-of-input.
- expected: 'else' or 'elif'
- detected: end of input
 6 |  
9 changes: 9 additions & 0 deletions tests/snapshots/parse_file__bend_missing_else.bend.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
source: tests/golden_tests.rs
input_file: tests/golden_tests/parse_file/bend_missing_else.bend
---
Errors:
In tests/golden_tests/parse_file/bend_missing_else.bend :
- expected: 'else'
- detected:
 14 | def main():
9 changes: 9 additions & 0 deletions tests/snapshots/parse_file__fold_missing_case.bend.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
source: tests/golden_tests.rs
input_file: tests/golden_tests/parse_file/fold_missing_case.bend
---
Errors:
In tests/golden_tests/parse_file/fold_missing_case.bend :
- expected: 'case'
- detected: end of input
 4 |  
9 changes: 9 additions & 0 deletions tests/snapshots/parse_file__if_missing_else.bend.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
source: tests/golden_tests.rs
input_file: tests/golden_tests/parse_file/if_missing_else.bend
---
Errors:
In tests/golden_tests/parse_file/if_missing_else.bend :
- expected: 'else' or 'elif'
- detected: end of input
 5 |  
9 changes: 9 additions & 0 deletions tests/snapshots/parse_file__match_missing_case.bend.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
source: tests/golden_tests.rs
input_file: tests/golden_tests/parse_file/match_missing_case.bend
---
Errors:
In tests/golden_tests/parse_file/match_missing_case.bend :
- expected: 'case'
- detected: end of input
 4 |  

0 comments on commit 67640d5

Please sign in to comment.