fix conversion from inner opaque type for when and assignment
This fixes Clause being used in cases where ListClause or TupleClause should be used
Reset defined and zero arg functions between each code gen
Fixes for optimizations when encountering shadowed variables
This will be useful to re-use this behavior in other structure that contains a Program<DeBruijn> without having to manually serialize or deserialize the entire structure.
It's best to keep builtin as-close-as possible to their standard name
because they're hard to document. We can then leverage the prelude and
the standard lib for convenient names.
Supersedes #35.
The syntax for these elements isn't "set in stone"; in the sense that it is unspecified in [input-output-hk/plutus](https://github.com/input-output-hk/plutus). There's no visible plan from IOG to extend the Haskell parser to support this syntax, though there are samples of imagined syntax in the code. Thus, we can lead the way and simply choose a suitable syntax and let the Haskell implementation align to it later.
This syntax is thus inspired from input-output-hk/plutus' samples, with only a small change: we use `<` and `>` for encapsulating type declaration instead of `(`, `)`. There are already enough parentheses in the UPLC syntax, adding more reduces visibility.
Doing this, I've also added a lot more test cases for the UPLC parser. There could be more, but this is a good start.
Here are some example programs (taken from test cases) utilizing this syntax:
```
(program 0.0.0 (con list<bytestring> [#00, #01]))
```
```
(program 0.0.0
(con pair
<integer, integer>
[14, 42]
)
)
```
```
(program 0.0.0
(con pair<string, list<integer>> ["foo", [14, 42]])
)
```
_(Note that this was mainly done as an exercise to get more familiar with Rust and parts of Aiken.)_