Separating out different parts of the meta system.

This commit is contained in:
Peter Slattery 2020-01-19 17:48:57 -08:00
parent e8759c931a
commit d1353e52fa
4 changed files with 1316 additions and 2164 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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));
} }
} }

View File

@ -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