Skip to content

Commit 6710a83

Browse files
morganthomasTomWambsgans
authored andcommitted
add else-if construct (#109)
1 parent e66024d commit 6710a83

File tree

4 files changed

+52
-29
lines changed

4 files changed

+52
-29
lines changed

crates/lean_compiler/src/grammar.pest

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,14 @@ single_assignment = { identifier ~ "=" ~ expression ~ ";" }
4242

4343
array_assign = { identifier ~ "[" ~ expression ~ "]" ~ "=" ~ expression ~ ";" }
4444

45-
if_statement = { "if" ~ condition ~ "{" ~ statement* ~ "}" ~ else_clause? }
45+
if_statement = { "if" ~ condition ~ "{" ~ statement* ~ "}" ~ else_if_clause* ~ else_clause? }
4646

4747
condition = { expression | assumed_bool_expr }
4848

4949
assumed_bool_expr = { "!!assume_bool" ~ "(" ~ expression ~ ")" }
5050

51+
else_if_clause = { "else" ~ "if" ~ condition ~ "{" ~ statement* ~ "}" }
52+
5153
else_clause = { "else" ~ "{" ~ statement* ~ "}" }
5254

5355
for_statement = { "for" ~ identifier ~ "in" ~ rev_clause? ~ expression ~ ".." ~ expression ~ unroll_clause? ~ "{" ~ statement* ~ "}" }

crates/lean_compiler/src/parser/parsers/statement.rs

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use super::function::{FunctionCallParser, TupleExpressionParser};
33
use super::literal::ConstExprParser;
44
use super::{Parse, ParseContext, next_inner_pair};
55
use crate::{
6+
SourceLineNumber,
67
ir::HighLevelOperation,
78
lang::{AssumeBoolean, Boolean, Condition, Expression, Line},
89
parser::{
@@ -88,14 +89,26 @@ impl Parse<Line> for IfStatementParser {
8889
let mut inner = pair.into_inner();
8990
let condition = ConditionParser::parse(next_inner_pair(&mut inner, "if condition")?, ctx)?;
9091

91-
let mut then_branch = Vec::new();
92-
let mut else_branch = Vec::new();
92+
let mut then_branch: Vec<Line> = Vec::new();
93+
let mut else_if_branches: Vec<(Condition, Vec<Line>, SourceLineNumber)> = Vec::new();
94+
let mut else_branch: Vec<Line> = Vec::new();
9395

9496
for item in inner {
9597
match item.as_rule() {
9698
Rule::statement => {
9799
Self::add_statement_with_location(&mut then_branch, item, ctx)?;
98100
}
101+
Rule::else_if_clause => {
102+
let line_number = item.line_col().0;
103+
let mut inner = item.into_inner();
104+
let else_if_condition =
105+
ConditionParser::parse(next_inner_pair(&mut inner, "else if condition")?, ctx)?;
106+
let mut else_if_branch = Vec::new();
107+
for else_if_item in inner {
108+
Self::add_statement_with_location(&mut else_if_branch, else_if_item, ctx)?;
109+
}
110+
else_if_branches.push((else_if_condition, else_if_branch, line_number));
111+
}
99112
Rule::else_clause => {
100113
for else_item in item.into_inner() {
101114
if else_item.as_rule() == Rule::statement {
@@ -107,10 +120,28 @@ impl Parse<Line> for IfStatementParser {
107120
}
108121
}
109122

123+
let mut outer_else_branch = Vec::new();
124+
let mut inner_else_branch = &mut outer_else_branch;
125+
126+
for (else_if_condition, else_if_branch, line_number) in else_if_branches.into_iter() {
127+
inner_else_branch.push(Line::IfCondition {
128+
condition: else_if_condition,
129+
then_branch: else_if_branch,
130+
else_branch: Vec::new(),
131+
line_number,
132+
});
133+
inner_else_branch = match &mut inner_else_branch[0] {
134+
Line::IfCondition { else_branch, .. } => else_branch,
135+
_ => unreachable!("Expected Line::IfCondition"),
136+
};
137+
}
138+
139+
inner_else_branch.extend(else_branch);
140+
110141
Ok(Line::IfCondition {
111142
condition,
112143
then_branch,
113-
else_branch,
144+
else_branch: outer_else_branch,
114145
line_number,
115146
})
116147
}

crates/lean_compiler/tests/test_compiler.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -257,17 +257,13 @@ fn test_mini_program_1() {
257257
for i in 0..N {
258258
if i == 0 {
259259
arr[i] = 10;
260+
} else if i == 1 {
261+
arr[i] = 20;
262+
} else if i == 2 {
263+
arr[i] = 30;
260264
} else {
261-
if i == 1 {
262-
arr[i] = 20;
263-
} else {
264-
if i == 2 {
265-
arr[i] = 30;
266-
} else {
267-
i_plus_one = i + 1;
268-
arr[i] = i_plus_one;
269-
}
270-
}
265+
i_plus_one = i + 1;
266+
arr[i] = i_plus_one;
271267
}
272268
}
273269
return;

crates/rec_aggregation/recursion_program.lean_lang

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -784,21 +784,15 @@ fn sample_bits_dynamic(fs_state, n_samples, K) -> 2 {
784784
if n_samples == NUM_QUERIES_0 {
785785
new_fs_state, sampled_bits = sample_bits_const(fs_state, NUM_QUERIES_0, K);
786786
return new_fs_state, sampled_bits;
787-
} else {
788-
if n_samples == NUM_QUERIES_1 {
789-
new_fs_state, sampled_bits = sample_bits_const(fs_state, NUM_QUERIES_1, K);
790-
return new_fs_state, sampled_bits;
791-
} else {
792-
if n_samples == NUM_QUERIES_2 {
793-
new_fs_state, sampled_bits = sample_bits_const(fs_state, NUM_QUERIES_2, K);
794-
return new_fs_state, sampled_bits;
795-
} else {
796-
if n_samples == NUM_QUERIES_3 {
797-
new_fs_state, sampled_bits = sample_bits_const(fs_state, NUM_QUERIES_3, K);
798-
return new_fs_state, sampled_bits;
799-
}
800-
}
801-
}
787+
} else if n_samples == NUM_QUERIES_1 {
788+
new_fs_state, sampled_bits = sample_bits_const(fs_state, NUM_QUERIES_1, K);
789+
return new_fs_state, sampled_bits;
790+
} else if n_samples == NUM_QUERIES_2 {
791+
new_fs_state, sampled_bits = sample_bits_const(fs_state, NUM_QUERIES_2, K);
792+
return new_fs_state, sampled_bits;
793+
} else if n_samples == NUM_QUERIES_3 {
794+
new_fs_state, sampled_bits = sample_bits_const(fs_state, NUM_QUERIES_3, K);
795+
return new_fs_state, sampled_bits;
802796
}
803797
print(n_samples);
804798
print(999333);

0 commit comments

Comments
 (0)