Separating out different parts of the meta system.
This commit is contained in:
parent
e8759c931a
commit
d1353e52fa
File diff suppressed because it is too large
Load Diff
1726
meta/gs_meta.cpp
1726
meta/gs_meta.cpp
File diff suppressed because it is too large
Load Diff
|
@ -1,98 +1,68 @@
|
||||||
#define MAX_ERROR_LENGTH 256
|
|
||||||
|
|
||||||
struct error
|
struct error_buffer
|
||||||
{
|
{
|
||||||
char Backbuffer[MAX_ERROR_LENGTH];
|
char* Backbuffer;
|
||||||
string Buffer;
|
string* Contents;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct error_list_buffer
|
#define ERROR_MAX_LENGTH 256
|
||||||
|
#define ERROR_BUFFER_SIZE 256
|
||||||
|
struct errors
|
||||||
{
|
{
|
||||||
error* List;
|
error_buffer* Buffers;
|
||||||
s32 Used;
|
u32 BuffersCount;
|
||||||
s32 Max;
|
u32 Used;
|
||||||
error_list_buffer* Next;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct error_list
|
internal void
|
||||||
|
PushFError (errors* Errors, char* Format, ...)
|
||||||
{
|
{
|
||||||
error_list_buffer* Head;
|
if (Errors->Used >= (Errors->BuffersCount * ERROR_BUFFER_SIZE))
|
||||||
s32 TotalUsed;
|
|
||||||
s32 TotalMax;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define ERROR_LIST_GROW_SIZE 32
|
|
||||||
|
|
||||||
internal void
|
|
||||||
GrowErrorList (error_list* Errors)
|
|
||||||
{
|
|
||||||
Assert(Errors);
|
|
||||||
|
|
||||||
s32 ExtensionSize = sizeof(error_list_buffer) + (sizeof(error) * ERROR_LIST_GROW_SIZE);
|
|
||||||
u8* ExtensionMemory = (u8*)malloc(ExtensionSize);
|
|
||||||
|
|
||||||
error_list_buffer* Extension = (error_list_buffer*)ExtensionMemory;
|
|
||||||
Extension->Used = 0;
|
|
||||||
Extension->Max = ERROR_LIST_GROW_SIZE;
|
|
||||||
Extension->List = (error*)(ExtensionMemory + sizeof(error_list_buffer));
|
|
||||||
|
|
||||||
Extension->Next = Errors->Head;
|
|
||||||
Errors->Head = Extension;
|
|
||||||
|
|
||||||
Errors->TotalMax += ERROR_LIST_GROW_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define ErrorAssert(condition, list, format, ...) \
|
|
||||||
if (!(condition)) { LogError_((list), __FILE__, __LINE__, (format), __VA_ARGS__); }
|
|
||||||
|
|
||||||
#define LogError(list, format, ...) LogError_((list), __FILE__, __LINE__, (format), __VA_ARGS__)
|
|
||||||
|
|
||||||
internal void
|
|
||||||
LogError_ (error_list* Errors, char* File, s32 Line, char* Format, ...)
|
|
||||||
{
|
|
||||||
if (Errors->TotalUsed >= Errors->TotalMax)
|
|
||||||
{
|
{
|
||||||
GrowErrorList(Errors);
|
Errors->BuffersCount += 1;
|
||||||
|
Errors->Buffers = (error_buffer*)realloc(Errors->Buffers, sizeof(error_buffer*) * Errors->BuffersCount);
|
||||||
|
|
||||||
|
error_buffer* NewBuffer = Errors->Buffers + (Errors->BuffersCount - 1);
|
||||||
|
NewBuffer->Backbuffer = (char*)malloc(sizeof(char) * ERROR_MAX_LENGTH * ERROR_BUFFER_SIZE);
|
||||||
|
NewBuffer->Contents = (string*)malloc(sizeof(string) * ERROR_BUFFER_SIZE);
|
||||||
|
|
||||||
|
for (u32 i = 0; i < ERROR_BUFFER_SIZE; i++)
|
||||||
|
{
|
||||||
|
NewBuffer->Contents[i].Memory = NewBuffer->Backbuffer + (i * ERROR_MAX_LENGTH);
|
||||||
|
NewBuffer->Contents[i].Max = ERROR_MAX_LENGTH;
|
||||||
|
NewBuffer->Contents[i].Length = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
error* Error = (Errors->Head->List + Errors->Head->Used++);
|
u32 NewErrorIndex = Errors->Used++;
|
||||||
Errors->TotalUsed++;
|
u32 BufferIndex = NewErrorIndex / ERROR_BUFFER_SIZE;
|
||||||
|
u32 IndexInBuffer = NewErrorIndex % ERROR_BUFFER_SIZE;
|
||||||
InitializeEmptyString(&Error->Buffer, Error->Backbuffer, MAX_ERROR_LENGTH);
|
string* NewError = Errors->Buffers[BufferIndex].Contents + IndexInBuffer;
|
||||||
|
|
||||||
va_list Args;
|
va_list Args;
|
||||||
va_start(Args, Format);
|
va_start(Args, Format);
|
||||||
|
NewError->Length = PrintFArgsList(NewError->Memory, NewError->Max, Format, Args);
|
||||||
PrintF(&Error->Buffer, "%s(%d): ", File, Line);
|
|
||||||
Error->Buffer.Length += PrintFArgsList(Error->Buffer.Memory + Error->Buffer.Length,
|
|
||||||
Error->Buffer.Max - Error->Buffer.Length,
|
|
||||||
Format, Args);
|
|
||||||
|
|
||||||
va_end(Args);
|
va_end(Args);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal string*
|
||||||
PrintErrorListBuffer (error_list_buffer* Buffer)
|
TakeError (errors* Errors)
|
||||||
{
|
{
|
||||||
if (Buffer->Next)
|
u32 NewErrorIndex = Errors->Used++;
|
||||||
{
|
u32 BufferIndex = NewErrorIndex / ERROR_BUFFER_SIZE;
|
||||||
PrintErrorListBuffer(Buffer->Next);
|
u32 IndexInBuffer = NewErrorIndex % ERROR_BUFFER_SIZE;
|
||||||
}
|
string* NewError = Errors->Buffers[BufferIndex].Contents + IndexInBuffer;
|
||||||
|
return NewError;
|
||||||
for (s32 i = 0; i < Buffer->Used; i++)
|
|
||||||
{
|
|
||||||
error* Error = Buffer->List + i;
|
|
||||||
NullTerminate(&Error->Buffer);
|
|
||||||
printf(Error->Backbuffer);
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
PrintErrorList (error_list Errors)
|
PrintAllErrors (errors Errors)
|
||||||
{
|
{
|
||||||
if (Errors.Head)
|
for (u32 i = 0; i < Errors.Used; i++)
|
||||||
{
|
{
|
||||||
PrintErrorListBuffer(Errors.Head);
|
u32 BufferIndex = i / ERROR_BUFFER_SIZE;
|
||||||
|
u32 IndexInBuffer = i % ERROR_BUFFER_SIZE;
|
||||||
|
string Error = Errors.Buffers[BufferIndex].Contents[IndexInBuffer];
|
||||||
|
printf("%.*s\n", StringExpand(Error));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,168 @@
|
||||||
|
//
|
||||||
|
// File: gs_meta_typeinfo_generator.h
|
||||||
|
// Author: Peter Slattery
|
||||||
|
// Creation Date: 2020-01-19
|
||||||
|
//
|
||||||
|
#ifndef GS_META_TYPEINFO_GENERATOR_H
|
||||||
|
|
||||||
|
#include <gs_language.h>
|
||||||
|
#include <gs_string.h>
|
||||||
|
#include <gs_string_builder.h>
|
||||||
|
|
||||||
|
struct typeinfo_generator
|
||||||
|
{
|
||||||
|
string_builder TypeList;
|
||||||
|
string_builder StructMembers;
|
||||||
|
string_builder TypeDefinitions;
|
||||||
|
|
||||||
|
u32 GeneratedInfoTypesCount;
|
||||||
|
u32 TypesMax;
|
||||||
|
b8* TypesGeneratedMask;
|
||||||
|
};
|
||||||
|
|
||||||
|
internal typeinfo_generator
|
||||||
|
InitTypeInfoGenerator(type_table TypeTable)
|
||||||
|
{
|
||||||
|
typeinfo_generator Result = {};
|
||||||
|
|
||||||
|
Result.TypesMax = TypeTable.Types.Used;
|
||||||
|
Result.TypesGeneratedMask = (b8*)malloc(sizeof(b8) * Result.TypesMax);
|
||||||
|
GSZeroMemory((u8*)Result.TypesGeneratedMask, Result.TypesMax);
|
||||||
|
|
||||||
|
WriteF(&Result.TypeList, "enum gsm_struct_type\n{\n");
|
||||||
|
|
||||||
|
WriteF(&Result.TypeDefinitions, "static gsm_struct_type_info StructTypes[] = {\n");
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
FinishGeneratingTypes(typeinfo_generator* Generator)
|
||||||
|
{
|
||||||
|
WriteF(&Generator->TypeList, "gsm_StructTypeCount,\n};\n\n");
|
||||||
|
|
||||||
|
WriteF(&Generator->StructMembers, "\n");
|
||||||
|
|
||||||
|
WriteF(&Generator->TypeDefinitions, "};\n");
|
||||||
|
WriteF(&Generator->TypeDefinitions, "gsm_u32 StructTypesCount = %d;\n", Generator->GeneratedInfoTypesCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
GenerateMetaTagInfo (gs_bucket<meta_tag> Tags, string_builder* Builder)
|
||||||
|
{
|
||||||
|
WriteF(Builder, "{");
|
||||||
|
for (u32 t = 0; t < Tags.Used; t++)
|
||||||
|
{
|
||||||
|
meta_tag* Tag = Tags.GetElementAtIndex(t);
|
||||||
|
WriteF(Builder, "{ \"%S\", %d }", Tag->Identifier, Tag->Identifier.Length);
|
||||||
|
if ((t + 1) < Tags.Used)
|
||||||
|
{
|
||||||
|
WriteF(Builder, ", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WriteF(Builder, "}, %d", Tags.Used);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
GenerateStructMemberInfo (variable_decl* Member, string StructIdentifier, type_table TypeTable, typeinfo_generator* Gen)
|
||||||
|
{
|
||||||
|
WriteF(&Gen->StructMembers, "{ \"%S\", %d, ", Member->Identifier, Member->Identifier.Length);
|
||||||
|
WriteF(&Gen->StructMembers, "(u64)&((%S*)0)->%S ", StructIdentifier, Member->Identifier);
|
||||||
|
WriteF(&Gen->StructMembers, "},\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
GenerateTypeInfo (type_definition* Type, u32 TypeIndex, type_table TypeTable, typeinfo_generator* Generator)
|
||||||
|
{
|
||||||
|
Generator->TypesGeneratedMask[TypeIndex] = true;
|
||||||
|
Generator->GeneratedInfoTypesCount++;
|
||||||
|
|
||||||
|
{
|
||||||
|
// NOTE(Peter): This block MUST come before generating
|
||||||
|
// type info for any member types. If it doesn't, it will screw
|
||||||
|
// up array ordering
|
||||||
|
|
||||||
|
// Lookup Enum
|
||||||
|
WriteF(&Generator->TypeList, "gsm_StructType_%S,\n", Type->Identifier);
|
||||||
|
|
||||||
|
// Type Info
|
||||||
|
WriteF(&Generator->TypeDefinitions, "{ gsm_StructType_%S, \"%S\", %d, %d, 0, 0, ",
|
||||||
|
Type->Identifier,
|
||||||
|
Type->Identifier, Type->Identifier.Length,
|
||||||
|
Type->Size
|
||||||
|
// TODO(Peter): include Meta Tags somehow
|
||||||
|
);
|
||||||
|
if ((Type->Type == TypeDef_Struct || Type->Type == TypeDef_Union) &&
|
||||||
|
Type->Struct.MemberDecls.Used > 0)
|
||||||
|
{
|
||||||
|
WriteF(&Generator->TypeDefinitions, "StructMembers_%S, %d },\n",
|
||||||
|
Type->Identifier,
|
||||||
|
Type->Struct.MemberDecls.Used);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WriteF(&Generator->TypeDefinitions, "0, 0 },\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Type->Type == TypeDef_Struct ||
|
||||||
|
Type->Type == TypeDef_Union)
|
||||||
|
{
|
||||||
|
for (u32 m = 0; m < Type->Struct.MemberDecls.Used; m++)
|
||||||
|
{
|
||||||
|
variable_decl* Member = Type->Struct.MemberDecls.GetElementAtIndex(m);
|
||||||
|
type_definition* MemberType = TypeTable.Types.GetElementAtIndex(Member->TypeIndex);
|
||||||
|
|
||||||
|
if (MemberType->Identifier.Length == 0) { continue; } // Don't gen info for anonymous struct and union members
|
||||||
|
if (Generator->TypesGeneratedMask[Member->TypeIndex]) { continue; }
|
||||||
|
|
||||||
|
GenerateTypeInfo(MemberType, Member->TypeIndex, TypeTable, Generator);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
WriteF(&Generator->StructMembers, "static gsm_struct_member_type_info StructMembers_%S[] = {\n", Type->Identifier);
|
||||||
|
for (u32 m = 0; m < Type->Struct.MemberDecls.Used; m++)
|
||||||
|
{
|
||||||
|
variable_decl* Member = Type->Struct.MemberDecls.GetElementAtIndex(m);
|
||||||
|
type_definition* MemberType = TypeTable.Types.GetElementAtIndex(Member->TypeIndex);
|
||||||
|
|
||||||
|
if (MemberType->Identifier.Length > 0)
|
||||||
|
{
|
||||||
|
GenerateStructMemberInfo(Member, Type->Identifier, TypeTable, Generator);
|
||||||
|
}
|
||||||
|
else if (MemberType->Type == TypeDef_Struct ||
|
||||||
|
MemberType->Type == TypeDef_Union)
|
||||||
|
{
|
||||||
|
// Anonymous Members
|
||||||
|
for (u32 a = 0; a < MemberType->Struct.MemberDecls.Used; a++)
|
||||||
|
{
|
||||||
|
variable_decl* AnonMember = MemberType->Struct.MemberDecls.GetElementAtIndex(a);
|
||||||
|
GenerateStructMemberInfo(AnonMember, Type->Identifier, TypeTable, Generator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WriteF(&Generator->StructMembers, "};\n", Type->Struct.MemberDecls.Used);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
GenerateFilteredTypeInfo (string MetaTagFilter, type_table TypeTable, typeinfo_generator* Generator)
|
||||||
|
{
|
||||||
|
for (u32 i = 0; i < TypeTable.Types.Used; i++)
|
||||||
|
{
|
||||||
|
if (Generator->TypesGeneratedMask[i])
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
type_definition* Type = TypeTable.Types.GetElementAtIndex(i);
|
||||||
|
if (HasTag(MetaTagFilter, Type->MetaTags))
|
||||||
|
{
|
||||||
|
GenerateTypeInfo(Type, i, TypeTable, Generator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define GS_META_TYPEINFO_GENERATOR_H
|
||||||
|
#endif // GS_META_TYPEINFO_GENERATOR_H
|
Loading…
Reference in New Issue