Add -doc-format command for the new .odin-doc file format (to be used to generate documentation tools)

This commit is contained in:
gingerBill
2021-04-18 18:33:15 +01:00
parent 8827818b1d
commit 2f1c896290
9 changed files with 1551 additions and 19 deletions
+251
View File
@@ -0,0 +1,251 @@
package odin_doc_format
import "core:mem"
Array :: struct($T: typeid) {
offset: u32,
length: u32,
}
String :: distinct Array(byte);
Version_Type_Major :: 0;
Version_Type_Minor :: 1;
Version_Type_Patch :: 0;
Version_Type :: struct {
major, minor, patch: u8,
_: u8,
};
Version_Type_Default :: Version_Type{
major=Version_Type_Major,
minor=Version_Type_Minor,
patch=Version_Type_Patch,
};
Magic_String :: "odindoc\x00";
Header_Base :: struct {
magic: [8]byte,
_: u32,
version: Version_Type,
total_size: u32,
header_size: u32,
hash: u32,
}
Header :: struct {
using base: Header_Base,
// NOTE: These arrays reserve the zero element as a sentinel value
files: Array(File),
pkgs: Array(Pkg),
entities: Array(Entity),
types: Array(Type),
}
File_Index :: distinct u32;
Pkg_Index :: distinct u32;
Entity_Index :: distinct u32;
Type_Index :: distinct u32;
Position :: struct {
file: File_Index,
line: u32,
column: u32,
offset: u32,
};
File :: struct {
pkg: Pkg_Index,
name: String,
}
Pkg :: struct {
fullpath: String,
name: String,
docs: String,
files: Array(File_Index),
entities: Array(Entity_Index),
}
Entity_Kind :: enum u32 {
Invalid = 0,
Constant = 1,
Variable = 2,
Type_Name = 3,
Procedure = 4,
Proc_Group = 5,
Import_Name = 6,
Library_Name = 7,
}
Entity_Flag :: enum u32 {
Foreign = 0,
Export = 1,
Param_Using = 2,
Param_Const = 3,
Param_Auto_Cast = 4,
Param_Ellipsis = 5,
Param_CVararg = 6,
Param_No_Alias = 7,
Type_Alias = 8,
Var_Thread_Local = 9,
}
Entity_Flags :: distinct bit_set[Entity_Flag; u32];
Entity :: struct {
kind: Entity_Kind,
flags: Entity_Flags,
pos: Position,
name: String,
type: Type_Index,
init_string: String,
_: u32,
comment: String,
docs: String,
foreign_library: Entity_Index,
link_name: String,
attributes: Array(Attribute),
grouped_entities: Array(Entity_Index), // Procedure Groups
where_clauses: Array(String), // Procedures
}
Attribute :: struct {
name: String,
value: String,
}
Type_Kind :: enum u32 {
Invalid = 0,
Basic = 1,
Named = 2,
Generic = 3,
Pointer = 4,
Array = 5,
Enumerated_Array = 6,
Slice = 7,
Dynamic_Array = 8,
Map = 9,
Struct = 10,
Union = 11,
Enum = 12,
Tuple = 13,
Proc = 14,
Bit_Set = 15,
Simd_Vector = 16,
SOA_Struct_Fixed = 17,
SOA_Struct_Slice = 18,
SOA_Struct_Dynamic = 19,
Relative_Pointer = 20,
Relative_Slice = 21,
}
Type_Elems_Cap :: 4;
Type :: struct {
kind: Type_Kind,
flags: u32, // Type_Kind specific
name: String,
custom_align: String,
// Used by some types
elem_count_len: u32,
elem_counts: [Type_Elems_Cap]u64,
// Each of these is esed by some types, not all
types: Array(Type_Index),
entities: Array(Entity_Index),
polymorphic_params: Type_Index, // Struct, Union
where_clauses: Array(String), // Struct, Union
}
Type_Flags_Basic :: distinct bit_set[Type_Flag_Basic; u32];
Type_Flag_Basic :: enum u32 {
Untyped = 1,
}
Type_Flags_Struct :: distinct bit_set[Type_Flag_Struct; u32];
Type_Flag_Struct :: enum u32 {
Polymorphic = 0,
Packed = 1,
Raw_Union = 2,
}
Type_Flags_Union :: distinct bit_set[Type_Flag_Union; u32];
Type_Flag_Union :: enum u32 {
Polymorphic = 0,
No_Nil = 1,
Maybe = 2,
}
Type_Flags_Proc :: distinct bit_set[Type_Flag_Proc; u32];
Type_Flag_Proc :: enum u32 {
Polymorphic = 0,
Diverging = 1,
Optional_Ok = 2,
Variadic = 3,
C_Vararg = 4,
}
Type_Flags_BitSet :: distinct bit_set[Type_Flag_BitSet; u32];
Type_Flag_BitSet :: enum u32 {
Range = 1,
Op_Lt = 2,
Op_Lt_Eq = 3,
Underlying_Type = 4,
}
Type_Flags_SimdVector :: distinct bit_set[Type_Flag_SimdVector; u32];
Type_Flag_SimdVector :: enum u32 {
x86_mmx = 1,
}
from_array :: proc(base: ^Header_Base, a: $A/Array($T)) -> []T {
s: mem.Raw_Slice;
s.data = rawptr(uintptr(base) + uintptr(a.offset));
s.len = int(a.length);
return transmute([]T)s;
}
from_string :: proc(base: ^Header_Base, s: String) -> string {
return string(from_array(base, s));
}
Reader_Error :: enum {
None,
Header_Too_Small,
Invalid_Magic,
Data_Too_Small,
Invalid_Version,
}
read_from_bytes :: proc(data: []byte) -> (h: ^Header, err: Reader_Error) {
if len(data) < size_of(Header_Base) {
err = .Header_Too_Small;
return;
}
header_base := (^Header_Base)(raw_data(data));
if header_base.magic != Magic_String {
err = .Invalid_Magic;
return;
}
if len(data) < int(header_base.total_size) {
err = .Data_Too_Small;
return;
}
if header_base.version != Version_Type_Default {
err = .Invalid_Version;
return;
}
h = (^Header)(header_base);
return;
}