Parametric types
This have been discussed for probably about a year in various forms, so I've finally decided to make a distinct issue for it.

So, the proposal is "parametric types", i.e. instancing a types, passing additional parameters during instancing. Initial draft was in https://github.com/kaitai-io/kaitai_struct/issues/78#issuecomment-272581874, here is the definition:

```yaml
meta:
  id: bcd
params:
  - id: num_bytes
    type: u4
  - id: is_half_byte
    type: bool
seq:
  - id: digits
    type:
      switch-on: is_half_byte
      cases:
        true: b4
        false: u1
    repeat: expr
    repeat-expr: is_half_byte ? (num_bytes * 2) : num_bytes
```

And I propose invocation to be something like that:

```yaml
seq:
  - id: my_bcd
    type: bcd
    params:
      num_bytes: 4
      is_half_byte: true
```

and may be a brief positional form:

```yaml
seq:
  - id: my_bcd
    type: bcd(4, true)
```

## Possible use cases

* Pass constants to customize standard library types (as in this BCD example) and keep library from exponential growth of repetitive code
* Pass runtime-only values into a type (like `_index`), so it will know its position in some list
* Unification of TLV-based parsing for different files. For example, many network protocol parsers have `linktype` field, linktype enum and a switch like that:
```yaml
      switch-on: some_field
      cases:
        'linktype::ppi': packet_ppi
        'linktype::ethernet': ethernet_frame
        # ...
```
Right now we have to duplicate it (both a switch and enum) in every file. With parametric type, it can be moved into a separate .ksy with single parameter: that `some_field` that would be used to switch parsing.
* May be we could reuse this syntax for [other possible new custom type](https://github.com/kaitai-io/kaitai_struct/issues/188)

## Implementation notes

### Type definition

`type` in `params` definition is not the same `type` as in all other attributes. It actually only declares in-memory type, not in-stream type, so it doesn't have a concept of endianness, it doesn't have any terminators, it can't have fixed size, it can't have `process`, etc, etc. This difference is subtle, but important. We never actually had a type system like that before, so it has to be developed. My proposal is to keep it as close to existing in-stream type system as possible:

* `uX` for unsigned ints
* `sX` for signed ints
* `fX` for floats
  * `(le|be)` suffixes are not valid here
  * `enum: XXX` is allowed to specify enum-type-over-integer
* `str` for strings
  * `strz` is not valid
* no value = byte array
* `bool` for booleans
* `io` for KaitaiStream
* `struct` for arbitrary KaitaiStruct-based instance
* `any` for arbitrary any type (`Object`, `Any`, etc), if target language supports it

I'm not sure if it's a good idea to allow passing arrays, but probably we can think of some "generic" array form as well, if that would be needed. Like `repeat: true` or something.

### Definition and invocation

If there are any parameters defined, they would be normally prepended into any constructor(s), something like:

```cpp
bcd_t::bcd_t(uint32_t p_num_bytes, bool p_is_half_byte, kaitai::kstream *p__io, kaitai::kstruct *p__parent, bcd_t *p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = this;

    // Store parameters
    m_num_bytes = p_num_bytes;
    m_is_half_byte = p_is_half_byte;
```

During invocation, a call like that is to be generated:

```cpp
m_foo = new bcd_t(4, true, m__io, this, m__root);
```

For now, I propose to implement all parameters as mandatory, mostly for initial simplicity. Later we can add something like `default: XXX` specification to allow default values (and thus optional parameters). Not passing a declared parameter or passing anything else beside declared parameters should be an error.

All opaque types are considered parameterless.

### Accessing

Parameters are to be treated exactly the same as eager seq attributes, the only difference is that they're received in constructor (and usually saved as fields of the object), not read in `_read` method. That means that relevant field declarations are to be generated, and relevant accessors. It should be possible to access parameters from other places in .ksy using normal `foo.bar.baz` syntax, i.e. something like `my_bcd.is_half_byte` should be legal.

Name clashes with other seq attributes / instance attributes are not allowed (check must be implemented).