Grammar for byte code representation of reflected types

A bytecode is used to represent a type together with its meta-data. It is implicitly assumed there is an associated string table holding the strings, indexed with a 16 bit integer.

The following (binary) grammar describes the byte code, where

int8 is a single byte
int16 is a 16 bit integer formed by 2 consecutive bytes in the byte code assuming little endian
int32 is a 32 bit integer formed by 4 consecutive bytes in the byte code assuming little endian
float64 is a 64 bit double precision floating point formed by 8 consecutive bytes in the byte code assuming little endian

meta-data:
    MDT_BOOL int8
    MDT_INT32 int32
    MDT_FLOAT64 float64
    MDT_STRING int32
    MDT_FUNCTOR_i int32 [meta-data]*i
    MDT_LIST_i          [meta-data]*i
    MDT_BEGIN_FUNCTOR int32 [meta-data]* MDT_END_FUNCTOR
    MDT_BEGIN_LIST          [meta-data]* MDT_END_LIST

basic-type:
    FT_VOID
    FT_BOOL
    FT_INT8
    FT_INT16
    FT_INT32
    FT_INT64
    FT_INT128
    FT_UINT8
    FT_UINT16
    FT_UINT32
    FT_UINT64
    FT_UINT128
    FT_FLOAT32
    FT_FLOAT64
    FT_CHAR8
    FT_CHAR16
    FT_STRING8
    FT_STRING16

ext-type-key:
    FT_CLASS
    FT_INTERFACE
    FT_TYPEDEF
    FT_ENUM
    FT_FUNCTOR
    FT_VARIANT
    FT_FUNCTION_PTR
    FT_NOT_REFLECTED

unary-type-qualifier:
    FT_VOLATILE                        volatile T
    FT_CONST                           const T
    FT_ASSIGNABLE
    FT_MOVABLE
    FT_OFFSETTABLE
    FT_POINTER                         T*
    FT_REFERENCE                       T&
    FT_INTERFACE_POINTER               ptr<T>    T = interface
    FT_OPEN_VARIANT                    openvariant<T>   T = interface
    FT_PREF                            pref<T>   T = interface
    FT_CREF                            cref<T>   T = concrete class
    FT_VECTOR                          xvector<T>
    FT_DEQUE                           xdeque<T>
    FT_LIST                            xlist<T>
    FT_SET                             xset<T>
    FT_BAG                             xbag<T>
    FT_DYNARRAY                        T[]

type:
    basic-type
    unary-type-qualifier type
    ext-type-key int16
    FT_ARRAY size type
    FT_MAP type type
    [MDT_FLAGS int32] [meta-data]* type

Note that ignoring metadata and qualifiers like FT_CONST, just after FT_CREF you always get
FT_CLASS then a 16 bit index into the string table for the name of the class.  Just after FT_PREF
or FT_INTERFACE_POINTER you always get FT_INTERFACE then a 16 bit index into the string table
for the name of the interface.

    FT_CREF FT_CLASS int16
    FT_PREF FT_INTERFACE int16
    FT_INTERFACE_POINTER FT_INTERFACE int16