It's redundant, since you can always compute them from the variable, and it
makes the code that deals with actuals rather cleaner.
On the other hand, it slightly complicates some of the tests, because any names
you use in an Actual need to be defined...
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.
The existing constant-folding code in the parser is still there, since it needs
to know whether things are constant, and A.Dimension expects an Int.
However, this pass is useful because it does a better job of constant folding
than the parser would on its own: it can fold subexpressions of expressions
that are as a whole not constant.
This used to work by adding a magic prefix to the error message, but it appears
that doesn't work with the GHC 6.6 version of Parsec. It now searches for a
magic substring anywhere in the error message.
It uses // as a delimeter rather than \0 now, since including nulls in Strings
causes problems -- for example, putStr "a\0b" will only print "a".
This implements #DEFINE, #UNDEF, #IF, #ELSE and #ENDIF, macro expansion with
##, and TRUE, FALSE, AND, OR, NOT and DEFINED within #IF expressions, with the
same semantics as occ21.
The macro COMPILER.TOCK is always defined by default, so you can now say things
like "#IF NOT DEFINED (COMPILER.TOCK) ... #ENDIF".