doc_format.odin 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  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 :: 3
  10. Version_Type_Patch :: 1
  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, // padding
  24. version: Version_Type,
  25. total_size: u32le, // in bytes
  26. header_size: u32le, // in bytes
  27. hash: u32le, // hash of the data after the header (header_size)
  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. entries: Array(Scope_Entry),
  64. }
  65. Scope_Entry :: struct {
  66. name: String,
  67. entity: Entity_Index,
  68. }
  69. Entity_Kind :: enum u32le {
  70. Invalid = 0,
  71. Constant = 1,
  72. Variable = 2,
  73. Type_Name = 3,
  74. Procedure = 4,
  75. Proc_Group = 5,
  76. Import_Name = 6,
  77. Library_Name = 7,
  78. Builtin = 8,
  79. }
  80. Entity_Flag :: enum u32le {
  81. Foreign = 0,
  82. Export = 1,
  83. Param_Using = 2, // using
  84. Param_Const = 3, // #const
  85. Param_Auto_Cast = 4, // auto_cast
  86. Param_Ellipsis = 5, // Variadic parameter
  87. Param_CVararg = 6, // #c_vararg
  88. Param_No_Alias = 7, // #no_alias
  89. Param_Any_Int = 8, // #any_int
  90. Param_By_Ptr = 9, // #by_ptr
  91. Param_No_Broadcast = 10, // #no_broadcast
  92. Bit_Field_Field = 19,
  93. Type_Alias = 20,
  94. Builtin_Pkg_Builtin = 30,
  95. Builtin_Pkg_Intrinsics = 31,
  96. Var_Thread_Local = 40,
  97. Var_Static = 41,
  98. Private = 50,
  99. }
  100. Entity_Flags :: distinct bit_set[Entity_Flag; u64le]
  101. Entity :: struct {
  102. kind: Entity_Kind,
  103. _: u32le, // reserved
  104. flags: Entity_Flags,
  105. pos: Position,
  106. name: String,
  107. type: Type_Index,
  108. init_string: String,
  109. _: u32le, // reserved for init
  110. comment: String,
  111. docs: String,
  112. // May be used by (Struct fields and procedure fields):
  113. // .Variable
  114. // .Constant
  115. // This is equal to the negative of the "bit size" it this is a `bit_field`s field
  116. field_group_index: i32le,
  117. // May used by:
  118. // .Variable
  119. // .Procedure
  120. foreign_library: Entity_Index,
  121. // May used by:
  122. // .Variable
  123. // .Procedure
  124. link_name: String,
  125. attributes: Array(Attribute),
  126. // Used by: .Proc_Group
  127. grouped_entities: Array(Entity_Index),
  128. // May used by: .Procedure
  129. where_clauses: Array(String),
  130. }
  131. Attribute :: struct {
  132. name: String,
  133. value: String,
  134. }
  135. Type_Kind :: enum u32le {
  136. Invalid = 0,
  137. Basic = 1,
  138. Named = 2,
  139. Generic = 3,
  140. Pointer = 4,
  141. Array = 5,
  142. Enumerated_Array = 6,
  143. Slice = 7,
  144. Dynamic_Array = 8,
  145. Map = 9,
  146. Struct = 10,
  147. Union = 11,
  148. Enum = 12,
  149. Tuple = 13,
  150. Proc = 14,
  151. Bit_Set = 15,
  152. Simd_Vector = 16,
  153. SOA_Struct_Fixed = 17,
  154. SOA_Struct_Slice = 18,
  155. SOA_Struct_Dynamic = 19,
  156. Relative_Pointer = 20,
  157. Relative_Multi_Pointer = 21,
  158. Multi_Pointer = 22,
  159. Matrix = 23,
  160. Soa_Pointer = 24,
  161. Bit_Field = 25,
  162. }
  163. Type_Elems_Cap :: 4
  164. Type :: struct {
  165. kind: Type_Kind,
  166. // Type_Kind specific used by some types
  167. // Underlying flag types:
  168. // .Basic - Type_Flags_Basic
  169. // .Struct - Type_Flags_Struct
  170. // .Union - Type_Flags_Union
  171. // .Proc - Type_Flags_Proc
  172. // .Bit_Set - Type_Flags_Bit_Set
  173. flags: u32le,
  174. // Used by:
  175. // .Basic
  176. // .Named
  177. // .Generic
  178. name: String,
  179. // Used By: .Struct, .Union
  180. custom_align: String,
  181. // Used by:
  182. // .Array - 1 count: 0=len
  183. // .Enumerated_Array - 1 count: 0=len
  184. // .SOA_Struct_Fixed - 1 count: 0=len
  185. // .Bit_Set - 2 count: 0=lower, 1=upper
  186. // .Simd_Vector - 1 count: 0=len
  187. // .Matrix - 2 count: 0=row_count, 1=column_count
  188. elem_count_len: u32le,
  189. elem_counts: [Type_Elems_Cap]i64le,
  190. // Used by: .Procedures
  191. // blank implies the "odin" calling convention
  192. calling_convention: String,
  193. // Used by:
  194. // .Named - 1 type: 0=base type
  195. // .Generic - <1 type: 0=specialization
  196. // .Pointer - 1 type: 0=element
  197. // .Array - 1 type: 0=element
  198. // .Enumerated_Array - 2 types: 0=index and 1=element
  199. // .Slice - 1 type: 0=element
  200. // .Dynamic_Array - 1 type: 0=element
  201. // .Map - 2 types: 0=key, 1=value
  202. // .SOA_Struct_Fixed - 1 type: underlying SOA struct element
  203. // .SOA_Struct_Slice - 1 type: underlying SOA struct element
  204. // .SOA_Struct_Dynamic - 1 type: underlying SOA struct element
  205. // .Union - 0+ types: variants
  206. // .Enum - <1 type: 0=base type
  207. // .Proc - 2 types: 0=parameters, 1=results
  208. // .Bit_Set - <=2 types: 0=element type, 1=underlying type (Underlying_Type flag will be set)
  209. // .Simd_Vector - 1 type: 0=element
  210. // .Relative_Pointer - 2 types: 0=pointer type, 1=base integer
  211. // .Multi_Pointer - 1 type: 0=element
  212. // .Matrix - 1 type: 0=element
  213. // .Soa_Pointer - 1 type: 0=element
  214. // .Bit_Field - 1 type: 0=backing type
  215. types: Array(Type_Index),
  216. // Used by:
  217. // .Named - 1 field for the definition
  218. // .Struct - fields
  219. // .Enum - fields
  220. // .Tuple - parameters (procedures only)
  221. entities: Array(Entity_Index),
  222. // Used By: .Struct, .Union
  223. polymorphic_params: Type_Index,
  224. // Used By: .Struct, .Union
  225. where_clauses: Array(String),
  226. // Used By: .Struct
  227. tags: Array(String),
  228. }
  229. Type_Flags_Basic :: distinct bit_set[Type_Flag_Basic; u32le]
  230. Type_Flag_Basic :: enum u32le {
  231. Untyped = 1,
  232. }
  233. Type_Flags_Struct :: distinct bit_set[Type_Flag_Struct; u32le]
  234. Type_Flag_Struct :: enum u32le {
  235. Polymorphic = 0,
  236. Packed = 1,
  237. Raw_Union = 2,
  238. }
  239. Type_Flags_Union :: distinct bit_set[Type_Flag_Union; u32le]
  240. Type_Flag_Union :: enum u32le {
  241. Polymorphic = 0,
  242. No_Nil = 1,
  243. Maybe = 2,
  244. }
  245. Type_Flags_Proc :: distinct bit_set[Type_Flag_Proc; u32le]
  246. Type_Flag_Proc :: enum u32le {
  247. Polymorphic = 0,
  248. Diverging = 1,
  249. Optional_Ok = 2,
  250. Variadic = 3,
  251. C_Vararg = 4,
  252. }
  253. Type_Flags_Bit_Set :: distinct bit_set[Type_Flag_Bit_Set; u32le]
  254. Type_Flag_Bit_Set :: enum u32le {
  255. Range = 1,
  256. Op_Lt = 2,
  257. Op_Lt_Eq = 3,
  258. Underlying_Type = 4,
  259. }
  260. from_array :: proc(base: ^Header_Base, a: $A/Array($T)) -> []T {
  261. s: mem.Raw_Slice
  262. s.data = rawptr(uintptr(base) + uintptr(a.offset))
  263. s.len = int(a.length)
  264. return transmute([]T)s
  265. }
  266. from_string :: proc(base: ^Header_Base, s: String) -> string {
  267. return string(from_array(base, s))
  268. }
  269. Reader_Error :: enum {
  270. None,
  271. Header_Too_Small,
  272. Invalid_Magic,
  273. Data_Too_Small,
  274. Invalid_Version,
  275. }
  276. read_from_bytes :: proc(data: []byte) -> (h: ^Header, err: Reader_Error) {
  277. if len(data) < size_of(Header_Base) {
  278. err = .Header_Too_Small
  279. return
  280. }
  281. header_base := (^Header_Base)(raw_data(data))
  282. if header_base.magic != Magic_String {
  283. err = .Invalid_Magic
  284. return
  285. }
  286. if len(data) < int(header_base.total_size) {
  287. err = .Data_Too_Small
  288. return
  289. }
  290. if header_base.version != Version_Type_Default {
  291. err = .Invalid_Version
  292. return
  293. }
  294. h = (^Header)(header_base)
  295. return
  296. }