doc_format.odin 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. package odin_doc_format
  2. import "core:mem"
  3. Array :: struct($T: typeid) {
  4. offset: u32le,
  5. length: u32le,
  6. }
  7. String :: distinct Array(byte);
  8. Version_Type_Major :: 0;
  9. Version_Type_Minor :: 1;
  10. Version_Type_Patch :: 0;
  11. Version_Type :: struct {
  12. major, minor, patch: u8,
  13. _: u8,
  14. };
  15. Version_Type_Default :: Version_Type{
  16. major=Version_Type_Major,
  17. minor=Version_Type_Minor,
  18. patch=Version_Type_Patch,
  19. };
  20. Magic_String :: "odindoc\x00";
  21. Header_Base :: struct {
  22. magic: [8]byte,
  23. _: u32le,
  24. version: Version_Type,
  25. total_size: u32le,
  26. header_size: u32le,
  27. hash: u32le,
  28. }
  29. Header :: struct {
  30. using base: Header_Base,
  31. // NOTE: These arrays reserve the zero element as a sentinel value
  32. files: Array(File),
  33. pkgs: Array(Pkg),
  34. entities: Array(Entity),
  35. types: Array(Type),
  36. }
  37. File_Index :: distinct u32le;
  38. Pkg_Index :: distinct u32le;
  39. Entity_Index :: distinct u32le;
  40. Type_Index :: distinct u32le;
  41. Position :: struct {
  42. file: File_Index,
  43. line: u32le,
  44. column: u32le,
  45. offset: u32le,
  46. };
  47. File :: struct {
  48. pkg: Pkg_Index,
  49. name: String,
  50. }
  51. Pkg_Flag :: enum u32le {
  52. Builtin = 0,
  53. Runtime = 1,
  54. Init = 2,
  55. }
  56. Pkg_Flags :: distinct bit_set[Pkg_Flag; u32le];
  57. Pkg :: struct {
  58. fullpath: String,
  59. name: String,
  60. flags: Pkg_Flags,
  61. docs: String,
  62. files: Array(File_Index),
  63. entities: Array(Entity_Index),
  64. }
  65. Entity_Kind :: enum u32le {
  66. Invalid = 0,
  67. Constant = 1,
  68. Variable = 2,
  69. Type_Name = 3,
  70. Procedure = 4,
  71. Proc_Group = 5,
  72. Import_Name = 6,
  73. Library_Name = 7,
  74. }
  75. Entity_Flag :: enum u32le {
  76. Foreign = 0,
  77. Export = 1,
  78. Param_Using = 2,
  79. Param_Const = 3,
  80. Param_Auto_Cast = 4,
  81. Param_Ellipsis = 5,
  82. Param_CVararg = 6,
  83. Param_No_Alias = 7,
  84. Type_Alias = 8,
  85. Var_Thread_Local = 9,
  86. }
  87. Entity_Flags :: distinct bit_set[Entity_Flag; u32le];
  88. Entity :: struct {
  89. kind: Entity_Kind,
  90. flags: Entity_Flags,
  91. pos: Position,
  92. name: String,
  93. type: Type_Index,
  94. init_string: String,
  95. _: u32le,
  96. comment: String,
  97. docs: String,
  98. foreign_library: Entity_Index,
  99. link_name: String,
  100. attributes: Array(Attribute),
  101. grouped_entities: Array(Entity_Index), // Procedure Groups
  102. where_clauses: Array(String), // Procedures
  103. }
  104. Attribute :: struct {
  105. name: String,
  106. value: String,
  107. }
  108. Type_Kind :: enum u32le {
  109. Invalid = 0,
  110. Basic = 1,
  111. Named = 2,
  112. Generic = 3,
  113. Pointer = 4,
  114. Array = 5,
  115. Enumerated_Array = 6,
  116. Slice = 7,
  117. Dynamic_Array = 8,
  118. Map = 9,
  119. Struct = 10,
  120. Union = 11,
  121. Enum = 12,
  122. Tuple = 13,
  123. Proc = 14,
  124. Bit_Set = 15,
  125. Simd_Vector = 16,
  126. SOA_Struct_Fixed = 17,
  127. SOA_Struct_Slice = 18,
  128. SOA_Struct_Dynamic = 19,
  129. Relative_Pointer = 20,
  130. Relative_Slice = 21,
  131. }
  132. Type_Elems_Cap :: 4;
  133. Type :: struct {
  134. kind: Type_Kind,
  135. flags: u32le, // Type_Kind specific
  136. name: String,
  137. custom_align: String,
  138. // Used by some types
  139. elem_count_len: u32le,
  140. elem_counts: [Type_Elems_Cap]i64le,
  141. // Each of these is esed by some types, not all
  142. calling_convention: String, // Procedures
  143. types: Array(Type_Index),
  144. entities: Array(Entity_Index),
  145. polymorphic_params: Type_Index, // Struct, Union
  146. where_clauses: Array(String), // Struct, Union
  147. }
  148. Type_Flags_Basic :: distinct bit_set[Type_Flag_Basic; u32le];
  149. Type_Flag_Basic :: enum u32le {
  150. Untyped = 1,
  151. }
  152. Type_Flags_Struct :: distinct bit_set[Type_Flag_Struct; u32le];
  153. Type_Flag_Struct :: enum u32le {
  154. Polymorphic = 0,
  155. Packed = 1,
  156. Raw_Union = 2,
  157. }
  158. Type_Flags_Union :: distinct bit_set[Type_Flag_Union; u32le];
  159. Type_Flag_Union :: enum u32le {
  160. Polymorphic = 0,
  161. No_Nil = 1,
  162. Maybe = 2,
  163. }
  164. Type_Flags_Proc :: distinct bit_set[Type_Flag_Proc; u32le];
  165. Type_Flag_Proc :: enum u32le {
  166. Polymorphic = 0,
  167. Diverging = 1,
  168. Optional_Ok = 2,
  169. Variadic = 3,
  170. C_Vararg = 4,
  171. }
  172. Type_Flags_Bit_Set :: distinct bit_set[Type_Flag_Bit_Set; u32le];
  173. Type_Flag_Bit_Set :: enum u32le {
  174. Range = 1,
  175. Op_Lt = 2,
  176. Op_Lt_Eq = 3,
  177. Underlying_Type = 4,
  178. }
  179. from_array :: proc(base: ^Header_Base, a: $A/Array($T)) -> []T {
  180. s: mem.Raw_Slice;
  181. s.data = rawptr(uintptr(base) + uintptr(a.offset));
  182. s.len = int(a.length);
  183. return transmute([]T)s;
  184. }
  185. from_string :: proc(base: ^Header_Base, s: String) -> string {
  186. return string(from_array(base, s));
  187. }
  188. Reader_Error :: enum {
  189. None,
  190. Header_Too_Small,
  191. Invalid_Magic,
  192. Data_Too_Small,
  193. Invalid_Version,
  194. }
  195. read_from_bytes :: proc(data: []byte) -> (h: ^Header, err: Reader_Error) {
  196. if len(data) < size_of(Header_Base) {
  197. err = .Header_Too_Small;
  198. return;
  199. }
  200. header_base := (^Header_Base)(raw_data(data));
  201. if header_base.magic != Magic_String {
  202. err = .Invalid_Magic;
  203. return;
  204. }
  205. if len(data) < int(header_base.total_size) {
  206. err = .Data_Too_Small;
  207. return;
  208. }
  209. if header_base.version != Version_Type_Default {
  210. err = .Invalid_Version;
  211. return;
  212. }
  213. h = (^Header)(header_base);
  214. return;
  215. }