This provides gmapMFor and gmapMFor2, which are like gmapM, but know what
they're looking for, and can therefore avoid going down branches of the tree
that won't contain any interesting types.
The basic approach is quite similar to Uniplate's PlateData: there's a function
(containsType) that'll tell you whether one type is contained somewhere within
another. However, unlike Uniplate, we build a static IntMap IntSet of the types
we need to know about, which allows rather quicker lookups. (I did try using
PlateData first.)
The result is that applyDepthM is now much quicker than it was before.
applyDepthM2 is a bit less impressive, which I assume is because it can't
really prune the tree much if it's looking for two types.
Future enhancements:
- convert more passes to use applyDepthM*;
- make gmapMFor* aware of constructors rather than just types, which should
allow a bit more pruning.
This touches an awful lot of code, but cgtest07/17 (arrays and retyping) pass.
This is useful because there are going to be places in the future where we'll
want to represent dimensions that are known at runtime but not at compile time
-- for example, mobile allocations, or dynamically-sized arrays. It simplifies
the code in a number of places.
However, we do now need to be careful that expressions containing variables do
not leak into the State, since they won't be affected by later passes.
Two caveats (marked as FIXMEs in the source):
- Retypes checking in the occam parser is disabled, since the plan is to move
it out to a pass anyway.
- There's some (now very obvious) duplication, particularly in the backend, of
bits of code that construct expressions for the total size of an array
(either in bytes or elements); this should be moved to a couple of helper
functions that everything can use.
This works at least for simple examples, although it's probably a bit
restrictive on the array indexes you're allowed; it should attempt to
constant-fold them.
This lets you say things like:
VAL []INT xs IS [i = 0 FOR 20 | i]:
and have it figure out that the type of xs is really [20]INT.
This also cleans up the code a very small amount.