From 09c0f9e605a89063de2de1574edd786abd06160e Mon Sep 17 00:00:00 2001 From: Nicolas Abril Date: Sat, 22 Feb 2025 16:02:38 +0100 Subject: [PATCH 1/3] #748 Fix signed numbers not parsing correctly after parens --- src/fun/parser.rs | 45 ++++++++++++++++--- .../parse_file/tup_with_signed.bend | 9 ++++ .../parse_file__tup_with_signed.bend.snap | 6 +++ 3 files changed, 55 insertions(+), 5 deletions(-) create mode 100644 tests/golden_tests/parse_file/tup_with_signed.bend create mode 100644 tests/snapshots/parse_file__tup_with_signed.bend.snap diff --git a/src/fun/parser.rs b/src/fun/parser.rs index 928910b6..38ef9ef0 100644 --- a/src/fun/parser.rs +++ b/src/fun/parser.rs @@ -590,21 +590,56 @@ impl<'a> FunParser<'a> { // App, Tup, Num Op if self.starts_with("(") { self.advance_one(); - - // Opr but maybe a tup self.skip_trivia(); + + // Opr but maybe something else + // ( +/-n , -> Tup with Int/Float + // ( +/-n ) -> Int/Float + // ( +/-n term -> App with Int/Float + // ( * , -> Tup with Era + // ( * ) -> Era + // ( opr -> Num Op if let Some(opr) = self.try_parse_oper() { + if (opr == Op::ADD || opr == Op::SUB) && self.peek_one().map_or(false, |c| "0123456789".contains(c)) + { + unexpected_tag(self)?; + *self.index() -= 1; + let num = self.parse_number()?; + let head = Term::Num { val: num }; + self.skip_trivia(); + + if self.starts_with(",") { + self.consume_exactly(",")?; + let tail = self.list_like(|p| p.parse_term(), "", ")", ",", true, 1)?; + let els = [head].into_iter().chain(tail).collect(); + return Ok(Term::Fan { fan: FanKind::Tup, tag: tag.unwrap_or(Tag::Static), els }); + } + + if self.starts_with(")") { + self.consume_exactly(")")?; + return Ok(head); + } + + let els = self.list_like(|p| p.parse_term(), "", ")", "", false, 0)?; + let term = els.into_iter().fold(head, |fun, arg| Term::App { + tag: tag.clone().unwrap_or(Tag::Static), + fun: Box::new(fun), + arg: Box::new(arg), + }); + return Ok(term); + } + self.skip_trivia(); - // jk, actually a tuple - if self.starts_with(",") && opr == Op::MUL { + if opr == Op::MUL && self.starts_with(",") { self.consume_exactly(",")?; let tail = self.list_like(|p| p.parse_term(), "", ")", ",", true, 1)?; let els = [Term::Era].into_iter().chain(tail).collect(); return Ok(Term::Fan { fan: FanKind::Tup, tag: tag.unwrap_or(Tag::Static), els }); } - if opr == Op::MUL && self.try_consume(")") { + if opr == Op::MUL && self.starts_with(")") { + self.consume_exactly(")")?; return Ok(Term::Era); } diff --git a/tests/golden_tests/parse_file/tup_with_signed.bend b/tests/golden_tests/parse_file/tup_with_signed.bend new file mode 100644 index 00000000..2de0ccd3 --- /dev/null +++ b/tests/golden_tests/parse_file/tup_with_signed.bend @@ -0,0 +1,9 @@ +# Test that we can parse tuples and apps beginning with signed numbers +main = + let a = (+1, +1) + let b = (+1.1324) + let c = (-6.234, -1) + let d = (-1) + let e = (+6 * λx x) + let f = ((*) λx x) + (+ a (+ b (+ c (+ d (- e f))))) diff --git a/tests/snapshots/parse_file__tup_with_signed.bend.snap b/tests/snapshots/parse_file__tup_with_signed.bend.snap new file mode 100644 index 00000000..f48b4efc --- /dev/null +++ b/tests/snapshots/parse_file__tup_with_signed.bend.snap @@ -0,0 +1,6 @@ +--- +source: tests/golden_tests.rs +input_file: tests/golden_tests/parse_file/tup_with_signed.bend +--- +unchecked main: Any +(main) = let a = (+1, +1); let b = 1.132; let c = (-6.234, -1); let d = -1; let e = (+6 * λx x); let f = (* λx x); (+ a (+ b (+ c (+ d (- e f))))) From 4c865bc413f398b5b938afbd0727ebd9b2c775c4 Mon Sep 17 00:00:00 2001 From: Nicolas Abril Date: Sat, 22 Feb 2025 16:32:20 +0100 Subject: [PATCH 2/3] update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 771cd93f..35f6cecf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ and this project does not currently adhere to a particular versioning scheme. ### Fixed - Fix type checker not properly unifying all the arms of a match expression. ([#734][gh-734]) +- Fix signed numbers (i24 and f24) not being parsed after parenthesis `(`. ([#748][gh-748]) ## [0.2.37] - 2024-10-18 @@ -443,3 +444,4 @@ and this project does not currently adhere to a particular versioning scheme. [gh-706]: https://github.com/HigherOrderCO/Bend/issues/706 [gh-734]: https://github.com/HigherOrderCO/Bend/issues/734 [gh-736]: https://github.com/HigherOrderCO/Bend/issues/736 +[gh-748]: https://github.com/HigherOrderCO/Bend/issues/748 From 7fd742b0d626aecefaa62773230be1e936b51518 Mon Sep 17 00:00:00 2001 From: Nicolas Abril Date: Sat, 22 Feb 2025 16:39:05 +0100 Subject: [PATCH 3/3] update for new clippy --- src/fun/parser.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/fun/parser.rs b/src/fun/parser.rs index 38ef9ef0..10532719 100644 --- a/src/fun/parser.rs +++ b/src/fun/parser.rs @@ -600,8 +600,7 @@ impl<'a> FunParser<'a> { // ( * ) -> Era // ( opr -> Num Op if let Some(opr) = self.try_parse_oper() { - if (opr == Op::ADD || opr == Op::SUB) && self.peek_one().map_or(false, |c| "0123456789".contains(c)) - { + if (opr == Op::ADD || opr == Op::SUB) && self.peek_one().is_some_and(|c| "0123456789".contains(c)) { unexpected_tag(self)?; *self.index() -= 1; let num = self.parse_number()?;