// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)

////////////////////////////////
//~ rjf: Generated File Format

@option library
@gen_folder "lib_rdi_format"
@h_name "rdi_format.h"
@c_name "rdi_format.c"

@h_header
{
  "////////////////////////////////////////////////////////////////";
  "//~ RAD Debug Info, (R)AD(D)BG(I) Format Library";
  "//";
  "// Defines standard RDI debug information format types and";
  "// functions.";
  "";
  "#ifndef RDI_FORMAT_H";
  "#define RDI_FORMAT_H";
  "";
  "////////////////////////////////////////////////////////////////";
  "//~ Overridable Procedure Decoration";
  "";
  "#if !defined(RDI_PROC)";
  "# define RDI_PROC static";
  "#endif";
  "";
  "////////////////////////////////////////////////////////////////";
  "//~ Overridable Basic Integer Types";
  "";
  "#if !defined(RDI_U8)";
  "# define RDI_U8 RDI_U8";
  "# define RDI_U16 RDI_U16";
  "# define RDI_U32 RDI_U32";
  "# define RDI_U64 RDI_U64";
  "# define RDI_S8 RDI_S8";
  "# define RDI_S16 RDI_S16";
  "# define RDI_S32 RDI_S32";
  "# define RDI_S64 RDI_S64";
  "#include <stdint.h>";
  "typedef uint8_t  RDI_U8;";
  "typedef uint16_t RDI_U16;";
  "typedef uint32_t RDI_U32;";
  "typedef uint64_t RDI_U64;";
  "typedef int8_t   RDI_S8;";
  "typedef int16_t  RDI_S16;";
  "typedef int32_t  RDI_S32;";
  "typedef int64_t  RDI_S64;";
  "#endif";
  "";
  "////////////////////////////////////////////////////////////////";
  "//~ Overridable Enabling/Disabling Of Table Index Typechecking";
  "";
  "#if !defined(RDI_DISABLE_TABLE_INDEX_TYPECHECKING)";
  "# define RDI_DISABLE_TABLE_INDEX_TYPECHECKING 0";
  "#endif";
  "";
  "////////////////////////////////////////////////////////////////";
  "//~ Format Constants";
  "";
  "// \"raddbg\\0\\0\"";
  "#define RDI_MAGIC_CONSTANT   0x0000676264646172";
  "#define RDI_ENCODING_VERSION 10";
  "";
  "////////////////////////////////////////////////////////////////";
  "//~ Format Types & Functions";
  "";
}

@h_footer
{
  "#endif // RDI_FORMAT_H";
}

@c_header
{
  "////////////////////////////////////////////////////////////////";
  "//~ RAD Debug Info, (R)AD(D)BG(I) Format Library";
  "//";
  "// Defines standard RDI debug information format types and";
  "// functions.";
  "";
  "#ifndef RDI_FORMAT_C";
  "#define RDI_FORMAT_C";
  "";
}

@c_footer
{
  "#endif // RDI_FORMAT_C";
}

////////////////////////////////
//~ rjf: Format Header Tables

@table(name type desc)
RDI_HeaderMemberTable:
{
  {magic                 RDI_U64    ""}
  {encoding_version      RDI_U32    ""}
  {data_section_off      RDI_U32    ""}
  {data_section_count    RDI_U32    ""}
}

@xlist RDI_Header_XList:
{
  @expand(RDI_HeaderMemberTable a) `$(a.type), $(a.name)`
}

@struct RDI_Header:
{
  @expand(RDI_HeaderMemberTable a) `$(a.type) $(a.name)`
}

////////////////////////////////
//~ rjf: Format Section Tables

@table(name  name_lower  element_type  value  is_required  index_base_type  desc)
RDI_SectionTable:
{
  {NULL                          null                               RDI_U8              0x0000   -    -                                              ""}
  {TopLevelInfo                  top_level_info                     RDI_TopLevelInfo    0x0001   -    -                                              ""}
  {StringData                    string_data                        RDI_U8              0x0002   x    -                                              ""}
  {StringTable                   string_table                       RDI_U32             0x0003   x    U32                                            ""}
  {IndexRuns                     index_runs                         RDI_U32             0x0004   x    U32                                            ""}
  {BinarySections                binary_sections                    RDI_BinarySection   0x0005   -    U32                                            ""}
  {FilePathNodes                 file_path_nodes                    RDI_FilePathNode    0x0006   -    U32                                            ""}
  {SourceFiles                   source_files                       RDI_SourceFile      0x0007   -    U32                                            ""}
  {LineTables                    line_tables                        RDI_LineTable       0x0008   -    U32                                            ""}
  {LineInfoVOffs                 line_info_voffs                    RDI_U64             0x0009   -    U32                                            ""}
  {LineInfoLines                 line_info_lines                    RDI_Line            0x000A   -    U32                                            ""}
  {LineInfoColumns               line_info_columns                  RDI_Column          0x000B   -    U32                                            ""}
  {SourceLineMaps                source_line_maps                   RDI_SourceLineMap   0x000C   -    U32                                            ""}
  {SourceLineMapNumbers          source_line_map_numbers            RDI_U32             0x000D   -    U32                                            ""}
  {SourceLineMapRanges           source_line_map_ranges             RDI_U32             0x000E   -    U32                                            ""}
  {SourceLineMapVOffs            source_line_map_voffs              RDI_U64             0x000F   -    U32                                            ""}
  {Units                         units                              RDI_Unit            0x0010   -    U32                                            ""}
  {UnitVMap                      unit_vmap                          RDI_VMapEntry       0x0011   -    -                                              ""}
  {TypeNodes                     type_nodes                         RDI_TypeNode        0x0012   -    U32                                            ""}
  {UDTs                          udts                               RDI_UDT             0x0013   -    U32                                            ""}
  {Members                       members                            RDI_Member          0x0014   -    U32                                            ""}
  {EnumMembers                   enum_members                       RDI_EnumMember      0x0015   -    U32                                            ""}
  {GlobalVariables               global_variables                   RDI_GlobalVariable  0x0016   -    U32                                            ""}
  {GlobalVMap                    global_vmap                        RDI_VMapEntry       0x0017   -    -                                              ""}
  {ThreadVariables               thread_variables                   RDI_ThreadVariable  0x0018   -    U32                                            ""}
  {Procedures                    procedures                         RDI_Procedure       0x0019   -    U32                                            ""}
  {Scopes                        scopes                             RDI_Scope           0x001A   -    U32                                            ""}
  {ScopeVOffData                 scope_voff_data                    RDI_U64             0x001B   -    U32                                            ""}
  {ScopeVMap                     scope_vmap                         RDI_VMapEntry       0x001C   -    -                                              ""}
  {InlineSites                   inline_sites                       RDI_InlineSite      0x001D   -    U32                                            ""}
  {Locals                        locals                             RDI_Local           0x001E   -    U32                                            ""}
  {LocationBlocks                location_blocks                    RDI_LocationBlock   0x001F   -    U32                                            ""}
  {LocationData                  location_data                      RDI_U8              0x0020   -    U32                                            ""}
  {NameMaps                      name_maps                          RDI_NameMap         0x0021   -    U32                                            ""}
  {NameMapBuckets                name_map_buckets                   RDI_NameMapBucket   0x0022   -    U32                                            ""}
  {NameMapNodes                  name_map_nodes                     RDI_NameMapNode     0x0023   -    U32                                            ""}
  {COUNT                         count                              RDI_U8              0x0024   -    -                                              ""}
}

@table(name value)
RDI_SectionEncodingTable:
{
  {Unpacked 0}
  {LZB      1}
}

@table(name type desc)
RDI_SectionMemberTable:
{
  {encoding      RDI_SectionEncoding ""}
  {pad           RDI_U32                 ""}
  {off           RDI_U64                 ""}
  {encoded_size  RDI_U64                 ""}
  {unpacked_size RDI_U64                 ""}
}

@enum(RDI_U32) RDI_SectionKind:
{
  @expand(RDI_SectionTable a) `$(a.name .. =>20) = $(a.value)`,
}

@enum(RDI_U32) RDI_SectionEncoding:
{
  @expand(RDI_SectionEncodingTable a) `$(a.name .. =>10) = $(a.value)`,
}

@xlist RDI_SectionKind_XList:
{
  @expand(RDI_SectionTable a) `$(a.name != COUNT -> a.name .. ', ' .. a.name_lower .. ', ' .. a.element_type)`;
}

@xlist RDI_SectionEncoding_XList:
{
  @expand(RDI_SectionEncodingTable a) `$(a.name)`;
}

@xlist RDI_Section_XList:
{
  @expand(RDI_SectionMemberTable a) `$(a.type), $(a.name)`
}

@struct RDI_Section:
{
  @expand(RDI_SectionMemberTable a) `$(a.type) $(a.name)`
}

@gen(enums)
{
  `#if !RDI_DISABLE_TABLE_INDEX_TYPECHECKING`;
  @expand(RDI_SectionTable a) `$(a.index_base_type != '-' -> "typedef struct RDI_" .. a.index_base_type .. "_" .. a.name .. =>50 .. " { RDI_" .. a.index_base_type .. " v; }".. " RDI_" .. a.index_base_type .. "_" .. a.name .. ";")`;
  `#else`;
  `typedef struct RDI_U32_Table { RDI_U32 v; } RDI_U32_Table;`;
  `typedef struct RDI_U64_Table { RDI_U64 v; } RDI_U64_Table;`;
  @expand(RDI_SectionTable a) `$(a.index_base_type != '-' -> "typedef RDI_" .. a.index_base_type .. "_Table RDI_" .. a.index_base_type .. "_" .. a.name .. ";")`;
  `#endif`;
  ``;
}

@gen(catchall)
{
  @expand(RDI_SectionTable a) `$(a.name != COUNT && a.name != NULL -> "typedef " .. a.element_type .. =>40 .. " RDI_SectionElementType_" .. a.name .. ";")`;
  ``;
}

@data(RDI_U16) rdi_section_element_size_table:
{
  @expand(RDI_SectionTable a) `sizeof($(a.element_type))`;
}

@data(RDI_U8) rdi_section_is_required_table:
{
  @expand(RDI_SectionTable a) `$(a.is_required == 'x' -> 1)$(a.is_required != 'x' -> 0)`;
}

////////////////////////////////
//~ rjf: Common Type Tables

@table(name type desc)
RDI_VMapEntryMemberTable:
{
  {voff RDI_U64 ""}
  {idx  RDI_U64 ""}
}

@xlist RDI_VMapEntry_XList:
{
  @expand(RDI_VMapEntryMemberTable a) `$(a.type), $(a.name)`
}

@struct RDI_VMapEntry:
{
  @expand(RDI_VMapEntryMemberTable a) `$(a.type) $(a.name)`
}

////////////////////////////////
//~ rjf: Arch Info Tables

@table(name value addr_size)
RDI_ArchTable:
{
  {NULL    0     0}
  {X86     1     4}
  {X64     2     8}
}

@table(name value)
RDI_RegCodeX86Table:
{
  {nil             0}
  {eax             1}
  {ecx             2}
  {edx             3}
  {ebx             4}
  {esp             5}
  {ebp             6}
  {esi             7}
  {edi             8}
  {fsbase          9}
  {gsbase         10}
  {eflags         11}
  {eip            12}
  {dr0            13}
  {dr1            14}
  {dr2            15}
  {dr3            16}
  {dr4            17}
  {dr5            18}
  {dr6            19}
  {dr7            20}
  {fpr0           21}
  {fpr1           22}
  {fpr2           23}
  {fpr3           24}
  {fpr4           25}
  {fpr5           26}
  {fpr6           27}
  {fpr7           28}
  {st0            29}
  {st1            30}
  {st2            31}
  {st3            32}
  {st4            33}
  {st5            34}
  {st6            35}
  {st7            36}
  {fcw            37}
  {fsw            38}
  {ftw            39}
  {fop            40}
  {fcs            41}
  {fds            42}
  {fip            43}
  {fdp            44}
  {mxcsr          45}
  {mxcsr_mask     46}
  {ss             47}
  {cs             48}
  {ds             49}
  {es             50}
  {fs             51}
  {gs             52}
  {ymm0           53}
  {ymm1           54}
  {ymm2           55}
  {ymm3           56}
  {ymm4           57}
  {ymm5           58}
  {ymm6           59}
  {ymm7           60}
}

@table(name value)
RDI_RegCodeX64Table:
{
  {nil             0}
  {rax             1}
  {rcx             2}
  {rdx             3}
  {rbx             4}
  {rsp             5}
  {rbp             6}
  {rsi             7}
  {rdi             8}
  {r8              9}
  {r9              10}
  {r10             11}
  {r11             12}
  {r12             13}
  {r13             14}
  {r14             15}
  {r15             16}
  {es              17}
  {cs              18}
  {ss              19}
  {ds              20}
  {fs              21}
  {gs              22}
  {rip             23}
  {rflags          24}
  {dr0             25}
  {dr1             26}
  {dr2             27}
  {dr3             28}
  {dr4             29}
  {dr5             30}
  {dr6             31}
  {dr7             32}
  {st0             33}
  {st1             34}
  {st2             35}
  {st3             36}
  {st4             37}
  {st5             38}
  {st6             39}
  {st7             40}
  {fpr0            41}
  {fpr1            42}
  {fpr2            43}
  {fpr3            44}
  {fpr4            45}
  {fpr5            46}
  {fpr6            47}
  {fpr7            48}
  {zmm0            49}
  {zmm1            50}
  {zmm2            51}
  {zmm3            52}
  {zmm4            53}
  {zmm5            54}
  {zmm6            55}
  {zmm7            56}
  {zmm8            57}
  {zmm9            58}
  {zmm10           59}
  {zmm11           60}
  {zmm12           61}
  {zmm13           62}
  {zmm14           63}
  {zmm15           64}
  {zmm16           65}
  {zmm17           66}
  {zmm18           67}
  {zmm19           68}
  {zmm20           69}
  {zmm21           70}
  {zmm22           71}
  {zmm23           72}
  {zmm24           73}
  {zmm25           74}
  {zmm26           75}
  {zmm27           76}
  {zmm28           77}
  {zmm29           78}
  {zmm30           79}
  {zmm31           80}
  {k0              81}
  {k1              82}
  {k2              83}
  {k3              84}
  {k4              85}
  {k5              86}
  {k6              87}
  {k7              88}
  {mxcsr           89}
  {fsbase          90}
  {gsbase          91}
  {fcw             92}
  {fsw             93}
  {ftw             94}
  {fop             95}
  {fcs             96}
  {fds             97}
  {fip             98}
  {fdp             99}
  {mxcsr_mask      100}
}

@enum(RDI_U32) RDI_Arch:
{
  @expand(RDI_ArchTable a) `$(a.name .. =>10) = $(a.value)`
}

@xlist RDI_Arch_XList:
{
  @expand(RDI_ArchTable a) `$(a.name)`;
}

@enum(RDI_U8) RDI_RegCode: {nil}

@enum(RDI_U8) RDI_RegCodeX86:
{
  @expand(RDI_RegCodeX86Table a) `$(a.name .. =>10) = $(a.value)`
}

@enum(RDI_U8) RDI_RegCodeX64:
{
  @expand(RDI_RegCodeX64Table a) `$(a.name .. =>10) = $(a.value)`
}

@xlist RDI_RegCodeX86_XList:
{
  @expand(RDI_RegCodeX86Table a) `$(a.name), $(a.value)`
}

@xlist RDI_RegCodeX64_XList:
{
  @expand(RDI_RegCodeX64Table a) `$(a.name), $(a.value)`
}

////////////////////////////////
//~ rjf: Top-Level Info Type Tables

@table(name type desc)
RDI_TopLevelInfoMemberTable:
{
  {arch                     RDI_Arch              ""}
  {exe_name_string_idx      RDI_U32               ""}
  {exe_hash                 RDI_U64               ""}
  {voff_max                 RDI_U64               ""}
  {producer_name_string_idx RDI_U32               ""}
}

@xlist RDI_TopLevelInfo_XList:
{
  @expand(RDI_TopLevelInfoMemberTable a) `$(a.type), $(a.name)`
}

@struct RDI_TopLevelInfo:
{
  @expand(RDI_TopLevelInfoMemberTable a) `$(a.type) $(a.name)`
}

////////////////////////////////
//~ rjf: Binary Section Info Type Tables

@table(name value)
RDI_BinarySectionFlagTable:
{
  {Read     `1<<0`}
  {Write    `1<<1`}
  {Execute  `1<<2`}
}

@table(name type desc)
RDI_BinarySectionMemberTable:
{
  {name_string_idx  RDI_U32                  ""}
  {flags            RDI_BinarySectionFlags   ""}
  {voff_first       RDI_U64                  ""}
  {voff_opl         RDI_U64                  ""}
  {foff_first       RDI_U64                  ""}
  {foff_opl         RDI_U64                  ""}
}

@enum(RDI_U32) RDI_BinarySectionFlags:
{
  @expand(RDI_BinarySectionFlagTable a) `$(a.name .. =>10) = $(a.value)`;
}

@xlist RDI_BinarySectionFlags_XList:
{
  @expand(RDI_BinarySectionFlagTable a) `$(a.name)`;
}

@xlist RDI_BinarySection_XList:
{
  @expand(RDI_BinarySectionMemberTable a) `$(a.type), $(a.name)`
}

@struct RDI_BinarySection:
{
  @expand(RDI_BinarySectionMemberTable a) `$(a.type) $(a.name)`
}

////////////////////////////////
//~ rjf: File Path Tree Info Type Tables

@table(name type desc)
RDI_FilePathNodeMemberTable:
{
  {name_string_idx   RDI_U32                ""}
  {parent_path_node  RDI_U32                ""}
  {first_child       RDI_U32                ""}
  {next_sibling      RDI_U32                ""}
  {source_file_idx   RDI_U32                ""}
}

@table(name type desc)
RDI_SourceFileMemberTable:
{
  {file_path_node_idx           RDI_U32        ""}
  {normal_full_path_string_idx  RDI_U32        ""}
  // usage of line map to go from a line number to an array of voffs
  //  (line_map_nums * line_number) -> (nil | index)
  //  (line_map_data * index) -> (range)
  //  (line_map_voff_data * range) -> (array(voff))
  {source_line_map_idx          RDI_U32        ""}
}

@xlist RDI_FilePathNode_XList:
{
  @expand(RDI_FilePathNodeMemberTable a) `$(a.type), $(a.name)`
}

@xlist RDI_SourceFile_XList:
{
  @expand(RDI_SourceFileMemberTable a) `$(a.type), $(a.name)`
}

@struct RDI_FilePathNode:
{
  @expand(RDI_FilePathNodeMemberTable a) `$(a.type) $(a.name)`
}

@struct RDI_SourceFile:
{
  @expand(RDI_SourceFileMemberTable a) `$(a.type) $(a.name)`
}

////////////////////////////////
//~ rjf: Unit Info Type Tables

@table(name type desc)
RDI_UnitMemberTable:
{
  {unit_name_string_idx          RDI_U32               ""}
  {compiler_name_string_idx      RDI_U32               ""}
  {source_file_path_node         RDI_U32               ""}
  {object_file_path_node         RDI_U32               ""}
  {archive_file_path_node        RDI_U32               ""}
  {build_path_node               RDI_U32               ""}
  {language                      RDI_Language          ""}
  {line_table_idx                RDI_U32               ""}
}

@xlist RDI_Unit_XList:
{
  @expand(RDI_UnitMemberTable a) `$(a.type), $(a.name)`
}

@struct RDI_Unit:
{
  @expand(RDI_UnitMemberTable a) `$(a.type) $(a.name)`
}

////////////////////////////////
//~ rjf: Line Info Type Tables

@table(name type desc)
RDI_LineTableMemberTable:
{
  // usage of line info to go from voff to file & line number:
  //  (line_info_voffs * voff) -> (nil + index)
  //  (line_info_data * index) -> (RDI_Line = (file_idx * line_number))
  {voffs_base_idx     RDI_U32                   ""} // U64[lines_count+1] (sorted ranges)
  {lines_base_idx     RDI_U32                   ""} // RDI_Line[lines_count]
  {cols_base_idx      RDI_U32                   ""} // RDI_Column[cols_count]
  {lines_count        RDI_U32                   ""}
  {cols_count         RDI_U32                   ""}
}

@table(name type desc)
RDI_LineMemberTable:
{
  {file_idx    RDI_U32                 ""}
  {line_num    RDI_U32                 ""}
}

@table(name type desc)
RDI_ColumnMemberTable:
{
  {col_first  RDI_U16     ""}
  {col_opl    RDI_U16     ""}
}

@table(name type desc)
RDI_SourceLineMapMemberTable:
{
  // usage of line map to go from a line number to an array of voffs
  //  (line_map_nums * line_number) -> (nil | index)
  //  (line_map_data * index) -> (range)
  //  (line_map_voff_data * range) -> (array(voff))
  {line_count                   RDI_U32                               ""}
  {voff_count                   RDI_U32                               ""}
  {line_map_nums_base_idx       RDI_U32                               ""} // U32[line_count] (sorted - not closed ranges)
  {line_map_range_base_idx      RDI_U32                               ""} // U32[line_count + 1] (pairs form ranges)
  {line_map_voff_base_idx       RDI_U32                               ""} // U64[voff_count] (idx by line_map_range_data)
}

@xlist RDI_LineTable_XList:
{
  @expand(RDI_LineTableMemberTable a) `$(a.type), $(a.name)`
}

@xlist RDI_Line_XList:
{
  @expand(RDI_LineMemberTable a) `$(a.type), $(a.name)`
}

@xlist RDI_Column_XList:
{
  @expand(RDI_ColumnMemberTable a) `$(a.type), $(a.name)`
}

@xlist RDI_SourceLineMapMemberTable:
{
  @expand(RDI_SourceLineMapMemberTable a) `$(a.type), $(a.name)`
}

@struct RDI_LineTable:
{
  @expand(RDI_LineTableMemberTable a) `$(a.type) $(a.name)`
}

@struct RDI_Line:
{
  @expand(RDI_LineMemberTable a) `$(a.type) $(a.name)`
}

@struct RDI_Column:
{
  @expand(RDI_ColumnMemberTable a) `$(a.type) $(a.name)`
}

@struct RDI_SourceLineMap:
{
  @expand(RDI_SourceLineMapMemberTable a) `$(a.type) $(a.name)`
}

////////////////////////////////
//~ rjf: Language Info Tables

@table(name value)
RDI_LanguageTable:
{
  {NULL        0}
  {C           1}
  {CPlusPlus   2}
  {Masm        3}
  {COUNT       4}
}

@enum(RDI_U32) RDI_Language:
{
  @expand(RDI_LanguageTable a) `$(a.name .. =>10) = $(a.value)`
}

@xlist RDI_Language_XList:
{
  @expand(RDI_LanguageTable a) `$(a.name)`;
}

////////////////////////////////
//~ rjf: Type Info Tables

@table(name value size bookend1 bookend2)
RDI_TypeKindTable:
{
  {NULL                 0x0000     0                                             }
  //-
  {Void                 0x0001     0              FirstBuiltIn                   }
  {Handle               0x0002     0xFFFFFFFF                                    }
  {HResult              0x0003     4                                             }
  {Char8                0x0004     1                                             }
  {Char16               0x0005     2                                             }
  {Char32               0x0006     4                                             }
  {UChar8               0x0007     1                                             }
  {UChar16              0x0008     2                                             }
  {UChar32              0x0009     4                                             }
  {U8                   0x000A     1                                             }
  {U16                  0x000B     2                                             }
  {U32                  0x000C     4                                             }
  {U64                  0x000D     8                                             }
  {U128                 0x000E     16                                            }
  {U256                 0x000F     32                                            }
  {U512                 0x0010     64                                            }
  {S8                   0x0011     1                                             }
  {S16                  0x0012     2                                             }
  {S32                  0x0013     4                                             }
  {S64                  0x0014     8                                             }
  {S128                 0x0015     16                                            }
  {S256                 0x0016     32                                            }
  {S512                 0x0017     64                                            }
  {Bool                 0x0018     1                                             }
  {F16                  0x0019     2                                             }
  {F32                  0x001A     4                                             }
  {F32PP                0x001B     4                                             }
  {F48                  0x001C     6                                             }
  {F64                  0x001D     8                                             }
  {F80                  0x001E     10                                            }
  {F128                 0x001F     16                                            }
  {ComplexF32           0x0020     8                                             }
  {ComplexF64           0x0021     16                                            }
  {ComplexF80           0x0022     20                                            }
  {ComplexF128          0x0023     32              LastBuiltIn                   }
  //-
  {Modifier             0x1000     0               FirstConstructed              }
  {Ptr                  0x1001     0                                             }
  {LRef                 0x1002     0                                             }
  {RRef                 0x1003     0                                             }
  {Array                0x1004     0                                             }
  {Function             0x1005     0                                             }
  {Method               0x1006     0                                             }
  {MemberPtr            0x1007     0               LastConstructed               }
  //-
  {Struct               0x2000     0               FirstUserDefined FirstRecord  }
  {Class                0x2001     0                                             }
  {Union                0x2002     0               LastRecord                    }
  {Enum                 0x2003     0                                             }
  {Alias                0x2004     0                                             }
  {IncompleteStruct     0x2005     0               FirstIncomplete               }
  {IncompleteUnion      0x2006     0                                             }
  {IncompleteClass      0x2007     0                                             }
  {IncompleteEnum       0x2008     0               LastIncomplete LastUserDefined}
  //-
  {Bitfield             0xF000     0                                             }
  {Variadic             0xF001     0                                             }
  {Count                0xF002     0                                             }
}

@table(name value)
RDI_TypeModifierFlagTable:
{
  {Const     `1<<0`}
  {Volatile  `1<<1`}
}

@table(name type_lhs type_rhs desc)
RDI_TypeNodeMemberTable:
{
  {kind       RDI_TypeKind ``     ""}
  {flags      RDI_U16      ``     ""}
  {byte_size  RDI_U32      ``     ""}
}

@table(name value)
RDI_UDTFlagTable:
{
  {EnumMembers `1<<0`}
}

@table(name type desc)
RDI_UDTMemberTable:
{
  {self_type_idx   RDI_U32                   ""}
  {flags           RDI_UDTFlags              ""}
  {member_first    RDI_U32                   ""}
  {member_count    RDI_U32                   ""}
  {file_idx        RDI_U32                   ""}
  {line            RDI_U32                   ""}
  {col             RDI_U32                   ""}
}

@table(name value)
RDI_MemberKindTable:
{
  {NULL          0x0000}
  {DataField     0x0001}
  {StaticData    0x0002}
  {Method        0x0100}
  {StaticMethod  0x0101}
  {VirtualMethod 0x0102}
  {VTablePtr     0x0200}
  {Base          0x0201}
  {VirtualBase   0x0202}
  {NestedType    0x0300}
}

@table(name type desc)
RDI_MemberMemberTable:
{
  {kind            RDI_MemberKind                  ""}
  {pad             RDI_U16                         ""}
  {name_string_idx RDI_U32                         ""}
  {type_idx        RDI_U32                         ""}
  {off             RDI_U32                         ""}
}

@table(name type desc)
RDI_EnumMemberTable:
{
  {name_string_idx RDI_U32                  ""}
  {pad             RDI_U32                  ""}
  {val             RDI_U64                  ""}
}

@enum(RDI_U16) RDI_TypeKind:
{
  @expand(RDI_TypeKindTable a) `$(a.name .. =>20) = $(a.value)`;
  @expand(RDI_TypeKindTable a) `$(a.bookend1 != "" -> a.bookend1 .. =>20 .. " = RDI_TypeKind_" .. a.name)`;
  @expand(RDI_TypeKindTable a) `$(a.bookend2 != "" -> a.bookend2 .. =>20 .. " = RDI_TypeKind_" .. a.name)`;
}

@enum(RDI_U16) RDI_TypeModifierFlags:
{
  @expand(RDI_TypeModifierFlagTable a) `$(a.name .. =>20) = $(a.value)`,
}

@xlist RDI_TypeKind_XList:
{
  @expand(RDI_TypeKindTable a) `$(a.name)`;
}

@xlist RDI_TypeModifierFlags_XList:
{
  @expand(RDI_TypeModifierFlagTable a) `$(a.name)`;
}

@xlist RDI_TypeNode_XList:
{
  @expand(RDI_TypeNodeMemberTable a) `$(a.type_lhs), $(a.name)`
}

@struct RDI_TypeNode:
{
  @expand(RDI_TypeNodeMemberTable a) `$(a.type_lhs) $(a.name)$(a.type_rhs)`
    ```
    union
  {
    // kind is 'built-in'
    struct
    {
      RDI_U32 name_string_idx;
    } built_in;
    
    // kind is 'constructed'
    struct
    {
      RDI_U32 direct_type_idx;
      RDI_U32 count;
      union
      {
        // when kind is 'Function' or 'Method'
        RDI_U32 param_idx_run_first;
        // when kind is 'MemberPtr'
        RDI_U32 owner_type_idx;
      };
    }
    constructed;
    
    // kind is 'user defined'
    struct
    {
      RDI_U32 name_string_idx;
      RDI_U32 direct_type_idx;
      RDI_U32 udt_idx;
    }
    user_defined;
    
    // (kind = Bitfield)
    struct
    {
      RDI_U32 direct_type_idx;
      RDI_U32 off;
      RDI_U32 size;
    }
    bitfield;
  }
  ```
}

@enum(RDI_U32) RDI_UDTFlags:
{
  @expand(RDI_UDTFlagTable a) `$(a.name .. =>20) = $(a.value)`
}

@xlist RDI_UDTFlags_XList:
{
  @expand(RDI_UDTFlagTable a) `$(a.name)`;
}

@xlist RDI_UDT_XList:
{
  @expand(RDI_UDTMemberTable a) `$(a.type), $(a.name)`
}

@struct RDI_UDT:
{
  @expand(RDI_UDTMemberTable a) `$(a.type) $(a.name)`
}

@enum(RDI_U16) RDI_MemberKind:
{
  @expand(RDI_MemberKindTable a) `$(a.name .. =>25) = $(a.value)`
}

@xlist RDI_MemberKind_XList:
{
  @expand(RDI_MemberKindTable a) `$(a.name)`;
}

@xlist RDI_Member_XList:
{
  @expand(RDI_MemberMemberTable a) `$(a.type), $(a.name)`
}

@xlist RDI_EnumMember_XList:
{
  @expand(RDI_EnumMemberTable a) `$(a.type), $(a.name)`
}

@struct RDI_Member:
{
  @expand(RDI_MemberMemberTable a) `$(a.type) $(a.name)`
}

@struct RDI_EnumMember:
{
  @expand(RDI_EnumMemberTable a) `$(a.type) $(a.name)`
}

////////////////////////////////
//~ rjf: Symbol Info Tables

//- rjf: tables

@table(name value)
RDI_LinkFlagTable:
{
  {External   `1<<0`}
  {TypeScoped `1<<1`}
  {ProcScoped `1<<2`}
}

@table(name value)
RDI_LocalKindTable:
{
  {NULL      0x0}
  {Parameter 0x1}
  {Variable  0x2}
}

@table(name value)
RDI_LocationKindTable:
{
  {NULL                 0x0}
  {AddrBytecodeStream   0x1}
  {ValBytecodeStream    0x2}
  {AddrRegPlusU16       0x3}
  {AddrAddrRegPlusU16   0x4}
  {ValReg               0x5}
}

@table(name type desc)
RDI_GlobalVariableMemberTable:
{
  {name_string_idx   RDI_U32               ""}
  {link_flags        RDI_LinkFlags         ""}
  {voff              RDI_U64               ""}
  {type_idx          RDI_U32               ""}
  {container_idx     RDI_U32               ""}
}

@table(name type desc)
RDI_ThreadVariableMemberTable:
{
  {name_string_idx   RDI_U32                    ""}
  {link_flags        RDI_LinkFlags              ""}
  {tls_off           RDI_U32                    ""}
  {type_idx          RDI_U32                    ""}
  {container_idx     RDI_U32                    ""}
}

@table(name type desc)
RDI_ProcedureMemberTable:
{
  {name_string_idx        RDI_U32                    ""}
  {link_name_string_idx   RDI_U32                    ""}
  {link_flags             RDI_LinkFlags              ""}
  {type_idx               RDI_U32                    ""}
  {root_scope_idx         RDI_U32                    ""}
  {container_idx          RDI_U32                    ""}
}

@table(name type desc)
RDI_ScopeMemberTable:
{
  {proc_idx                   RDI_U32               ""}
  {parent_scope_idx           RDI_U32               ""}
  {first_child_scope_idx      RDI_U32               ""}
  {next_sibling_scope_idx     RDI_U32               ""}
  {voff_range_first           RDI_U32               ""}
  {voff_range_opl             RDI_U32               ""}
  {local_first                RDI_U32               ""}
  {local_count                RDI_U32               ""}
  {static_local_idx_run_first RDI_U32               ""}
  {static_local_count         RDI_U32               ""}
  {inline_site_idx            RDI_U32               ""}
}

@table(name type desc)
RDI_InlineSiteMemberTable:
{
  {name_string_idx     RDI_U32              ""}
  {type_idx            RDI_U32              ""}
  {owner_type_idx      RDI_U32              ""}
  {line_table_idx      RDI_U32              ""}
}

@table(name type desc)
RDI_LocalMemberTable:
{
  {kind            RDI_LocalKind           ""}
  {name_string_idx RDI_U32                 ""}
  {type_idx        RDI_U32                 ""}
  {pad             RDI_U32                 ""}
  {location_first  RDI_U32                 ""}
  {location_opl    RDI_U32                 ""}
}

@table(name type desc)
RDI_LocationBlockMemberTable:
{
  {scope_off_first     RDI_U32                }
  {scope_off_opl       RDI_U32                }
  {location_data_off   RDI_U32                }
}

@table(name type desc)
RDI_LocationBytecodeStreamMemberTable:
{
  {kind RDI_LocationKind ""}
  // [... 0] null terminated byte sequence RDI_EvalBytecodeStream
}

@table(name type desc)
RDI_LocationRegPlusU16MemberTable:
{
  {kind             RDI_LocationKind }
  {reg_code         RDI_RegCode }
  {offset           RDI_U16 }
}

@table(name type desc)
RDI_LocationRegMemberTable:
{
  {kind             RDI_LocationKind }
  {reg_code         RDI_RegCode }
}

//- rjf: enums

@enum(RDI_U32) RDI_LinkFlags:
{
  @expand(RDI_LinkFlagTable a) `$(a.name .. =>20) = $(a.value)`
}

@enum(RDI_U32) RDI_LocalKind:
{
  @expand(RDI_LocalKindTable a) `$(a.name .. =>20) = $(a.value)`
}

@enum(RDI_U8) RDI_LocationKind:
{
  @expand(RDI_LocationKindTable a) `$(a.name .. =>20) = $(a.value)`
}

//- rjf: xlists

@xlist RDI_LinkFlags_XList:
{
  @expand(RDI_LinkFlagTable a) `$(a.name != COUNT -> a.name)`;
}

@xlist RDI_LocalKind_XList:
{
  @expand(RDI_LocalKindTable a) `$(a.name != COUNT -> a.name)`;
}

@xlist RDI_LocationKind_XList:
{
  @expand(RDI_LocationKindTable a) `$(a.name != COUNT -> a.name)`;
}

@xlist RDI_GlobalVariable_XList:
{
  @expand(RDI_GlobalVariableMemberTable a) `$(a.type), $(a.name)`
}

@xlist RDI_ThreadVariable_XList:
{
  @expand(RDI_ThreadVariableMemberTable a) `$(type), $(a.name)`
}

@xlist RDI_Procedure_XList:
{
  @expand(RDI_ProcedureMemberTable a) `$(a.type), $(a.name)`
}

@xlist RDI_Scope_XList:
{
  @expand(RDI_ScopeMemberTable a) `$(a.type), $(a.name)`
}

@xlist RDI_InlineSite_XList:
{
  @expand(RDI_InlineSiteMemberTable a) `$(a.type), $(a.name)`
}

@xlist RDI_Local_XList:
{
  @expand(RDI_LocalMemberTable a) `$(a.type), $(a.name)`
}

@xlist RDI_LocationBlock_XList:
{
  @expand(RDI_LocationBlockMemberTable a) `$(a.type), $(a.name)`
}

@xlist RDI_LocationBytecodeStream_XList:
{
  @expand(RDI_LocationBytecodeStreamMemberTable a) `$(a.type), $(a.name)`
}

@xlist RDI_LocationRegPlusU16_XList:
{
  @expand(RDI_LocationRegPlusU16MemberTable a) `$(a.type), $(a.name)`
}

@xlist RDI_LocationReg_XList:
{
  @expand(RDI_LocationRegMemberTable a) `$(a.type), $(a.name)`
}

//- rjf: structs

@struct RDI_GlobalVariable:
{
  @expand(RDI_GlobalVariableMemberTable a) `$(a.type) $(a.name)`
}

@struct RDI_ThreadVariable:
{
  @expand(RDI_ThreadVariableMemberTable a) `$(a.type) $(a.name)`
}

@struct RDI_Procedure:
{
  @expand(RDI_ProcedureMemberTable a) `$(a.type) $(a.name)`
}

@struct RDI_Scope:
{
  @expand(RDI_ScopeMemberTable a) `$(a.type) $(a.name)`
}

@struct RDI_InlineSite:
{
  @expand(RDI_InlineSiteMemberTable a) `$(a.type) $(a.name)`
}

@struct RDI_Local:
{
  @expand(RDI_LocalMemberTable a) `$(a.type) $(a.name)`
}

@struct RDI_LocationBlock:
{
  @expand(RDI_LocationBlockMemberTable a) `$(a.type) $(a.name)`
}

@struct RDI_LocationBytecodeStream:
{
  @expand(RDI_LocationBytecodeStreamMemberTable a) `$(a.type) $(a.name)`
}

@struct RDI_LocationRegPlusU16:
{
  @expand(RDI_LocationRegPlusU16MemberTable a) `$(a.type) $(a.name)`
}

@struct RDI_LocationReg:
{
  @expand(RDI_LocationRegMemberTable a) `$(a.type) $(a.name)`
}

////////////////////////////////
//~ rjf: Evaluation Bytecode Tables

@table(name value num_decodes num_pops num_pushes)
RDI_EvalOpTable:
{
  {Stop        0       0 0 0}
  {Noop        1       0 0 0}
  {Cond        2       1 1 0}
  {Skip        3       2 0 0}
  {MemRead     4       1 1 1}
  {RegRead     5       4 0 1}
  {RegReadDyn  6       0 1 1}
  {FrameOff    7       1 0 1}
  {ModuleOff   8       4 0 1}
  {TLSOff      9       4 0 1}
  {ObjectOff   10      0 0 0}
  {CFA         11      0 0 0}
  {ConstU8     12      1 0 1}
  {ConstU16    13      2 0 1}
  {ConstU32    14      4 0 1}
  {ConstU64    15      8 0 1}
  {ConstU128   16     16 0 1}
  {ConstString 17      1 0 1}
  {Abs         18      1 1 1}
  {Neg         19      1 1 1}
  {Add         20      1 2 1}
  {Sub         21      1 2 1}
  {Mul         22      1 2 1}
  {Div         23      1 2 1}
  {Mod         24      1 2 1}
  {LShift      25      1 2 1}
  {RShift      26      1 2 1}
  {BitAnd      27      1 2 1}
  {BitOr       28      1 2 1}
  {BitXor      29      1 2 1}
  {BitNot      30      1 1 1}
  {LogAnd      31      1 2 1}
  {LogOr       32      1 2 1}
  {LogNot      33      1 1 1}
  {EqEq        34      1 2 1}
  {NtEq        35      1 2 1}
  {LsEq        36      1 2 1}
  {GrEq        37      1 2 1}
  {Less        38      1 2 1}
  {Grtr        39      1 2 1}
  {Trunc       40      1 1 1}
  {TruncSigned 41      1 1 1}
  {Convert     42      2 1 1}
  {Pick        43      1 0 1}
  {Pop         44      0 1 0}
  {Insert      45      1 0 0}
  {ValueRead   46      1 2 1}
  {ByteSwap    47      1 1 1}
  {COUNT       48      0 0 0}
}

// NOTE(rjf): "ck" -> "conversion kind, when converted to type group", used in square matrix form
// e.g. x:0, y:0 means other -> other, x:3, y:1 means uint -> f32, etc.
@table(name value       ck0             ck1         ck2          ck3         ck4)
RDI_EvalTypeGroupTable:
{
  {Other  0              OtherToOther    FromOther   FromOther    FromOther   FromOther   }
  {U      1              ToOther         Noop        Noop         Legal       Legal       }
  {S      2              ToOther         Noop        Noop         Legal       Legal       }
  {F32    3              ToOther         Legal       Legal        Noop        Legal       }
  {F64    4              ToOther         Legal       Legal        Legal       Noop        }
  {COUNT  5              Noop            Noop        Noop         Noop        Noop        }
}

@table(name value error_string)
RDI_EvalConversionKindTable:
{
  {Noop         0 ""                                   }
  {Legal        1 ""                                   }
  {OtherToOther 2 "Cannot convert between these types."}
  {ToOther      3 "Cannot convert to this type."       }
  {FromOther    4 "Cannot convert this type."          }
  {COUNT        5 ""                                   }
}

@enum(RDI_U8) RDI_EvalOp:
{
  @expand(RDI_EvalOpTable a) `$(a.name .. =>20) = $(a.value)`
}

@enum(RDI_U8) RDI_EvalTypeGroup:
{
  @expand(RDI_EvalTypeGroupTable a) `$(a.name .. =>20) = $(a.value)`
}

@enum(RDI_U8) RDI_EvalConversionKind:
{
  @expand(RDI_EvalConversionKindTable a) `$(a.name .. =>20) = $(a.value)`
}

@xlist RDI_EvalOp_XList:
{
  @expand(RDI_EvalOpTable a) `$(a.name != COUNT -> a.name)`;
}

@xlist RDI_EvalTypeGroup_XList:
{
  @expand(RDI_EvalTypeGroupTable a) `$(a.name != COUNT -> a.name)`;
}

@xlist RDI_EvalConversionKind_XList:
{
  @expand(RDI_EvalConversionKindTable a) `$(a.name != COUNT -> a.name)`;
}

@gen(enums)
```
#define RDI_EVAL_CTRLBITS(decodeN,popN,pushN) (((decodeN) << 8) | ((popN) << 4) | ((pushN) << 0))
#define RDI_DECODEN_FROM_CTRLBITS(ctrlbits)   (((ctrlbits) >> 8) & 0xff)
#define RDI_POPN_FROM_CTRLBITS(ctrlbits)      (((ctrlbits) >> 4) & 0xf)
#define RDI_PUSHN_FROM_CTRLBITS(ctrlbits)     (((ctrlbits) >> 0) & 0xf)
#define RDI_EncodeRegReadParam(reg,bytesize,bytepos) ((reg)|((bytesize)<<8)|((bytepos)<<16))
```

@data(RDI_U16) rdi_eval_op_ctrlbits_table:
{
  @expand(RDI_EvalOpTable a) `RDI_EVAL_CTRLBITS($(a.num_decodes), $(a.num_pops), $(a.num_pushes))`;
}

@data(`struct {RDI_EvalConversionKind dst_typegroups[RDI_EvalTypeGroup_COUNT];}`) @c_file
rdi_eval_typegroup_conversion_kind_matrix:
{
  @expand(RDI_EvalTypeGroupTable a) `{{RDI_EvalConversionKind_$(a.ck0), RDI_EvalConversionKind_$(a.ck1), RDI_EvalConversionKind_$(a.ck2), RDI_EvalConversionKind_$(a.ck3), RDI_EvalConversionKind_$(a.ck4)}}`
}

@data(`struct {RDI_U8 *str; RDI_U64 size;}`) @c_file
rdi_eval_conversion_kind_message_string_table:
{
  @expand(RDI_EvalTypeGroupTable a) `{(RDI_U8 *)"$(a.error_string)", sizeof("$(a.error_string)")}`
}

////////////////////////////////
//~ rjf: Name Map Tables

@table(name value)
RDI_NameMapKindTable:
{
  {NULL               0}
  {GlobalVariables    1}
  {ThreadVariables    2}
  {Procedures         3}
  {Types              4}
  {LinkNameProcedures 5}
  {NormalSourcePaths  6}
  {COUNT              7}
}

@table(name type desc)
RDI_NameMapMemberTable:
{
  {bucket_base_idx    RDI_U32                        ""}
  {node_base_idx      RDI_U32                        ""}
  {bucket_count       RDI_U32                        ""}
  {node_count         RDI_U32                        ""}
}

@table(name type desc)
RDI_NameMapBucketMemberTable:
{
  {first_node    RDI_U32   ""}
  {node_count    RDI_U32   ""}
}

@table(name type desc)
RDI_NameMapNodeMemberTable:
{
  {string_idx                    RDI_U32               ""}
  {match_count                   RDI_U32               ""}
  // NOTE: if (match_count == 1) then this is the index of the matching item
  //       if (match_count > 1)  then this is the first for an index run of all the matches
  {match_idx_or_idx_run_first    RDI_U32               ""}
}

@enum(RDI_U32) RDI_NameMapKind:
{
  @expand(RDI_NameMapKindTable a) `$(a.name .. =>20) = $(a.value)`
}

@xlist RDI_NameMapKind_XList:
{
  @expand(RDI_NameMapKindTable a) `$(a.name != COUNT -> a.name)`;
}

@xlist RDI_NameMap_XList:
{
  @expand(RDI_NameMapMemberTable a) `$(a.type), $(a.val)`
}

@xlist RDI_NameMapBucket_XList:
{
  @expand(RDI_NameMapBucketMemberTable a) `$(a.type), $(a.val)`
}

@xlist RDI_NameMapNode_XList:
{
  @expand(RDI_NameMapNodeMemberTable a) `$(a.type), $(a.val)`
}

@struct RDI_NameMap:
{
  @expand(RDI_NameMapMemberTable a) `$(a.type) $(a.val)`
}

@struct RDI_NameMapBucket:
{
  @expand(RDI_NameMapBucketMemberTable a) `$(a.type) $(a.val)`
}

@struct RDI_NameMapNode:
{
  @expand(RDI_NameMapNodeMemberTable a) `$(a.type) $(a.val)`
}

////////////////////////////////
//~ rjf: Functions

@gen(functions)
```
RDI_PROC RDI_U64 rdi_hash(RDI_U8 *ptr, RDI_U64 size);
RDI_PROC RDI_U32 rdi_size_from_basic_type_kind(RDI_TypeKind kind);
RDI_PROC RDI_U32 rdi_addr_size_from_arch(RDI_Arch arch);
RDI_PROC RDI_EvalConversionKind rdi_eval_conversion_kind_from_typegroups(RDI_EvalTypeGroup in, RDI_EvalTypeGroup out);
RDI_PROC RDI_S32 rdi_eval_op_typegroup_are_compatible(RDI_EvalOp op, RDI_EvalTypeGroup group);
RDI_PROC RDI_U8 *rdi_explanation_string_from_eval_conversion_kind(RDI_EvalConversionKind kind, RDI_U64 *size_out);
```

@gen(functions) @c_file
```
RDI_PROC RDI_U64
rdi_hash(RDI_U8 *ptr, RDI_U64 size)
{
  RDI_U64 result = 5381;
  RDI_U8 *opl = ptr + size;
  for(;ptr < opl; ptr += 1)
  {
    result = ((result << 5) + result) + *ptr;
  }
  return result;
}
```

@gen(functions) @c_file
{
  `RDI_PROC RDI_U32`;
  `rdi_size_from_basic_type_kind(RDI_TypeKind kind)`;
  `{`;
    `RDI_U32 result = 0;`;
    `switch(kind)`;
    `{`;
      `default:{}break;`;
      @expand(RDI_TypeKindTable a) `$(a.size != 0 -> "    case RDI_TypeKind_" .. a.name .. ":{result = " .. a.size .. ";}break;")`,
      `}`;
    `return result;`;
    `}`;
  ``;
}

@gen(functions) @c_file
{
  `RDI_PROC RDI_U32`;
  `rdi_addr_size_from_arch(RDI_Arch arch)`;
  `{`;
    `RDI_U32 result = 0;`;
    `switch(arch)`;
    `{`;
      `default:{}break;`;
      @expand(RDI_ArchTable a) `$(a.addr_size != 0 -> "    case RDI_Arch_" .. a.name .. ":{result = " .. a.addr_size .. ";}break;")`;
      `}`;
    `return result;`;
    `}`;
  ``;
}

@gen(functions) @c_file
```
RDI_PROC RDI_EvalConversionKind
rdi_eval_conversion_kind_from_typegroups(RDI_EvalTypeGroup in, RDI_EvalTypeGroup out)
{
  RDI_EvalConversionKind k = rdi_eval_typegroup_conversion_kind_matrix[in].dst_typegroups[out];
  return k;
}
```

@gen(functions) @c_file
```
RDI_PROC RDI_S32
rdi_eval_op_typegroup_are_compatible(RDI_EvalOp op, RDI_EvalTypeGroup group)
{
  RDI_S32 result = 0;
  switch(op)
  {
    case RDI_EvalOp_Neg: case RDI_EvalOp_Add: case RDI_EvalOp_Sub:
    case RDI_EvalOp_Mul: case RDI_EvalOp_Div:
    case RDI_EvalOp_EqEq:case RDI_EvalOp_NtEq:
    case RDI_EvalOp_LsEq:case RDI_EvalOp_GrEq:
    case RDI_EvalOp_Less:case RDI_EvalOp_Grtr:
    {
      if(group != RDI_EvalTypeGroup_Other)
      {
        result = 1;
      }
    }break;
    case RDI_EvalOp_Mod:case RDI_EvalOp_LShift:case RDI_EvalOp_RShift:
    case RDI_EvalOp_BitNot:case RDI_EvalOp_BitAnd:case RDI_EvalOp_BitXor:
    case RDI_EvalOp_BitOr:case RDI_EvalOp_LogNot:case RDI_EvalOp_LogAnd:
    case RDI_EvalOp_LogOr: 
    {
      if(group == RDI_EvalTypeGroup_S || group == RDI_EvalTypeGroup_U)
      {
        result = 1;
      }
    }break;
  }
  return result;
}
```

@gen(functions) @c_file
```
RDI_PROC RDI_U8 *
rdi_explanation_string_from_eval_conversion_kind(RDI_EvalConversionKind kind, RDI_U64 *size_out)
{
  *size_out = rdi_eval_conversion_kind_message_string_table[kind].size;
  return rdi_eval_conversion_kind_message_string_table[kind].str;
}
```
