Skip to content

Commit

Permalink
Merge pull request #511 from HigherOrderCO/427-request-else-if-chains
Browse files Browse the repository at this point in the history
#427 else if chains
  • Loading branch information
developedby authored May 27, 2024
2 parents f5dfa48 + 3ec35c5 commit 7cb38c2
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 6 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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/"]
Expand Down
7 changes: 3 additions & 4 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
"dref",
"dups",
"effectful",
"elif",
"elifs",
"foldl",
"hasher",
"hexdigit",
Expand Down Expand Up @@ -120,10 +122,7 @@
"walkdir",
"wopts"
],
"files": [
"**/*.rs",
"**/*.md"
],
"files": ["**/*.rs", "**/*.md"],
"ignoreRegExpList": [
"HexValues",
"/λ/g",
Expand Down
14 changes: 14 additions & 0 deletions docs/syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,20 @@ 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
```
The conditions are evaluated in order, one by one, stopping at the first successful case.

### Switch

```python
Expand Down
22 changes: 22 additions & 0 deletions src/imp/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -532,13 +532,35 @@ 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(":")?;
indent.enter_level();

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)?;
Expand Down
16 changes: 16 additions & 0 deletions tests/golden_tests/compile_file/elif.bend
Original file line number Diff line number Diff line change
@@ -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
5 changes: 5 additions & 0 deletions tests/golden_tests/compile_file/elif_no_else.bend
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
def main:
if 1 == 1:
return 0
elif 2 == 2:
return 1
18 changes: 18 additions & 0 deletions tests/snapshots/compile_file__elif.bend.snap
Original file line number Diff line number Diff line change
@@ -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]
8 changes: 8 additions & 0 deletions tests/snapshots/compile_file__elif_no_else.bend.snap
Original file line number Diff line number Diff line change
@@ -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 |  

0 comments on commit 7cb38c2

Please sign in to comment.