Skip to content
Snippets Groups Projects

Normalize dynamic constants during typechecking

Merged rarbore2 requested to merge dc_typecheck_norm into main
1 file
+ 19
2
Compare changes
  • Side-by-side
  • Inline
use std::cmp::{max, min};
use std::collections::HashMap;
use std::iter::zip;
@@ -1128,7 +1129,8 @@ fn types_match(
/*
* Determine if the given dynamic constant matches the parameter's dynamic
* constants when the provided dynamic constants are substituted in for the
* dynamic constants used in the parameter's dynamic constant
* dynamic constants used in the parameter's dynamic constant. Implement dynamic
* constant normalization here as well - i.e., 1 * 2 * 3 = 6.
*/
fn dyn_consts_match(
dynamic_constants: &Vec<DynamicConstant>,
@@ -1136,6 +1138,14 @@ fn dyn_consts_match(
param: DynamicConstantID,
input: DynamicConstantID,
) -> bool {
// First, try evaluating the DCs and seeing if they're the same value.
if let (Some(cons1), Some(cons2)) = (
evaluate_dynamic_constant(param, dynamic_constants),
evaluate_dynamic_constant(input, dynamic_constants),
) {
return cons1 == cons2;
}
match (
&dynamic_constants[param.idx()],
&dynamic_constants[input.idx()],
@@ -1143,8 +1153,15 @@ fn dyn_consts_match(
(DynamicConstant::Constant(x), DynamicConstant::Constant(y)) => x == y,
(DynamicConstant::Parameter(i), _) => input == dc_args[*i],
(DynamicConstant::Add(pl, pr), DynamicConstant::Add(il, ir))
| (DynamicConstant::Sub(pl, pr), DynamicConstant::Sub(il, ir))
| (DynamicConstant::Mul(pl, pr), DynamicConstant::Mul(il, ir))
| (DynamicConstant::Min(pl, pr), DynamicConstant::Min(il, ir))
| (DynamicConstant::Max(pl, pr), DynamicConstant::Max(il, ir)) => {
// Normalize for associative ops by always looking at smaller DC ID
// as left arm and larger DC ID as right arm.
dyn_consts_match(dynamic_constants, dc_args, min(*pl, *pr), min(*il, *ir))
&& dyn_consts_match(dynamic_constants, dc_args, max(*pl, *pr), max(*il, *ir))
}
(DynamicConstant::Sub(pl, pr), DynamicConstant::Sub(il, ir))
| (DynamicConstant::Div(pl, pr), DynamicConstant::Div(il, ir))
| (DynamicConstant::Rem(pl, pr), DynamicConstant::Rem(il, ir)) => {
dyn_consts_match(dynamic_constants, dc_args, *pl, *il)
Loading