Gir has three optimization passes. joinAdjacentOps --------------- * *consumes*: commands without offsets * *produces*: commands without offsets * *unknown commands*: passed through unmodified * *acts on*: `moveHead`, `add` `joinAdjacentOps` joins adjacent `moveHead`s and `add`s together. Normally `parse` joins runs of `<>` or `+-` into one command, but if the runs are interrupted by another character two commands get generated. `moveHead`s are joined first, before the pass goes over the generated commands again and joins `add`s. transformClearLoops ------------------- * *consumes*: commands without offsets * *produces*: commands without offsets * *unknown commands*: passed through unmodified * *acts on*: `loop` with one command, which is `add 1` or `add -1` `transformClearLoops` changes loops of the form `[-]` or `[+]` into a single `clear` command. addOffsetProperties ------------------- * *consumes*: commands without offsets * *produces*: commands with offsets * *unknown commands*: raise UnknownIRError * *acts on*: `moveHead`, `add`, `clear`, `writeByte`, `readByte`, `loop` `addOffsetProperties` adds an `offset` property to `add`, `clear`, `writeByte`, and `readByte`. The `offset` tells the offset at which from the current tape head location the operations are performed. It also adds an `isBalanced` property to loops. This property tells if execution of loop body ends at the same cell where it began, which is useful for performing further optimizations.