I was just thinking that, since at some point we will need to do constant-folding at parse time (for instance just at the end of every `statement:` rule), for folding array indexes, array sizes, and initialization expressions, it may make sense to treat the `lower_index_loads` pass in the same way, because we may also need the passes to split loads there.
We'll definitely need multiple passes to resolve constant expressions, and I expect that lower_index_loads() may be one of them. It probably makes most sense to add those as needed.
Performing those passes at the end of every statement rule seems questionable, and I think won't work anyway (since we need to lower expressions, not statements). Probably it should just be done when we need to, in evaluate_constant_expression() or whatever it's called now.