The new system works by inserting code in the processing of all AST elements that directly contain a variable. If the variable needs to be dereferenced, it is. This only happens outside variables, and when a variable is subscripted. I did try putting this processing in doVariable, but then odd double-dereferences began to crop up, so I realised the processing has to happen outside the variable. It seems to pass cgtest85 fine, which it was having lots of trouble with before.
This makes sure that we catch all leftover instances of using SYB to do generic operations that we should be using Polyplate for instead. Most modules should only import Data, and possibly Typeable.
For some reason, the usage check tests are now very slow to run (perhaps because of all the operator definitions added to each one?), which needs further investigation.
The idea behind this is to parse unary/binary operators into function calls with 1/2 operands. So the AST actually has a FunctionCall with the name "+". Function names may now be quoted operators, and thus you can also have function declarations with names such as "+". Resolving is *not* done in the parser for these function names, but rather every "+" is left as "+" (no matter what types it operates on, or what is in scope) by the parser (see later patches to InferTypes instead).
When parsing an occam source file, we automatically insert a bunch of PRAGMA TOCKEXTERNAL that define the default occam operators (e.g. + on INT) as external C functions (which they are!). The naming scheme for these C functions is standardised, and must be used by functions such as mulExprs (which bases the function on the type of its operands) and the new versions mulExprsInt (which are pegged to INT).
The Types module also has some new functions for dealing with operator-functions.
This may seem like an odd change, but it simplifies the logic a lot. I kept having problems with passes not operating on externals (e.g. functions-to-procs, adding array sizes, constant folding in array dimensions) and adding a special case every time to also process the externals was getting silly.
Putting the externals in the AST therefore made sense, but I didn't want to just add dummy bodies as this would cause them to throw up errors (e.g. in the type-checking for functions). So I turned the bodies into a Maybe type, and that has worked out well.
I also stopped storing the formals in csExternals (since they are now in csNames, and the tree), which streamlined that nicely, and stopped me having to keep them up to date.