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
1740
meta/gs_meta.cpp
1740
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];
|
||||
string Buffer;
|
||||
char* Backbuffer;
|
||||
string* Contents;
|
||||
};
|
||||
|
||||
struct error_list_buffer
|
||||
#define ERROR_MAX_LENGTH 256
|
||||
#define ERROR_BUFFER_SIZE 256
|
||||
struct errors
|
||||
{
|
||||
error* List;
|
||||
s32 Used;
|
||||
s32 Max;
|
||||
error_list_buffer* Next;
|
||||
error_buffer* Buffers;
|
||||
u32 BuffersCount;
|
||||
u32 Used;
|
||||
};
|
||||
|
||||
struct error_list
|
||||
{
|
||||
error_list_buffer* Head;
|
||||
s32 TotalUsed;
|
||||
s32 TotalMax;
|
||||
};
|
||||
|
||||
#define ERROR_LIST_GROW_SIZE 32
|
||||
|
||||
internal void
|
||||
GrowErrorList (error_list* Errors)
|
||||
PushFError (errors* Errors, char* Format, ...)
|
||||
{
|
||||
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)
|
||||
if (Errors->Used >= (Errors->BuffersCount * ERROR_BUFFER_SIZE))
|
||||
{
|
||||
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++);
|
||||
Errors->TotalUsed++;
|
||||
|
||||
InitializeEmptyString(&Error->Buffer, Error->Backbuffer, MAX_ERROR_LENGTH);
|
||||
u32 NewErrorIndex = Errors->Used++;
|
||||
u32 BufferIndex = NewErrorIndex / ERROR_BUFFER_SIZE;
|
||||
u32 IndexInBuffer = NewErrorIndex % ERROR_BUFFER_SIZE;
|
||||
string* NewError = Errors->Buffers[BufferIndex].Contents + IndexInBuffer;
|
||||
|
||||
va_list Args;
|
||||
va_start(Args, Format);
|
||||
|
||||
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);
|
||||
|
||||
NewError->Length = PrintFArgsList(NewError->Memory, NewError->Max, Format, Args);
|
||||
va_end(Args);
|
||||
}
|
||||
|
||||
internal void
|
||||
PrintErrorListBuffer (error_list_buffer* Buffer)
|
||||
internal string*
|
||||
TakeError (errors* Errors)
|
||||
{
|
||||
if (Buffer->Next)
|
||||
{
|
||||
PrintErrorListBuffer(Buffer->Next);
|
||||
}
|
||||
|
||||
for (s32 i = 0; i < Buffer->Used; i++)
|
||||
{
|
||||
error* Error = Buffer->List + i;
|
||||
NullTerminate(&Error->Buffer);
|
||||
printf(Error->Backbuffer);
|
||||
printf("\n");
|
||||
}
|
||||
u32 NewErrorIndex = Errors->Used++;
|
||||
u32 BufferIndex = NewErrorIndex / ERROR_BUFFER_SIZE;
|
||||
u32 IndexInBuffer = NewErrorIndex % ERROR_BUFFER_SIZE;
|
||||
string* NewError = Errors->Buffers[BufferIndex].Contents + IndexInBuffer;
|
||||
return NewError;
|
||||
}
|
||||
|
||||
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