Compressing Type Info Generation
This commit is contained in:
parent
d1353e52fa
commit
af11a85e94
|
@ -1,15 +1,9 @@
|
||||||
//
|
//
|
||||||
// Usage
|
// File: foldhaus_meta.cpp
|
||||||
|
// Author: Peter Slattery
|
||||||
|
// Creation Date: 2020-01-19
|
||||||
//
|
//
|
||||||
// GSMetaTag(<tag name>) to give commands to the meta layer
|
#ifndef FOLDHAUS_META_CPP
|
||||||
//
|
|
||||||
// Tag Values
|
|
||||||
//
|
|
||||||
// breakpoint
|
|
||||||
// will cause the meta layer to break in the debugger when it reaches
|
|
||||||
// that point in processing the file
|
|
||||||
// TODO: specify which stage you want it to break at
|
|
||||||
|
|
||||||
|
|
||||||
#include "gs_meta.cpp"
|
#include "gs_meta.cpp"
|
||||||
#include "gs_meta_typeinfo_generator.h"
|
#include "gs_meta_typeinfo_generator.h"
|
||||||
|
@ -23,25 +17,64 @@ int main(int ArgCount, char* Args[])
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_meta_preprocessor Meta = PreprocessProgram(Args[1]);
|
gs_meta_preprocessor Meta = PreprocessProgram(Args[1]);
|
||||||
s64 Cycles_Preprocess = GetWallClock();
|
|
||||||
|
|
||||||
typeinfo_generator TypeGenerator = InitTypeInfoGenerator(Meta.TypeTable);
|
typeinfo_generator TypeGenerator = InitTypeInfoGenerator(Meta.TypeTable);
|
||||||
|
|
||||||
GenerateFilteredTypeInfo(MakeStringLiteral("node_struct"), Meta.TypeTable, &TypeGenerator);
|
GenerateFilteredTypeInfo(MakeStringLiteral("node_struct"), Meta.TypeTable, &TypeGenerator);
|
||||||
GenerateFilteredTypeInfo(MakeStringLiteral("gen_type_info"), Meta.TypeTable, &TypeGenerator);
|
GenerateFilteredTypeInfo(MakeStringLiteral("gen_type_info"), Meta.TypeTable, &TypeGenerator);
|
||||||
|
|
||||||
FinishGeneratingTypes(&TypeGenerator);
|
FinishGeneratingTypes(&TypeGenerator);
|
||||||
|
|
||||||
|
gsm_code_generator NodeTypeGen = BeginEnumGeneration("node_type", "NodeType", false, true);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// TODO(Peter): Create a FilterTypesByTag function to create a contiguous array
|
||||||
|
// of type_definition**
|
||||||
|
printf("\n\n");
|
||||||
|
for (u32 i = 0; i < Meta.TypeTable.Types.Used; i++)
|
||||||
|
{
|
||||||
|
type_definition* Decl = Meta.TypeTable.Types.GetElementAtIndex(i);
|
||||||
|
if (HasTag(MakeStringLiteral("node_proc"), Decl->MetaTags) &&
|
||||||
|
Decl->Type == TypeDef_Function)
|
||||||
|
{
|
||||||
|
AddEnumElement(&NodeTypeGen, Decl->Identifier);
|
||||||
|
|
||||||
|
type_table_handle ReturnTypeHandle = Decl->Function.ReturnTypeHandle;
|
||||||
|
type_definition* ReturnType = GetTypeDefinition(ReturnTypeHandle, Meta.TypeTable);
|
||||||
|
printf("%.*s %.*s(\n", StringExpand(ReturnType->Identifier), StringExpand(Decl->Identifier));
|
||||||
|
for (u32 j = 0; j < Decl->Function.Parameters.Used; j++)
|
||||||
|
{
|
||||||
|
variable_decl* Param = Decl->Function.Parameters.GetElementAtIndex(j);
|
||||||
|
type_table_handle ParamTypeHandle = Param->TypeHandle;
|
||||||
|
type_definition* ParamType = GetTypeDefinition(ParamTypeHandle, Meta.TypeTable);
|
||||||
|
printf(" %.*s %.*s,\n", StringExpand(ParamType->Identifier), StringExpand(Param->Identifier));
|
||||||
|
}
|
||||||
|
printf(");\n\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\n\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
FinishEnumGeneration(&NodeTypeGen);
|
||||||
|
|
||||||
FILE* TypeInfoH = fopen("C:\\projects\\foldhaus\\src\\generated\\gs_meta_generated_typeinfo.h", "w");
|
FILE* TypeInfoH = fopen("C:\\projects\\foldhaus\\src\\generated\\gs_meta_generated_typeinfo.h", "w");
|
||||||
if (TypeInfoH)
|
if (TypeInfoH)
|
||||||
{
|
{
|
||||||
WriteStringBuilderToFile(TypeGenerator.TypeList, TypeInfoH);
|
WriteStringBuilderToFile(*TypeGenerator.TypeList.Builder, TypeInfoH);
|
||||||
WriteStringBuilderToFile(TypeGenerator.StructMembers, TypeInfoH);
|
WriteStringBuilderToFile(TypeGenerator.StructMembers, TypeInfoH);
|
||||||
WriteStringBuilderToFile(TypeGenerator.TypeDefinitions, TypeInfoH);
|
WriteStringBuilderToFile(TypeGenerator.TypeDefinitions, TypeInfoH);
|
||||||
fclose(TypeInfoH);
|
fclose(TypeInfoH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FILE* NodeInfoH = fopen("C:\\projects\\foldhaus\\src\\generated\\foldhaus_nodes_generated.h", "w");
|
||||||
|
if (NodeInfoH)
|
||||||
|
{
|
||||||
|
WriteStringBuilderToFile(*NodeTypeGen.Builder, NodeInfoH);
|
||||||
|
fclose(NodeInfoH);
|
||||||
|
}
|
||||||
|
|
||||||
FinishMetaprogram(&Meta);
|
FinishMetaprogram(&Meta);
|
||||||
//__debugbreak();
|
//__debugbreak();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define FOLDHAUS_META_CPP
|
||||||
|
#endif // FOLDHAUS_META_CPP
|
|
@ -16,10 +16,17 @@ enum type_definition_type
|
||||||
TypeDef_Union,
|
TypeDef_Union,
|
||||||
TypeDef_BasicType,
|
TypeDef_BasicType,
|
||||||
TypeDef_FunctionPointer,
|
TypeDef_FunctionPointer,
|
||||||
|
TypeDef_Function,
|
||||||
|
|
||||||
TypeDef_Count,
|
TypeDef_Count,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct type_table_handle
|
||||||
|
{
|
||||||
|
s32 BucketIndex;
|
||||||
|
u32 IndexInBucket;
|
||||||
|
};
|
||||||
|
|
||||||
struct meta_tag
|
struct meta_tag
|
||||||
{
|
{
|
||||||
string Identifier;
|
string Identifier;
|
||||||
|
@ -31,7 +38,7 @@ struct variable_decl
|
||||||
// at the same time. This means that not all types will be able to be matched
|
// at the same time. This means that not all types will be able to be matched
|
||||||
// up on the first pass through. A TypeIndex of -1 means we need to fixup that
|
// up on the first pass through. A TypeIndex of -1 means we need to fixup that
|
||||||
// type at a later time
|
// type at a later time
|
||||||
s32 TypeIndex;
|
type_table_handle TypeHandle;
|
||||||
string Identifier;
|
string Identifier;
|
||||||
b32 Pointer;
|
b32 Pointer;
|
||||||
|
|
||||||
|
@ -45,6 +52,7 @@ struct variable_decl
|
||||||
|
|
||||||
struct struct_decl
|
struct struct_decl
|
||||||
{
|
{
|
||||||
|
b32 IsAnonymous;
|
||||||
// TODO(Peter): Lots of tiny arrays everywhere! Pull these into a central allocation
|
// TODO(Peter): Lots of tiny arrays everywhere! Pull these into a central allocation
|
||||||
// buffer somewhere
|
// buffer somewhere
|
||||||
// :SmallAllocationsAllOver
|
// :SmallAllocationsAllOver
|
||||||
|
@ -53,11 +61,18 @@ struct struct_decl
|
||||||
|
|
||||||
struct function_pointer_decl
|
struct function_pointer_decl
|
||||||
{
|
{
|
||||||
s32 ReturnTypeIndex;
|
type_table_handle ReturnTypeHandle;
|
||||||
// :SmallAllocationsAllOver
|
// :SmallAllocationsAllOver
|
||||||
gs_bucket<variable_decl> Parameters;
|
gs_bucket<variable_decl> Parameters;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct function_decl
|
||||||
|
{
|
||||||
|
type_table_handle ReturnTypeHandle;
|
||||||
|
gs_bucket<variable_decl> Parameters;
|
||||||
|
// TODO(Peter): AST?
|
||||||
|
};
|
||||||
|
|
||||||
struct enum_decl
|
struct enum_decl
|
||||||
{
|
{
|
||||||
gs_bucket<string> Identifiers;
|
gs_bucket<string> Identifiers;
|
||||||
|
@ -80,13 +95,22 @@ struct type_definition
|
||||||
enum_decl Enum;
|
enum_decl Enum;
|
||||||
struct_decl Struct;
|
struct_decl Struct;
|
||||||
function_pointer_decl FunctionPtr;
|
function_pointer_decl FunctionPtr;
|
||||||
|
function_decl Function;
|
||||||
};
|
};
|
||||||
b32 Pointer;
|
b32 Pointer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define TYPE_TABLE_BUCKET_MAX 1024
|
||||||
|
struct type_table_hash_bucket
|
||||||
|
{
|
||||||
|
u32* Keys;
|
||||||
|
type_definition* Values;
|
||||||
|
};
|
||||||
|
|
||||||
struct type_table
|
struct type_table
|
||||||
{
|
{
|
||||||
gs_bucket<type_definition> Types;
|
type_table_hash_bucket* Types;
|
||||||
|
u32 TypeBucketsCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
internal b32
|
internal b32
|
||||||
|
@ -119,63 +143,190 @@ CopyMetaTagsAndClear(gs_bucket<token>* Source, gs_bucket<meta_tag>* Dest)
|
||||||
Source->Used = 0;
|
Source->Used = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal s32
|
#define InvalidTypeTableHandle type_table_handle{0, 0}
|
||||||
|
|
||||||
|
// #define TypeHandleIsValid(handle) (!((handle).BucketIndex == 0) && ((handle).IndexInBucket == 0))
|
||||||
|
inline b32 TypeHandleIsValid(type_table_handle A)
|
||||||
|
{
|
||||||
|
b32 FirstBucket = (A.BucketIndex == 0);
|
||||||
|
b32 FirstIndex = (A.IndexInBucket == 0);
|
||||||
|
b32 Both = FirstBucket && FirstIndex;
|
||||||
|
return !Both;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define TypeHandlesEqual(a, b) (((a).BucketIndex == (b).BucketIndex) && ((a).IndexInBucket == (b).IndexInBucket))
|
||||||
|
|
||||||
|
internal u32
|
||||||
|
HashIdentifier(string Identifier)
|
||||||
|
{
|
||||||
|
u32 IdentHash = HashString(Identifier);
|
||||||
|
if (IdentHash == 0)
|
||||||
|
{
|
||||||
|
// NOTE(Peter): We are excluding a has of zero so taht
|
||||||
|
// the type_table_handle where BucketIndex and IndexInBucket
|
||||||
|
// are both zero is an invalid handle
|
||||||
|
IdentHash += 1;
|
||||||
|
}
|
||||||
|
return IdentHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal type_table_handle
|
||||||
|
PushTypeOnHashTable(type_definition TypeDef, type_table* TypeTable)
|
||||||
|
{
|
||||||
|
type_table_handle Result = InvalidTypeTableHandle;
|
||||||
|
|
||||||
|
u32 IdentHash = HashIdentifier(TypeDef.Identifier);
|
||||||
|
u32 Index = IdentHash % TYPE_TABLE_BUCKET_MAX;
|
||||||
|
|
||||||
|
for (u32 b = 0; b < TypeTable->TypeBucketsCount; b++)
|
||||||
|
{
|
||||||
|
type_table_hash_bucket* Bucket = TypeTable->Types + b;
|
||||||
|
if (Bucket->Keys[Index] == 0)
|
||||||
|
{
|
||||||
|
Bucket->Keys[Index] = IdentHash;
|
||||||
|
Bucket->Values[Index] = TypeDef;
|
||||||
|
|
||||||
|
Result.BucketIndex = b;
|
||||||
|
Result.IndexInBucket = Index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TypeHandleIsValid(Result))
|
||||||
|
{
|
||||||
|
// Grow Hash Table
|
||||||
|
u32 NewTypeBucketIndex = TypeTable->TypeBucketsCount++;
|
||||||
|
u32 NewTypesSize = TypeTable->TypeBucketsCount * sizeof(type_table_hash_bucket);
|
||||||
|
TypeTable->Types = (type_table_hash_bucket*)realloc(TypeTable->Types, NewTypesSize);
|
||||||
|
|
||||||
|
type_table_hash_bucket* NewBucket = TypeTable->Types + NewTypeBucketIndex;
|
||||||
|
NewBucket->Keys = (u32*)malloc(sizeof(u32) * TYPE_TABLE_BUCKET_MAX);
|
||||||
|
NewBucket->Values = (type_definition*)malloc(sizeof(type_definition) * TYPE_TABLE_BUCKET_MAX);
|
||||||
|
GSZeroMemory((u8*)NewBucket->Keys, sizeof(u32) * TYPE_TABLE_BUCKET_MAX);
|
||||||
|
GSZeroMemory((u8*)NewBucket->Values, sizeof(type_definition) * TYPE_TABLE_BUCKET_MAX);
|
||||||
|
|
||||||
|
NewBucket->Keys[Index] = IdentHash;
|
||||||
|
NewBucket->Values[Index] = TypeDef;
|
||||||
|
|
||||||
|
Result.BucketIndex = NewTypeBucketIndex;
|
||||||
|
Result.IndexInBucket = Index;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal type_table_handle
|
||||||
PushUndeclaredType (string Identifier, type_table* TypeTable)
|
PushUndeclaredType (string Identifier, type_table* TypeTable)
|
||||||
{
|
{
|
||||||
type_definition UndeclaredTypeDef = {};
|
type_definition UndeclaredTypeDef = {};
|
||||||
UndeclaredTypeDef.Identifier = Identifier;
|
UndeclaredTypeDef.Identifier = Identifier;
|
||||||
UndeclaredTypeDef.Type = TypeDef_Unknown;
|
UndeclaredTypeDef.Type = TypeDef_Unknown;
|
||||||
s32 TypeIndex = (s32)TypeTable->Types.PushElementOnBucket(UndeclaredTypeDef);
|
type_table_handle Result = PushTypeOnHashTable(UndeclaredTypeDef, TypeTable);
|
||||||
return TypeIndex;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal s32
|
internal type_table_handle
|
||||||
GetIndexOfType (string Identifier, type_table TypeTable)
|
GetTypeHandle (string Identifier, type_table TypeTable)
|
||||||
{
|
{
|
||||||
s32 Result = -1;
|
type_table_handle Result = InvalidTypeTableHandle;
|
||||||
for (u32 i = 0; i < TypeTable.Types.Used; i++)
|
|
||||||
|
u32 IdentHash = HashIdentifier(Identifier);
|
||||||
|
u32 Index = IdentHash % TYPE_TABLE_BUCKET_MAX;
|
||||||
|
|
||||||
|
for (u32 b = 0; b < TypeTable.TypeBucketsCount; b++)
|
||||||
{
|
{
|
||||||
type_definition* TypeDef = TypeTable.Types.GetElementAtIndex(i);
|
type_table_hash_bucket Bucket = TypeTable.Types[b];
|
||||||
if (StringsEqual(Identifier, TypeDef->Identifier))
|
if (Bucket.Keys[Index] == IdentHash)
|
||||||
{
|
{
|
||||||
Result = i;
|
Result.BucketIndex = b;
|
||||||
|
Result.IndexInBucket = Index;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Guaranteed to return a valid result
|
||||||
|
internal type_definition*
|
||||||
|
GetTypeDefinition(type_table_handle Handle, type_table TypeTable)
|
||||||
|
{
|
||||||
|
Assert(TypeHandleIsValid(Handle));
|
||||||
|
type_definition* Result = 0;
|
||||||
|
if (TypeTable.Types[Handle.BucketIndex].Keys != 0)
|
||||||
|
{
|
||||||
|
Result = TypeTable.Types[Handle.BucketIndex].Values + Handle.IndexInBucket;
|
||||||
|
}
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// May return zero
|
||||||
|
internal type_definition*
|
||||||
|
GetTypeDefinitionUnsafe(type_table_handle Handle, type_table TypeTable)
|
||||||
|
{
|
||||||
|
type_definition* Result = 0;
|
||||||
|
if (TypeTable.Types[Handle.BucketIndex].Keys != 0)
|
||||||
|
{
|
||||||
|
Result = TypeTable.Types[Handle.BucketIndex].Values + Handle.IndexInBucket;
|
||||||
|
}
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal type_definition*
|
||||||
|
GetTypeDefinition(string Identifier, type_table TypeTable)
|
||||||
|
{
|
||||||
|
type_definition* Result = 0;
|
||||||
|
u32 IdentHash = HashIdentifier(Identifier);
|
||||||
|
u32 Index = IdentHash % TYPE_TABLE_BUCKET_MAX;
|
||||||
|
for (u32 b = 0; b < TypeTable.TypeBucketsCount; b++)
|
||||||
|
{
|
||||||
|
type_table_hash_bucket Bucket = TypeTable.Types[b];
|
||||||
|
if (Bucket.Keys[Index] == IdentHash )
|
||||||
|
{
|
||||||
|
Result = Bucket.Values + Index;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal s32
|
internal type_table_handle
|
||||||
PushTypeDefOnTypeTable(type_definition TypeDef, type_table* TypeTable)
|
PushTypeDefOnTypeTable(type_definition TypeDef, type_table* TypeTable)
|
||||||
{
|
{
|
||||||
s32 Index = -1;
|
// NOTE(Peter): We don't accept type definitions with empty identifiers.
|
||||||
|
// If a struct or union is anonymous, it should be assigned a name of the form
|
||||||
|
// parent_struct_name_# where # is the member index
|
||||||
|
// ie.
|
||||||
|
// struct foo { int a; union { int x }; };
|
||||||
|
// the union in foo would have the identifier foo_1
|
||||||
|
Assert(TypeDef.Identifier.Length != 0);
|
||||||
|
|
||||||
s32 ExistingUndeclaredTypeIndex = GetIndexOfType(TypeDef.Identifier, *TypeTable);
|
type_table_handle Result = InvalidTypeTableHandle;
|
||||||
|
type_table_handle ExistingUndeclaredTypeHandle = GetTypeHandle(TypeDef.Identifier, *TypeTable);
|
||||||
|
|
||||||
// NOTE(Peter): If the identifier length is zero, they will all match with the
|
if (!TypeHandleIsValid(ExistingUndeclaredTypeHandle))
|
||||||
// first anonymous struct/union member. So every anon struct/union gets its own
|
|
||||||
// typeef
|
|
||||||
if (ExistingUndeclaredTypeIndex < 0 || TypeDef.Identifier.Length == 0)
|
|
||||||
{
|
{
|
||||||
Index = TypeTable->Types.PushElementOnBucket(TypeDef);
|
Result = PushTypeOnHashTable(TypeDef, TypeTable);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Index = ExistingUndeclaredTypeIndex;
|
Result = ExistingUndeclaredTypeHandle;
|
||||||
type_definition* ExistingTypeDef = TypeTable->Types.GetElementAtIndex(ExistingUndeclaredTypeIndex);
|
type_definition* ExistingTypeDef = GetTypeDefinition(Result, *TypeTable);
|
||||||
|
Assert(ExistingTypeDef != 0);
|
||||||
*ExistingTypeDef = TypeDef;
|
*ExistingTypeDef = TypeDef;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Index;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal s32
|
internal s32
|
||||||
GetSizeOfType (s32 TypeIndex, type_table TypeTable)
|
GetSizeOfType (type_table_handle TypeHandle, type_table TypeTable)
|
||||||
{
|
{
|
||||||
s32 Result = -1;
|
s32 Result = -1;
|
||||||
Assert(TypeIndex >= 0 && (u32)TypeIndex < TypeTable.Types.Used);
|
type_definition* TypeDef = GetTypeDefinition(TypeHandle, TypeTable);
|
||||||
type_definition* TypeDef = TypeTable.Types.GetElementAtIndex(TypeIndex);
|
if (TypeDef)
|
||||||
|
{
|
||||||
Result = TypeDef->Size;
|
Result = TypeDef->Size;
|
||||||
|
}
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,14 +334,10 @@ internal s32
|
||||||
GetSizeOfType (string Identifier, type_table TypeTable)
|
GetSizeOfType (string Identifier, type_table TypeTable)
|
||||||
{
|
{
|
||||||
s32 Result = -1;
|
s32 Result = -1;
|
||||||
for (u32 i = 0; i < TypeTable.Types.Used; i++)
|
type_definition* TypeDef = GetTypeDefinition(Identifier, TypeTable);
|
||||||
{
|
if (TypeDef)
|
||||||
type_definition* TypeDef = TypeTable.Types.GetElementAtIndex(i);
|
|
||||||
if (StringsEqual(Identifier, TypeDef->Identifier))
|
|
||||||
{
|
{
|
||||||
Result = TypeDef->Size;
|
Result = TypeDef->Size;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
@ -199,7 +346,7 @@ internal b32
|
||||||
VariableDeclsEqual (variable_decl A, variable_decl B)
|
VariableDeclsEqual (variable_decl A, variable_decl B)
|
||||||
{
|
{
|
||||||
b32 Result = false;
|
b32 Result = false;
|
||||||
if (A.TypeIndex == B.TypeIndex &&
|
if (TypeHandlesEqual(A.TypeHandle, B.TypeHandle) &&
|
||||||
A.ArrayCount == B.ArrayCount &&
|
A.ArrayCount == B.ArrayCount &&
|
||||||
StringsEqual(A.Identifier, B.Identifier))
|
StringsEqual(A.Identifier, B.Identifier))
|
||||||
{
|
{
|
||||||
|
@ -236,51 +383,35 @@ StructOrUnionsEqual (type_definition A, type_definition B)
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal s32
|
internal type_table_handle
|
||||||
FindIndexOfMatchingType (type_definition Match, type_table TypeTable)
|
FindHandleOfMatchingType (type_definition Match, type_table TypeTable)
|
||||||
{
|
{
|
||||||
s32 Result = -1;
|
type_table_handle Result = InvalidTypeTableHandle;
|
||||||
for (u32 i = 0; i < TypeTable.Types.Used; i++)
|
type_table_handle Handle = GetTypeHandle(Match.Identifier, TypeTable);
|
||||||
|
if (TypeHandleIsValid(Handle))
|
||||||
{
|
{
|
||||||
type_definition* TypeDef = TypeTable.Types.GetElementAtIndex(i);
|
Result = Handle;
|
||||||
if (StringsEqual(Match.Identifier, TypeDef->Identifier))
|
|
||||||
{
|
|
||||||
if (Match.Type == TypeDef_Struct ||
|
|
||||||
Match.Type == TypeDef_Union)
|
|
||||||
{
|
|
||||||
if (StructOrUnionsEqual(Match, *TypeDef))
|
|
||||||
{
|
|
||||||
Result = (s32)i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Result = (s32)i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void FixUpStructSize (s32 StructIndex, type_table TypeTable, errors* Errors);
|
internal void FixUpStructSize (type_table_handle TypeHandle, type_table TypeTable, errors* Errors);
|
||||||
internal void FixUpUnionSize (s32 UnionIndex, type_table TypeTable, errors* Errors);
|
internal void FixUpUnionSize (type_table_handle TypeHandle, type_table TypeTable, errors* Errors);
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
FixupMemberType (variable_decl* Member, type_table TypeTable)
|
FixupMemberType (variable_decl* Member, type_table TypeTable)
|
||||||
{
|
{
|
||||||
if (Member->TypeIndex == -1)
|
if (!TypeHandleIsValid(Member->TypeHandle))
|
||||||
{
|
{
|
||||||
Member->TypeIndex = GetIndexOfType(Member->Identifier, TypeTable);
|
Member->TypeHandle = GetTypeHandle(Member->Identifier, TypeTable);
|
||||||
}
|
}
|
||||||
Assert(Member->TypeIndex >= 0);
|
Assert(TypeHandleIsValid(Member->TypeHandle));
|
||||||
}
|
}
|
||||||
|
|
||||||
internal s32
|
internal s32
|
||||||
CalculateStructMemberSize (variable_decl Member, type_definition MemberType)
|
CalculateStructMemberSize (variable_decl Member, type_definition MemberType)
|
||||||
{
|
{
|
||||||
Assert(Member.TypeIndex >= 0);
|
Assert(TypeHandleIsValid(Member.TypeHandle));
|
||||||
// NOTE(Peter): At one point we were Asserting on struct sizes of zero, but
|
// NOTE(Peter): At one point we were Asserting on struct sizes of zero, but
|
||||||
// that's actually incorrect. It is valid to have an empty struct.
|
// that's actually incorrect. It is valid to have an empty struct.
|
||||||
|
|
||||||
|
@ -325,11 +456,11 @@ FixupStructMember (variable_decl* Member, type_definition* MemberTypeDef, type_t
|
||||||
{
|
{
|
||||||
if (MemberTypeDef->Type == TypeDef_Struct)
|
if (MemberTypeDef->Type == TypeDef_Struct)
|
||||||
{
|
{
|
||||||
FixUpStructSize(Member->TypeIndex, TypeTable, Errors);
|
FixUpStructSize(Member->TypeHandle, TypeTable, Errors);
|
||||||
}
|
}
|
||||||
else if (MemberTypeDef->Type == TypeDef_Union)
|
else if (MemberTypeDef->Type == TypeDef_Union)
|
||||||
{
|
{
|
||||||
FixUpUnionSize(Member->TypeIndex, TypeTable, Errors);
|
FixUpUnionSize(Member->TypeHandle, TypeTable, Errors);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -353,9 +484,9 @@ FixupStructMember (variable_decl* Member, type_definition* MemberTypeDef, type_t
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
FixUpStructSize (s32 StructIndex, type_table TypeTable, errors* Errors)
|
FixUpStructSize (type_table_handle TypeHandle, type_table TypeTable, errors* Errors)
|
||||||
{
|
{
|
||||||
type_definition* Struct = TypeTable.Types.GetElementAtIndex(StructIndex);
|
type_definition* Struct = GetTypeDefinition(TypeHandle, TypeTable);
|
||||||
Assert(Struct->Type == TypeDef_Struct);
|
Assert(Struct->Type == TypeDef_Struct);
|
||||||
|
|
||||||
if (HasTag(MakeStringLiteral("breakpoint"), Struct->MetaTags))
|
if (HasTag(MakeStringLiteral("breakpoint"), Struct->MetaTags))
|
||||||
|
@ -369,12 +500,10 @@ FixUpStructSize (s32 StructIndex, type_table TypeTable, errors* Errors)
|
||||||
variable_decl* Member = Struct->Struct.MemberDecls.GetElementAtIndex(j);
|
variable_decl* Member = Struct->Struct.MemberDecls.GetElementAtIndex(j);
|
||||||
FixupMemberType(Member, TypeTable);
|
FixupMemberType(Member, TypeTable);
|
||||||
|
|
||||||
if (Member->TypeIndex >= 0)
|
if (TypeHandleIsValid(Member->TypeHandle))
|
||||||
{
|
{
|
||||||
type_definition* MemberTypeDef = TypeTable.Types.GetElementAtIndex(Member->TypeIndex);
|
type_definition* MemberTypeDef = GetTypeDefinition(Member->TypeHandle, TypeTable);
|
||||||
|
|
||||||
FixupStructMember(Member, MemberTypeDef, TypeTable, Errors);
|
FixupStructMember(Member, MemberTypeDef, TypeTable, Errors);
|
||||||
|
|
||||||
u32 MemberSize = CalculateStructMemberSize(*Member, *MemberTypeDef);
|
u32 MemberSize = CalculateStructMemberSize(*Member, *MemberTypeDef);
|
||||||
SizeAcc += MemberSize;
|
SizeAcc += MemberSize;
|
||||||
}
|
}
|
||||||
|
@ -400,9 +529,9 @@ FixUpStructSize (s32 StructIndex, type_table TypeTable, errors* Errors)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
FixUpUnionSize (s32 UnionIndex, type_table TypeTable, errors* Errors)
|
FixUpUnionSize (type_table_handle TypeHandle, type_table TypeTable, errors* Errors)
|
||||||
{
|
{
|
||||||
type_definition* Union = TypeTable.Types.GetElementAtIndex(UnionIndex);
|
type_definition* Union = GetTypeDefinition(TypeHandle, TypeTable);
|
||||||
Assert(Union->Type == TypeDef_Union);
|
Assert(Union->Type == TypeDef_Union);
|
||||||
|
|
||||||
s32 BiggestMemberSize = 0;
|
s32 BiggestMemberSize = 0;
|
||||||
|
@ -411,9 +540,9 @@ FixUpUnionSize (s32 UnionIndex, type_table TypeTable, errors* Errors)
|
||||||
variable_decl* Member = Union->Struct.MemberDecls.GetElementAtIndex(j);
|
variable_decl* Member = Union->Struct.MemberDecls.GetElementAtIndex(j);
|
||||||
FixupMemberType(Member, TypeTable);
|
FixupMemberType(Member, TypeTable);
|
||||||
|
|
||||||
if (Member->TypeIndex >= 0)
|
if (TypeHandleIsValid(Member->TypeHandle))
|
||||||
{
|
{
|
||||||
type_definition* MemberTypeDef = TypeTable.Types.GetElementAtIndex(Member->TypeIndex);
|
type_definition* MemberTypeDef = GetTypeDefinition(Member->TypeHandle, TypeTable);
|
||||||
FixupStructMember(Member, MemberTypeDef, TypeTable, Errors);
|
FixupStructMember(Member, MemberTypeDef, TypeTable, Errors);
|
||||||
s32 MemberSize = CalculateStructMemberSize(*Member, *MemberTypeDef);
|
s32 MemberSize = CalculateStructMemberSize(*Member, *MemberTypeDef);
|
||||||
BiggestMemberSize = GSMax(BiggestMemberSize, MemberSize);
|
BiggestMemberSize = GSMax(BiggestMemberSize, MemberSize);
|
||||||
|
|
582
meta/gs_meta.cpp
582
meta/gs_meta.cpp
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,100 @@
|
||||||
|
//
|
||||||
|
// File: gs_meta_code_generator.h
|
||||||
|
// Author: Peter Slattery
|
||||||
|
// Creation Date: 2020-01-20
|
||||||
|
//
|
||||||
|
#ifndef GS_META_CODE_GENERATOR_H
|
||||||
|
|
||||||
|
#include <gs_string.h>
|
||||||
|
#include <gs_string_builder.h>
|
||||||
|
|
||||||
|
enum gsm_code_gen_type
|
||||||
|
{
|
||||||
|
gsm_CodeGen_Enum,
|
||||||
|
gsm_CodeGen_Count,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct gsm_enum_generator
|
||||||
|
{
|
||||||
|
string Identifier;
|
||||||
|
string Prefix;
|
||||||
|
b32 EndsWithCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct gsm_code_generator
|
||||||
|
{
|
||||||
|
gsm_code_gen_type Type;
|
||||||
|
string_builder* Builder;
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
gsm_enum_generator Enum;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// ---------------
|
||||||
|
// Enum
|
||||||
|
// ---------------
|
||||||
|
|
||||||
|
internal gsm_code_generator
|
||||||
|
BeginEnumGeneration(string EnumIdentifier, string ValuePrefix, b32 StartsWithInvalid, b32 EndsWithCount)
|
||||||
|
{
|
||||||
|
gsm_code_generator Gen = {};
|
||||||
|
|
||||||
|
// TODO(Peter): TEMP!!
|
||||||
|
Gen.Builder = (string_builder*)malloc(sizeof(string_builder));
|
||||||
|
*Gen.Builder = {};
|
||||||
|
|
||||||
|
Gen.Type = gsm_CodeGen_Enum;
|
||||||
|
Gen.Enum.Identifier = EnumIdentifier;
|
||||||
|
Gen.Enum.Prefix = ValuePrefix;
|
||||||
|
Gen.Enum.EndsWithCount = EndsWithCount;
|
||||||
|
|
||||||
|
WriteF(Gen.Builder, "enum %S\n{\n", EnumIdentifier);
|
||||||
|
if (StartsWithInvalid)
|
||||||
|
{
|
||||||
|
WriteF(Gen.Builder, " %S_Invalid,\n", ValuePrefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Gen;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal gsm_code_generator
|
||||||
|
BeginEnumGeneration(char* EnumIdentifier, char* ValuePrefix, b32 StartsWithInvalid, b32 EndsWithCount)
|
||||||
|
{
|
||||||
|
return BeginEnumGeneration(MakeStringLiteral(EnumIdentifier),
|
||||||
|
MakeStringLiteral(ValuePrefix),
|
||||||
|
StartsWithInvalid,
|
||||||
|
EndsWithCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
AddEnumElement(gsm_code_generator* Gen, string ElementIdentifier)
|
||||||
|
{
|
||||||
|
// TODO(Peter): Support const expr defining enum values
|
||||||
|
Assert(Gen->Type == gsm_CodeGen_Enum);
|
||||||
|
WriteF(Gen->Builder, " %S_%S,\n", Gen->Enum.Prefix, ElementIdentifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
AddEnumElement(gsm_code_generator* Gen, char* ElementIdentifier)
|
||||||
|
{
|
||||||
|
AddEnumElement(Gen, MakeStringLiteral(ElementIdentifier));
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
FinishEnumGeneration(gsm_code_generator* Gen)
|
||||||
|
{
|
||||||
|
Assert(Gen->Type == gsm_CodeGen_Enum);
|
||||||
|
|
||||||
|
if (Gen->Enum.EndsWithCount)
|
||||||
|
{
|
||||||
|
WriteF(Gen->Builder, " %S_Count,\n", Gen->Enum.Prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteF(Gen->Builder, "};\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define GS_META_CODE_GENERATOR_H
|
||||||
|
#endif // GS_META_CODE_GENERATOR_H
|
|
@ -121,8 +121,7 @@ GetNextToken (tokenizer* Tokenizer)
|
||||||
Tokenizer->At += 2;
|
Tokenizer->At += 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
EatToNewLine(Tokenizer);
|
Tokenizer->At++;
|
||||||
EatWhitespace(Tokenizer);
|
|
||||||
}
|
}
|
||||||
EatWhitespace(Tokenizer);
|
EatWhitespace(Tokenizer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,15 +3,21 @@
|
||||||
// Author: Peter Slattery
|
// Author: Peter Slattery
|
||||||
// Creation Date: 2020-01-19
|
// Creation Date: 2020-01-19
|
||||||
//
|
//
|
||||||
|
// Usage
|
||||||
|
// TODO
|
||||||
|
//
|
||||||
|
//
|
||||||
#ifndef GS_META_TYPEINFO_GENERATOR_H
|
#ifndef GS_META_TYPEINFO_GENERATOR_H
|
||||||
|
|
||||||
#include <gs_language.h>
|
#include <gs_language.h>
|
||||||
#include <gs_string.h>
|
#include <gs_string.h>
|
||||||
#include <gs_string_builder.h>
|
#include <gs_string_builder.h>
|
||||||
|
#include "gs_meta_code_generator.h"
|
||||||
|
|
||||||
struct typeinfo_generator
|
struct typeinfo_generator
|
||||||
{
|
{
|
||||||
string_builder TypeList;
|
string_builder TypeListString;
|
||||||
|
gsm_code_generator TypeList;
|
||||||
string_builder StructMembers;
|
string_builder StructMembers;
|
||||||
string_builder TypeDefinitions;
|
string_builder TypeDefinitions;
|
||||||
|
|
||||||
|
@ -20,16 +26,17 @@ struct typeinfo_generator
|
||||||
b8* TypesGeneratedMask;
|
b8* TypesGeneratedMask;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define TypeHandleToIndex(handle) ((handle.BucketIndex * TYPE_TABLE_BUCKET_MAX) + handle.IndexInBucket)
|
||||||
internal typeinfo_generator
|
internal typeinfo_generator
|
||||||
InitTypeInfoGenerator(type_table TypeTable)
|
InitTypeInfoGenerator(type_table TypeTable)
|
||||||
{
|
{
|
||||||
typeinfo_generator Result = {};
|
typeinfo_generator Result = {};
|
||||||
|
|
||||||
Result.TypesMax = TypeTable.Types.Used;
|
Result.TypesMax = TypeTable.TypeBucketsCount * TYPE_TABLE_BUCKET_MAX;
|
||||||
Result.TypesGeneratedMask = (b8*)malloc(sizeof(b8) * Result.TypesMax);
|
Result.TypesGeneratedMask = (b8*)malloc(sizeof(b8) * Result.TypesMax);
|
||||||
GSZeroMemory((u8*)Result.TypesGeneratedMask, Result.TypesMax);
|
GSZeroMemory((u8*)Result.TypesGeneratedMask, Result.TypesMax);
|
||||||
|
|
||||||
WriteF(&Result.TypeList, "enum gsm_struct_type\n{\n");
|
Result.TypeList = BeginEnumGeneration("gsm_struct_type", "gsm_StructType", false, true);
|
||||||
|
|
||||||
WriteF(&Result.TypeDefinitions, "static gsm_struct_type_info StructTypes[] = {\n");
|
WriteF(&Result.TypeDefinitions, "static gsm_struct_type_info StructTypes[] = {\n");
|
||||||
return Result;
|
return Result;
|
||||||
|
@ -38,12 +45,12 @@ InitTypeInfoGenerator(type_table TypeTable)
|
||||||
internal void
|
internal void
|
||||||
FinishGeneratingTypes(typeinfo_generator* Generator)
|
FinishGeneratingTypes(typeinfo_generator* Generator)
|
||||||
{
|
{
|
||||||
WriteF(&Generator->TypeList, "gsm_StructTypeCount,\n};\n\n");
|
FinishEnumGeneration(&Generator->TypeList);
|
||||||
|
|
||||||
WriteF(&Generator->StructMembers, "\n");
|
WriteF(&Generator->StructMembers, "\n");
|
||||||
|
|
||||||
WriteF(&Generator->TypeDefinitions, "};\n");
|
WriteF(&Generator->TypeDefinitions, "};\n");
|
||||||
WriteF(&Generator->TypeDefinitions, "gsm_u32 StructTypesCount = %d;\n", Generator->GeneratedInfoTypesCount);
|
WriteF(&Generator->TypeDefinitions, "static gsm_u32 StructTypesCount = %d;\n", Generator->GeneratedInfoTypesCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
|
@ -71,9 +78,12 @@ GenerateStructMemberInfo (variable_decl* Member, string StructIdentifier, type_t
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
GenerateTypeInfo (type_definition* Type, u32 TypeIndex, type_table TypeTable, typeinfo_generator* Generator)
|
GenerateTypeInfo (type_definition* Type, type_table_handle TypeHandle, type_table TypeTable, typeinfo_generator* Generator)
|
||||||
{
|
{
|
||||||
Generator->TypesGeneratedMask[TypeIndex] = true;
|
// TODO(Peter):
|
||||||
|
// 1. allocate the full range of the types hash table
|
||||||
|
// 2. use bucketindex * bucket_max + indexinbucket to get the consecutive index
|
||||||
|
Generator->TypesGeneratedMask[TypeHandleToIndex(TypeHandle)] = true;
|
||||||
Generator->GeneratedInfoTypesCount++;
|
Generator->GeneratedInfoTypesCount++;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -81,8 +91,7 @@ GenerateTypeInfo (type_definition* Type, u32 TypeIndex, type_table TypeTable, ty
|
||||||
// type info for any member types. If it doesn't, it will screw
|
// type info for any member types. If it doesn't, it will screw
|
||||||
// up array ordering
|
// up array ordering
|
||||||
|
|
||||||
// Lookup Enum
|
AddEnumElement(&Generator->TypeList, Type->Identifier);
|
||||||
WriteF(&Generator->TypeList, "gsm_StructType_%S,\n", Type->Identifier);
|
|
||||||
|
|
||||||
// Type Info
|
// Type Info
|
||||||
WriteF(&Generator->TypeDefinitions, "{ gsm_StructType_%S, \"%S\", %d, %d, 0, 0, ",
|
WriteF(&Generator->TypeDefinitions, "{ gsm_StructType_%S, \"%S\", %d, %d, 0, 0, ",
|
||||||
|
@ -110,12 +119,18 @@ GenerateTypeInfo (type_definition* Type, u32 TypeIndex, type_table TypeTable, ty
|
||||||
for (u32 m = 0; m < Type->Struct.MemberDecls.Used; m++)
|
for (u32 m = 0; m < Type->Struct.MemberDecls.Used; m++)
|
||||||
{
|
{
|
||||||
variable_decl* Member = Type->Struct.MemberDecls.GetElementAtIndex(m);
|
variable_decl* Member = Type->Struct.MemberDecls.GetElementAtIndex(m);
|
||||||
type_definition* MemberType = TypeTable.Types.GetElementAtIndex(Member->TypeIndex);
|
type_definition* MemberType = GetTypeDefinition(Member->TypeHandle, TypeTable);
|
||||||
|
|
||||||
if (MemberType->Identifier.Length == 0) { continue; } // Don't gen info for anonymous struct and union members
|
if ((MemberType->Type == TypeDef_Struct ||
|
||||||
if (Generator->TypesGeneratedMask[Member->TypeIndex]) { continue; }
|
MemberType->Type == TypeDef_Union) &&
|
||||||
|
MemberType->Struct.IsAnonymous)
|
||||||
|
{
|
||||||
|
continue; // Don't gen info for anonymous struct and union members
|
||||||
|
}
|
||||||
|
|
||||||
GenerateTypeInfo(MemberType, Member->TypeIndex, TypeTable, Generator);
|
if (Generator->TypesGeneratedMask[TypeHandleToIndex(Member->TypeHandle)]) { continue; }
|
||||||
|
|
||||||
|
GenerateTypeInfo(MemberType, Member->TypeHandle, TypeTable, Generator);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -123,14 +138,14 @@ GenerateTypeInfo (type_definition* Type, u32 TypeIndex, type_table TypeTable, ty
|
||||||
for (u32 m = 0; m < Type->Struct.MemberDecls.Used; m++)
|
for (u32 m = 0; m < Type->Struct.MemberDecls.Used; m++)
|
||||||
{
|
{
|
||||||
variable_decl* Member = Type->Struct.MemberDecls.GetElementAtIndex(m);
|
variable_decl* Member = Type->Struct.MemberDecls.GetElementAtIndex(m);
|
||||||
type_definition* MemberType = TypeTable.Types.GetElementAtIndex(Member->TypeIndex);
|
type_definition* MemberType = GetTypeDefinition(Member->TypeHandle, TypeTable);
|
||||||
|
|
||||||
if (MemberType->Identifier.Length > 0)
|
if ((MemberType->Type != TypeDef_Struct && MemberType->Type != TypeDef_Union) ||
|
||||||
|
!MemberType->Struct.IsAnonymous)
|
||||||
{
|
{
|
||||||
GenerateStructMemberInfo(Member, Type->Identifier, TypeTable, Generator);
|
GenerateStructMemberInfo(Member, Type->Identifier, TypeTable, Generator);
|
||||||
}
|
}
|
||||||
else if (MemberType->Type == TypeDef_Struct ||
|
else if (MemberType->Struct.IsAnonymous)
|
||||||
MemberType->Type == TypeDef_Union)
|
|
||||||
{
|
{
|
||||||
// Anonymous Members
|
// Anonymous Members
|
||||||
for (u32 a = 0; a < MemberType->Struct.MemberDecls.Used; a++)
|
for (u32 a = 0; a < MemberType->Struct.MemberDecls.Used; a++)
|
||||||
|
@ -147,17 +162,29 @@ GenerateTypeInfo (type_definition* Type, u32 TypeIndex, type_table TypeTable, ty
|
||||||
internal void
|
internal void
|
||||||
GenerateFilteredTypeInfo (string MetaTagFilter, type_table TypeTable, typeinfo_generator* Generator)
|
GenerateFilteredTypeInfo (string MetaTagFilter, type_table TypeTable, typeinfo_generator* Generator)
|
||||||
{
|
{
|
||||||
for (u32 i = 0; i < TypeTable.Types.Used; i++)
|
for (u32 b = 0; b < TypeTable.TypeBucketsCount; b++)
|
||||||
{
|
{
|
||||||
if (Generator->TypesGeneratedMask[i])
|
type_table_hash_bucket Bucket = TypeTable.Types[b];
|
||||||
|
|
||||||
|
for (u32 i = 0; i < TYPE_TABLE_BUCKET_MAX; i++)
|
||||||
|
{
|
||||||
|
type_table_handle TypeHandle = {};
|
||||||
|
TypeHandle.BucketIndex = b;
|
||||||
|
TypeHandle.IndexInBucket = i;
|
||||||
|
|
||||||
|
if (Generator->TypesGeneratedMask[TypeHandleToIndex(TypeHandle)])
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
type_definition* Type = TypeTable.Types.GetElementAtIndex(i);
|
type_definition* Type = GetTypeDefinitionUnsafe(TypeHandle, TypeTable);
|
||||||
|
if (Type)
|
||||||
|
{
|
||||||
if (HasTag(MetaTagFilter, Type->MetaTags))
|
if (HasTag(MetaTagFilter, Type->MetaTags))
|
||||||
{
|
{
|
||||||
GenerateTypeInfo(Type, i, TypeTable, Generator);
|
GenerateTypeInfo(Type, TypeHandle, TypeTable, Generator);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ node_specification* NodeSpecifications = 0;
|
||||||
|
|
||||||
|
|
||||||
#include "assembly_parser.cpp"
|
#include "assembly_parser.cpp"
|
||||||
//#include "test_patterns.h"
|
#include "test_patterns.h"
|
||||||
|
|
||||||
// TODO(Peter): something we can do later is to remove all reliance on app_state and context
|
// TODO(Peter): something we can do later is to remove all reliance on app_state and context
|
||||||
// from foldhaus_pane.h. It should just emit lists of things that the app can iterate over and
|
// from foldhaus_pane.h. It should just emit lists of things that the app can iterate over and
|
||||||
|
|
|
@ -1,22 +1,5 @@
|
||||||
#define GENERATED_NODE_TYPES \
|
enum node_type
|
||||||
NodeType_MultiplyNodeProc, \
|
{
|
||||||
NodeType_AddNodeProc, \
|
NodeType_Count,
|
||||||
NodeType_FloatValueProc, \
|
};
|
||||||
NodeType_SolidColorProc, \
|
|
||||||
NodeType_VerticalColorFadeProc
|
|
||||||
|
|
||||||
#define GENERATED_NODE_SPECS \
|
|
||||||
{ NodeType_MultiplyNodeProc, "MultiplyNodeProc", 16, MemberList_multiply_data, 12, 3, 2, 1, false}, \
|
|
||||||
{ NodeType_AddNodeProc, "AddNodeProc", 11, MemberList_add_data, 48, 3, 2, 1, false}, \
|
|
||||||
{ NodeType_FloatValueProc, "FloatValueProc", 14, MemberList_float_value_data, 8, 2, 1, 1, false}, \
|
|
||||||
{ NodeType_SolidColorProc, "SolidColorProc", 14, MemberList_solid_color_data, 16, 1, 1, 0, true}, \
|
|
||||||
{ NodeType_VerticalColorFadeProc, "VerticalColorFadeProc", 21, MemberList_vertical_color_fade_data, 24, 3, 3, 0, true}
|
|
||||||
#define GENERATED_NODE_SPECS_COUNT 5
|
|
||||||
|
|
||||||
#define EVALUATE_GENERATED_NODES \
|
|
||||||
case NodeType_MultiplyNodeProc: { MultiplyNodeProc((multiply_data*)NodeData); } break; \
|
|
||||||
case NodeType_AddNodeProc: { AddNodeProc((add_data*)NodeData); } break; \
|
|
||||||
case NodeType_FloatValueProc: { FloatValueProc((float_value_data*)NodeData); } break; \
|
|
||||||
case NodeType_SolidColorProc: { SolidColorProc((solid_color_data*)NodeData, LEDs, Colors, LEDCount); } break; \
|
|
||||||
case NodeType_VerticalColorFadeProc: { VerticalColorFadeProc((vertical_color_fade_data*)NodeData, LEDs, Colors, LEDCount); } break; \
|
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ gsm_StructType_v4,
|
||||||
gsm_StructType_float,
|
gsm_StructType_float,
|
||||||
gsm_StructType_pixel,
|
gsm_StructType_pixel,
|
||||||
gsm_StructType_u8,
|
gsm_StructType_u8,
|
||||||
gsm_StructTypeCount,
|
gsm_StructType_Count,
|
||||||
};
|
};
|
||||||
|
|
||||||
static gsm_struct_member_type_info StructMembers_sin_wave_data[] = {
|
static gsm_struct_member_type_info StructMembers_sin_wave_data[] = {
|
||||||
|
@ -64,4 +64,4 @@ static gsm_struct_type_info StructTypes[] = {
|
||||||
{ gsm_StructType_pixel, "pixel", 5, 3, 0, 0, StructMembers_pixel, 2 },
|
{ gsm_StructType_pixel, "pixel", 5, 3, 0, 0, StructMembers_pixel, 2 },
|
||||||
{ gsm_StructType_u8, "u8", 2, 1, 0, 0, 0, 0 },
|
{ gsm_StructType_u8, "u8", 2, 1, 0, 0, 0, 0 },
|
||||||
};
|
};
|
||||||
gsm_u32 StructTypesCount = 10;
|
static gsm_u32 StructTypesCount = 10;
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
//
|
//
|
||||||
#ifndef TEST_PATTERNS_H
|
#ifndef TEST_PATTERNS_H
|
||||||
|
|
||||||
|
|
||||||
GSMetaTag(node_struct)
|
GSMetaTag(node_struct)
|
||||||
struct solid_color_data
|
struct solid_color_data
|
||||||
{
|
{
|
||||||
|
@ -17,20 +16,20 @@ struct solid_color_data
|
||||||
};
|
};
|
||||||
|
|
||||||
GSMetaTag(node_proc); // :TagParamsForNodeParamStructs
|
GSMetaTag(node_proc); // :TagParamsForNodeParamStructs
|
||||||
void SolidColorProc, solid_color_data* Data)
|
void SolidColorProc(solid_color_data* Data)
|
||||||
{
|
{
|
||||||
u8 R = (u8)GSClamp(0.f, (Data->Color.r * 255), 255.f);
|
u8 R = (u8)GSClamp(0.f, (Data->Color.r * 255), 255.f);
|
||||||
u8 G = (u8)GSClamp(0.f, (Data->Color.g * 255), 255.f);
|
u8 G = (u8)GSClamp(0.f, (Data->Color.g * 255), 255.f);
|
||||||
u8 B = (u8)GSClamp(0.f, (Data->Color.b * 255), 255.f);
|
u8 B = (u8)GSClamp(0.f, (Data->Color.b * 255), 255.f);
|
||||||
|
|
||||||
led* LED = Data->ResultLEDs;
|
led* LED = Data->Result.LEDs;
|
||||||
for (s32 l = 0; l < Data->ResultLEDCount; l++)
|
for (s32 l = 0; l < Data->Result.LEDCount; l++)
|
||||||
{
|
{
|
||||||
Assert(LED->Index >= 0 && LED->Index < Data->ResultLEDCount);
|
Assert(LED->Index >= 0 && LED->Index < Data->Result.LEDCount);
|
||||||
|
|
||||||
Data->ResultColors[LED->Index].R = R;
|
Data->Result.Colors[LED->Index].R = R;
|
||||||
Data->ResultColors[LED->Index].G = G;
|
Data->Result.Colors[LED->Index].G = G;
|
||||||
Data->ResultColors[LED->Index].B = B;
|
Data->Result.Colors[LED->Index].B = B;
|
||||||
LED++;
|
LED++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,7 +51,7 @@ struct vertical_color_fade_data
|
||||||
};
|
};
|
||||||
|
|
||||||
GSMetaTag(node_proc); // :TagParamsForNodeParamStructs
|
GSMetaTag(node_proc); // :TagParamsForNodeParamStructs
|
||||||
void VerticalColorFadeProc, vertical_color_fade_data* Data)
|
void VerticalColorFadeProc(vertical_color_fade_data* Data)
|
||||||
{
|
{
|
||||||
r32 R = (Data->Color.r * 255);
|
r32 R = (Data->Color.r * 255);
|
||||||
r32 G = (Data->Color.g * 255);
|
r32 G = (Data->Color.g * 255);
|
||||||
|
@ -60,17 +59,17 @@ void VerticalColorFadeProc, vertical_color_fade_data* Data)
|
||||||
|
|
||||||
r32 Range = Data->Max - Data->Min;
|
r32 Range = Data->Max - Data->Min;
|
||||||
|
|
||||||
led* LED = Data->ResultLEDs;
|
led* LED = Data->Result.LEDs;
|
||||||
for (s32 l = 0; l < Data->ResultLEDCount; l++)
|
for (s32 l = 0; l < Data->Result.LEDCount; l++)
|
||||||
{
|
{
|
||||||
Assert(LED->Index >= 0 && LED->Index < Data->ResultLEDCount);
|
Assert(LED->Index >= 0 && LED->Index < Data->Result.LEDCount);
|
||||||
|
|
||||||
r32 Amount = (LED->Position.y - Data->Min) / Range;
|
r32 Amount = (LED->Position.y - Data->Min) / Range;
|
||||||
Amount = GSClamp01(1.0f - Amount);
|
Amount = GSClamp01(1.0f - Amount);
|
||||||
|
|
||||||
Data->ResultColors[LED->Index].R = (u8)(R * Amount);
|
Data->Result.Colors[LED->Index].R = (u8)(R * Amount);
|
||||||
Data->ResultColors[LED->Index].G = (u8)(G * Amount);
|
Data->Result.Colors[LED->Index].G = (u8)(G * Amount);
|
||||||
Data->ResultColors[LED->Index].B = (u8)(B * Amount);
|
Data->Result.Colors[LED->Index].B = (u8)(B * Amount);
|
||||||
LED++;
|
LED++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,7 +104,7 @@ struct revolving_discs_data
|
||||||
};
|
};
|
||||||
|
|
||||||
GSMetaTag(node_proc); // :TagParamsForNodeParamStructs
|
GSMetaTag(node_proc); // :TagParamsForNodeParamStructs
|
||||||
void RevolvingDiscs, revolving_discs_data* Data)
|
void RevolvingDiscs(revolving_discs_data* Data)
|
||||||
{
|
{
|
||||||
DEBUG_TRACK_FUNCTION;
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
|
@ -125,8 +124,8 @@ void RevolvingDiscs, revolving_discs_data* Data)
|
||||||
r32 OuterRadiusSquared = Data->OuterRadius * Data->OuterRadius;
|
r32 OuterRadiusSquared = Data->OuterRadius * Data->OuterRadius;
|
||||||
r32 InnerRadiusSquared = Data->InnerRadius * Data->InnerRadius;
|
r32 InnerRadiusSquared = Data->InnerRadius * Data->InnerRadius;
|
||||||
|
|
||||||
led* LED = Data->ResultLEDs;
|
led* LED = Data->Result.LEDs;
|
||||||
for (s32 l = 0; l < Data->ResultLEDCount; l++)
|
for (s32 l = 0; l < Data->Result.LEDCount; l++)
|
||||||
{
|
{
|
||||||
v4 Position = LED->Position;
|
v4 Position = LED->Position;
|
||||||
|
|
||||||
|
@ -144,7 +143,7 @@ void RevolvingDiscs, revolving_discs_data* Data)
|
||||||
{
|
{
|
||||||
if (XOR(ToFrontDotNormal > 0, ToBackDotNormal > 0))
|
if (XOR(ToFrontDotNormal > 0, ToBackDotNormal > 0))
|
||||||
{
|
{
|
||||||
Data->ResultColors[LED->Index] = Color;
|
Data->Result.Colors[LED->Index] = Color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LED++;
|
LED++;
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <windowsx.h>
|
#include <windowsx.h>
|
||||||
#include <gl/gl.h>
|
#include <gl/gl.h>
|
||||||
|
|
||||||
|
#include "../meta/foldhaus_meta_include.h"
|
||||||
#include "foldhaus_platform.h"
|
#include "foldhaus_platform.h"
|
||||||
|
|
||||||
#include "gs_win32.cpp"
|
#include "gs_win32.cpp"
|
||||||
|
|
Loading…
Reference in New Issue