mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 06:44:46 +00:00
cleanup: we either have a guard or a test, not both
This commit is contained in:
parent
a22d1e9e4c
commit
541a62b109
2 changed files with 22 additions and 82 deletions
|
@ -61,13 +61,6 @@ enum DecisionTree<'a> {
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
enum GuardedTest<'a> {
|
enum GuardedTest<'a> {
|
||||||
TestGuarded {
|
|
||||||
test: Test<'a>,
|
|
||||||
|
|
||||||
/// after assigning to symbol, the stmt jumps to this label
|
|
||||||
id: JoinPointId,
|
|
||||||
stmt: Stmt<'a>,
|
|
||||||
},
|
|
||||||
// e.g. `_ if True -> ...`
|
// e.g. `_ if True -> ...`
|
||||||
GuardedNoTest {
|
GuardedNoTest {
|
||||||
/// after assigning to symbol, the stmt jumps to this label
|
/// after assigning to symbol, the stmt jumps to this label
|
||||||
|
@ -137,10 +130,6 @@ impl<'a> Hash for Test<'a> {
|
||||||
impl<'a> Hash for GuardedTest<'a> {
|
impl<'a> Hash for GuardedTest<'a> {
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
match self {
|
match self {
|
||||||
GuardedTest::TestGuarded { test, .. } => {
|
|
||||||
state.write_u8(0);
|
|
||||||
test.hash(state);
|
|
||||||
}
|
|
||||||
GuardedTest::GuardedNoTest { .. } => {
|
GuardedTest::GuardedNoTest { .. } => {
|
||||||
state.write_u8(1);
|
state.write_u8(1);
|
||||||
}
|
}
|
||||||
|
@ -249,7 +238,6 @@ fn guarded_tests_are_complete(tests: &[GuardedTest]) -> bool {
|
||||||
debug_assert!(length > 0);
|
debug_assert!(length > 0);
|
||||||
|
|
||||||
match tests.last().unwrap() {
|
match tests.last().unwrap() {
|
||||||
GuardedTest::TestGuarded { .. } => false,
|
|
||||||
GuardedTest::GuardedNoTest { .. } => false,
|
GuardedTest::GuardedNoTest { .. } => false,
|
||||||
GuardedTest::TestNotGuarded { test } => tests_are_complete_help(test, length),
|
GuardedTest::TestNotGuarded { test } => tests_are_complete_help(test, length),
|
||||||
}
|
}
|
||||||
|
@ -519,15 +507,7 @@ fn test_at_path<'a>(
|
||||||
StrLiteral(v) => IsStr(v.clone()),
|
StrLiteral(v) => IsStr(v.clone()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let guarded_test = if let Guard::Guard { id, stmt, .. } = &branch.guard {
|
let guarded_test = GuardedTest::TestNotGuarded { test };
|
||||||
GuardedTest::TestGuarded {
|
|
||||||
test,
|
|
||||||
stmt: stmt.clone(),
|
|
||||||
id: *id,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
GuardedTest::TestNotGuarded { test }
|
|
||||||
};
|
|
||||||
|
|
||||||
Some(guarded_test)
|
Some(guarded_test)
|
||||||
}
|
}
|
||||||
|
@ -565,30 +545,18 @@ fn to_relevant_branch<'a>(
|
||||||
start,
|
start,
|
||||||
found_pattern: pattern,
|
found_pattern: pattern,
|
||||||
end,
|
end,
|
||||||
} => {
|
} => match guarded_test {
|
||||||
let actual_test = match guarded_test {
|
|
||||||
GuardedTest::TestGuarded { test, .. } => test,
|
|
||||||
GuardedTest::GuardedNoTest { .. } => {
|
GuardedTest::GuardedNoTest { .. } => {
|
||||||
let mut new_branch = branch.clone();
|
new_branches.push(branch.clone());
|
||||||
|
|
||||||
new_branches.push(new_branch);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
GuardedTest::TestNotGuarded { test } => test,
|
GuardedTest::TestNotGuarded { test } => {
|
||||||
};
|
if let Some(new_branch) =
|
||||||
|
to_relevant_branch_help(test, path, start, end, branch, pattern)
|
||||||
if let Some(mut new_branch) = to_relevant_branch_help(
|
{
|
||||||
actual_test,
|
|
||||||
path,
|
|
||||||
start,
|
|
||||||
end,
|
|
||||||
branch,
|
|
||||||
branch.guard.clone(),
|
|
||||||
pattern,
|
|
||||||
) {
|
|
||||||
new_branches.push(new_branch);
|
new_branches.push(new_branch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -598,7 +566,6 @@ fn to_relevant_branch_help<'a>(
|
||||||
mut start: Vec<(Vec<PathInstruction>, Pattern<'a>)>,
|
mut start: Vec<(Vec<PathInstruction>, Pattern<'a>)>,
|
||||||
end: Vec<(Vec<PathInstruction>, Pattern<'a>)>,
|
end: Vec<(Vec<PathInstruction>, Pattern<'a>)>,
|
||||||
branch: &Branch<'a>,
|
branch: &Branch<'a>,
|
||||||
guard: Guard<'a>,
|
|
||||||
pattern: Pattern<'a>,
|
pattern: Pattern<'a>,
|
||||||
) -> Option<Branch<'a>> {
|
) -> Option<Branch<'a>> {
|
||||||
use Pattern::*;
|
use Pattern::*;
|
||||||
|
@ -1879,7 +1846,7 @@ fn fanout_decider<'a>(
|
||||||
let fallback_decider = tree_to_decider(fallback);
|
let fallback_decider = tree_to_decider(fallback);
|
||||||
let necessary_tests = edges
|
let necessary_tests = edges
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(test, tree)| fanout_decider_help(tree, test, &fallback_decider))
|
.map(|(test, tree)| fanout_decider_help(tree, test))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
Decider::FanOut {
|
Decider::FanOut {
|
||||||
|
@ -1892,25 +1859,15 @@ fn fanout_decider<'a>(
|
||||||
fn fanout_decider_help<'a>(
|
fn fanout_decider_help<'a>(
|
||||||
dectree: DecisionTree<'a>,
|
dectree: DecisionTree<'a>,
|
||||||
guarded_test: GuardedTest<'a>,
|
guarded_test: GuardedTest<'a>,
|
||||||
fallback_decider: &Decider<'a, u64>,
|
|
||||||
) -> (Test<'a>, Decider<'a, u64>) {
|
) -> (Test<'a>, Decider<'a, u64>) {
|
||||||
let decider = tree_to_decider(dectree);
|
|
||||||
|
|
||||||
match guarded_test {
|
match guarded_test {
|
||||||
GuardedTest::TestGuarded { test, id, stmt } => {
|
|
||||||
let guarded = Decider::Guarded {
|
|
||||||
id,
|
|
||||||
stmt,
|
|
||||||
success: Box::new(decider),
|
|
||||||
failure: Box::new(fallback_decider.clone()),
|
|
||||||
};
|
|
||||||
|
|
||||||
(test, guarded)
|
|
||||||
}
|
|
||||||
GuardedTest::GuardedNoTest { .. } => {
|
GuardedTest::GuardedNoTest { .. } => {
|
||||||
unreachable!("this would not end up in a switch")
|
unreachable!("this would not end up in a switch")
|
||||||
}
|
}
|
||||||
GuardedTest::TestNotGuarded { test } => (test, decider),
|
GuardedTest::TestNotGuarded { test } => {
|
||||||
|
let decider = tree_to_decider(dectree);
|
||||||
|
(test, decider)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1921,23 +1878,6 @@ fn chain_decider<'a>(
|
||||||
success_tree: DecisionTree<'a>,
|
success_tree: DecisionTree<'a>,
|
||||||
) -> Decider<'a, u64> {
|
) -> Decider<'a, u64> {
|
||||||
match guarded_test {
|
match guarded_test {
|
||||||
GuardedTest::TestGuarded { test, id, stmt } => {
|
|
||||||
let failure = Box::new(tree_to_decider(failure_tree));
|
|
||||||
let success = Box::new(tree_to_decider(success_tree));
|
|
||||||
|
|
||||||
let guarded = Decider::Guarded {
|
|
||||||
id,
|
|
||||||
stmt,
|
|
||||||
success,
|
|
||||||
failure: failure.clone(),
|
|
||||||
};
|
|
||||||
|
|
||||||
Decider::Chain {
|
|
||||||
test_chain: vec![(path, test)],
|
|
||||||
success: Box::new(guarded),
|
|
||||||
failure,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
GuardedTest::GuardedNoTest { id, stmt } => {
|
GuardedTest::GuardedNoTest { id, stmt } => {
|
||||||
let failure = Box::new(tree_to_decider(failure_tree));
|
let failure = Box::new(tree_to_decider(failure_tree));
|
||||||
let success = Box::new(tree_to_decider(success_tree));
|
let success = Box::new(tree_to_decider(success_tree));
|
||||||
|
|
|
@ -514,11 +514,11 @@ fn if_guard_constructor() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
when Identity 42 is
|
when Identity 42 "" is
|
||||||
Identity 41 -> 0
|
Identity 41 _ -> 0
|
||||||
Identity s if s == 3 -> 0
|
Identity 42 _ if 3 == 3 -> 0
|
||||||
# Identity 43 -> 0
|
# Identity 43 _ -> 0
|
||||||
Identity z -> z
|
Identity z _ -> z
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
42,
|
42,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue