From 24b3219016f023b849bece74725a362c9d881bf6 Mon Sep 17 00:00:00 2001 From: imaqtkatt Date: Mon, 27 May 2024 08:15:36 -0300 Subject: [PATCH 1/5] Implement elif --- src/imp/parser.rs | 22 +++++++++++++++++++ tests/golden_tests/compile_file/elif.bend | 16 ++++++++++++++ .../compile_file/elif_no_else.bend | 5 +++++ tests/snapshots/compile_file__elif.bend.snap | 18 +++++++++++++++ .../compile_file__elif_no_else.bend.snap | 8 +++++++ 5 files changed, 69 insertions(+) create mode 100644 tests/golden_tests/compile_file/elif.bend create mode 100644 tests/golden_tests/compile_file/elif_no_else.bend create mode 100644 tests/snapshots/compile_file__elif.bend.snap create mode 100644 tests/snapshots/compile_file__elif_no_else.bend.snap diff --git a/src/imp/parser.rs b/src/imp/parser.rs index 565649f31..293e34285 100644 --- a/src/imp/parser.rs +++ b/src/imp/parser.rs @@ -532,6 +532,21 @@ impl<'a> PyParser<'a> { if nxt_indent != *indent { return self.expected_indent(*indent, nxt_indent); } + let mut elifs = Vec::new(); + while self.try_parse_keyword("elif") { + let cond = self.parse_expr(true)?; + self.skip_trivia_inline(); + self.consume_exactly(":")?; + indent.enter_level(); + self.consume_indent_exactly(*indent)?; + let (then, nxt_indent) = self.parse_statement(indent)?; + indent.exit_level(); + + if nxt_indent != *indent { + return self.expected_indent(*indent, nxt_indent); + } + elifs.push((cond, then)); + } self.parse_keyword("else")?; self.skip_trivia_inline(); self.consume_exactly(":")?; @@ -539,6 +554,13 @@ impl<'a> PyParser<'a> { self.consume_indent_exactly(*indent)?; let (otherwise, nxt_indent) = self.parse_statement(indent)?; + let otherwise = elifs.into_iter().fold(otherwise, |acc, (cond, then)| Stmt::If { + cond: Box::new(cond), + then: Box::new(then), + otherwise: Box::new(acc), + nxt: None, + }); + indent.exit_level(); if nxt_indent == *indent { let (nxt, nxt_indent) = self.parse_statement(indent)?; diff --git a/tests/golden_tests/compile_file/elif.bend b/tests/golden_tests/compile_file/elif.bend new file mode 100644 index 000000000..222d4456e --- /dev/null +++ b/tests/golden_tests/compile_file/elif.bend @@ -0,0 +1,16 @@ +def main: + cond1 = 1 == 2 + cond2 = 2 < 1 + cond3 = 3 > 2 + cond4 = 2 == 2 + if cond1: + res = 1 + elif cond2: + res = 2 + elif cond3: + res = 3 + elif cond4: + res = 4 + else: + res = 0 + return res diff --git a/tests/golden_tests/compile_file/elif_no_else.bend b/tests/golden_tests/compile_file/elif_no_else.bend new file mode 100644 index 000000000..0f25c55df --- /dev/null +++ b/tests/golden_tests/compile_file/elif_no_else.bend @@ -0,0 +1,5 @@ +def main: + if 1 == 1: + return 0 + elif 2 == 2: + return 1 diff --git a/tests/snapshots/compile_file__elif.bend.snap b/tests/snapshots/compile_file__elif.bend.snap new file mode 100644 index 000000000..c2b506478 --- /dev/null +++ b/tests/snapshots/compile_file__elif.bend.snap @@ -0,0 +1,18 @@ +--- +source: tests/golden_tests.rs +input_file: tests/golden_tests/compile_file/elif.bend +--- +@main = d + & @main__C3 ~ (a (b (c d))) + & $(1 a) ~ [<2] + & $(2 b) ~ [>3] + & $(2 c) ~ [=2] + +@main__C0 = (?((0 (* 2)) a) a) + +@main__C1 = (a (?((@main__C0 (* (* 3))) (a b)) b)) + +@main__C2 = (a (b (?((@main__C1 (* (* (* 4)))) (a (b c))) c))) + +@main__C3 = a + & $(2 ?((@main__C2 (* (* (* (* 1))))) a)) ~ [=1] diff --git a/tests/snapshots/compile_file__elif_no_else.bend.snap b/tests/snapshots/compile_file__elif_no_else.bend.snap new file mode 100644 index 000000000..4a120f89d --- /dev/null +++ b/tests/snapshots/compile_file__elif_no_else.bend.snap @@ -0,0 +1,8 @@ +--- +source: tests/golden_tests.rs +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. + 6 |   From ac6f0fbb676a15d1fc9e9db1cec3965d775ede3f Mon Sep 17 00:00:00 2001 From: imaqtkatt Date: Mon, 27 May 2024 08:53:32 -0300 Subject: [PATCH 2/5] Bump version to 0.2.24 and update docs --- Cargo.lock | 2 +- Cargo.toml | 2 +- cspell.json | 6 ++---- docs/syntax.md | 13 +++++++++++++ 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index da20c41dc..3d262a8fd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -62,7 +62,7 @@ dependencies = [ [[package]] name = "bend-lang" -version = "0.2.23" +version = "0.2.24" dependencies = [ "TSPL", "clap", diff --git a/Cargo.toml b/Cargo.toml index 9fe0f30c6..c0e0fc55c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "bend-lang" description = "A high-level, massively parallel programming language" license = "Apache-2.0" -version = "0.2.23" +version = "0.2.24" edition = "2021" rust-version = "1.74" exclude = ["tests/snapshots/"] diff --git a/cspell.json b/cspell.json index 44d5b7473..9f352bbd8 100644 --- a/cspell.json +++ b/cspell.json @@ -32,6 +32,7 @@ "dref", "dups", "effectful", + "elifs", "foldl", "hasher", "hexdigit", @@ -120,10 +121,7 @@ "walkdir", "wopts" ], - "files": [ - "**/*.rs", - "**/*.md" - ], + "files": ["**/*.rs", "**/*.md"], "ignoreRegExpList": [ "HexValues", "/λ/g", diff --git a/docs/syntax.md b/docs/syntax.md index 9cb9d5b93..61bcd0b1b 100644 --- a/docs/syntax.md +++ b/docs/syntax.md @@ -193,6 +193,19 @@ A branching statement where `else` is mandatory. The condition must return a `u24` number, where 0 will run the `else` branch and any other value will return the first one. +It is possible to make if-chains using `elif`: + +```python +if condition1: + return 0 +elif condition2: + return 1 +elif condition3: + return 2 +else: + return 3 +``` + ### Switch ```python From bd5617ab30e9b06bd1b69d5f815113080b43eb58 Mon Sep 17 00:00:00 2001 From: imaqtkatt Date: Mon, 27 May 2024 08:56:52 -0300 Subject: [PATCH 3/5] Adjust cspell --- cspell.json | 1 + 1 file changed, 1 insertion(+) diff --git a/cspell.json b/cspell.json index 9f352bbd8..57844d28b 100644 --- a/cspell.json +++ b/cspell.json @@ -32,6 +32,7 @@ "dref", "dups", "effectful", + "elif", "elifs", "foldl", "hasher", From 6c9f87c98cd7c80c20d565c7322dd38a28d4f30f Mon Sep 17 00:00:00 2001 From: Nicolas Abril Date: Mon, 27 May 2024 15:01:21 +0200 Subject: [PATCH 4/5] Explain that elifs are evaluated sequentially in syntax.md --- docs/syntax.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/syntax.md b/docs/syntax.md index 61bcd0b1b..5471f4594 100644 --- a/docs/syntax.md +++ b/docs/syntax.md @@ -205,6 +205,7 @@ elif condition3: else: return 3 ``` +The conditions are evaluated in order, one by one, stopping at the first succesful case. ### Switch From 3ec35c5092bf4f6877a11c3fb65077c4576314b4 Mon Sep 17 00:00:00 2001 From: Nicolas Abril Date: Mon, 27 May 2024 15:15:15 +0200 Subject: [PATCH 5/5] Fix spelling of successful --- docs/syntax.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/syntax.md b/docs/syntax.md index 5471f4594..396f68847 100644 --- a/docs/syntax.md +++ b/docs/syntax.md @@ -205,7 +205,7 @@ elif condition3: else: return 3 ``` -The conditions are evaluated in order, one by one, stopping at the first succesful case. +The conditions are evaluated in order, one by one, stopping at the first successful case. ### Switch