Compressing Type Info Generation

This commit is contained in:
Peter Slattery 2020-01-20 21:11:07 -08:00
parent d1353e52fa
commit af11a85e94
11 changed files with 927 additions and 282 deletions

View File

@ -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
//
// 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
#ifndef FOLDHAUS_META_CPP
#include "gs_meta.cpp"
#include "gs_meta_typeinfo_generator.h"
@ -23,25 +17,64 @@ int main(int ArgCount, char* Args[])
}
gs_meta_preprocessor Meta = PreprocessProgram(Args[1]);
s64 Cycles_Preprocess = GetWallClock();
typeinfo_generator TypeGenerator = InitTypeInfoGenerator(Meta.TypeTable);
GenerateFilteredTypeInfo(MakeStringLiteral("node_struct"), Meta.TypeTable, &TypeGenerator);
GenerateFilteredTypeInfo(MakeStringLiteral("gen_type_info"), Meta.TypeTable, &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");
if (TypeInfoH)
{
WriteStringBuilderToFile(TypeGenerator.TypeList, TypeInfoH);
WriteStringBuilderToFile(*TypeGenerator.TypeList.Builder, TypeInfoH);
WriteStringBuilderToFile(TypeGenerator.StructMembers, TypeInfoH);
WriteStringBuilderToFile(TypeGenerator.TypeDefinitions, 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);
//__debugbreak();
return 0;
}
#define FOLDHAUS_META_CPP
#endif // FOLDHAUS_META_CPP

View File

@ -16,10 +16,17 @@ enum type_definition_type
TypeDef_Union,
TypeDef_BasicType,
TypeDef_FunctionPointer,
TypeDef_Function,
TypeDef_Count,
};
struct type_table_handle
{
s32 BucketIndex;
u32 IndexInBucket;
};
struct meta_tag
{
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
// up on the first pass through. A TypeIndex of -1 means we need to fixup that
// type at a later time
s32 TypeIndex;
type_table_handle TypeHandle;
string Identifier;
b32 Pointer;
@ -45,6 +52,7 @@ struct variable_decl
struct struct_decl
{
b32 IsAnonymous;
// TODO(Peter): Lots of tiny arrays everywhere! Pull these into a central allocation
// buffer somewhere
// :SmallAllocationsAllOver
@ -53,11 +61,18 @@ struct struct_decl
struct function_pointer_decl
{
s32 ReturnTypeIndex;
type_table_handle ReturnTypeHandle;
// :SmallAllocationsAllOver
gs_bucket<variable_decl> Parameters;
};
struct function_decl
{
type_table_handle ReturnTypeHandle;
gs_bucket<variable_decl> Parameters;
// TODO(Peter): AST?
};
struct enum_decl
{
gs_bucket<string> Identifiers;
@ -80,13 +95,22 @@ struct type_definition
enum_decl Enum;
struct_decl Struct;
function_pointer_decl FunctionPtr;
function_decl Function;
};
b32 Pointer;
};
#define TYPE_TABLE_BUCKET_MAX 1024
struct type_table_hash_bucket
{
u32* Keys;
type_definition* Values;
};
struct type_table
{
gs_bucket<type_definition> Types;
type_table_hash_bucket* Types;
u32 TypeBucketsCount;
};
internal b32
@ -119,63 +143,190 @@ CopyMetaTagsAndClear(gs_bucket<token>* Source, gs_bucket<meta_tag>* Dest)
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)
{
type_definition UndeclaredTypeDef = {};
UndeclaredTypeDef.Identifier = Identifier;
UndeclaredTypeDef.Type = TypeDef_Unknown;
s32 TypeIndex = (s32)TypeTable->Types.PushElementOnBucket(UndeclaredTypeDef);
return TypeIndex;
type_table_handle Result = PushTypeOnHashTable(UndeclaredTypeDef, TypeTable);
return Result;
}
internal s32
GetIndexOfType (string Identifier, type_table TypeTable)
internal type_table_handle
GetTypeHandle (string Identifier, type_table TypeTable)
{
s32 Result = -1;
for (u32 i = 0; i < TypeTable.Types.Used; i++)
type_table_handle Result = InvalidTypeTableHandle;
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);
if (StringsEqual(Identifier, TypeDef->Identifier))
type_table_hash_bucket Bucket = TypeTable.Types[b];
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;
}
}
return Result;
}
internal s32
internal type_table_handle
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
// first anonymous struct/union member. So every anon struct/union gets its own
// typeef
if (ExistingUndeclaredTypeIndex < 0 || TypeDef.Identifier.Length == 0)
if (!TypeHandleIsValid(ExistingUndeclaredTypeHandle))
{
Index = TypeTable->Types.PushElementOnBucket(TypeDef);
Result = PushTypeOnHashTable(TypeDef, TypeTable);
}
else
{
Index = ExistingUndeclaredTypeIndex;
type_definition* ExistingTypeDef = TypeTable->Types.GetElementAtIndex(ExistingUndeclaredTypeIndex);
Result = ExistingUndeclaredTypeHandle;
type_definition* ExistingTypeDef = GetTypeDefinition(Result, *TypeTable);
Assert(ExistingTypeDef != 0);
*ExistingTypeDef = TypeDef;
}
return Index;
return Result;
}
internal s32
GetSizeOfType (s32 TypeIndex, type_table TypeTable)
GetSizeOfType (type_table_handle TypeHandle, type_table TypeTable)
{
s32 Result = -1;
Assert(TypeIndex >= 0 && (u32)TypeIndex < TypeTable.Types.Used);
type_definition* TypeDef = TypeTable.Types.GetElementAtIndex(TypeIndex);
Result = TypeDef->Size;
type_definition* TypeDef = GetTypeDefinition(TypeHandle, TypeTable);
if (TypeDef)
{
Result = TypeDef->Size;
}
return Result;
}
@ -183,14 +334,10 @@ internal s32
GetSizeOfType (string Identifier, type_table TypeTable)
{
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;
break;
}
Result = TypeDef->Size;
}
return Result;
}
@ -199,7 +346,7 @@ internal b32
VariableDeclsEqual (variable_decl A, variable_decl B)
{
b32 Result = false;
if (A.TypeIndex == B.TypeIndex &&
if (TypeHandlesEqual(A.TypeHandle, B.TypeHandle) &&
A.ArrayCount == B.ArrayCount &&
StringsEqual(A.Identifier, B.Identifier))
{
@ -236,51 +383,35 @@ StructOrUnionsEqual (type_definition A, type_definition B)
return Result;
}
internal s32
FindIndexOfMatchingType (type_definition Match, type_table TypeTable)
internal type_table_handle
FindHandleOfMatchingType (type_definition Match, type_table TypeTable)
{
s32 Result = -1;
for (u32 i = 0; i < TypeTable.Types.Used; i++)
type_table_handle Result = InvalidTypeTableHandle;
type_table_handle Handle = GetTypeHandle(Match.Identifier, TypeTable);
if (TypeHandleIsValid(Handle))
{
type_definition* TypeDef = TypeTable.Types.GetElementAtIndex(i);
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;
}
}
Result = Handle;
}
return Result;
}
internal void FixUpStructSize (s32 StructIndex, type_table TypeTable, errors* Errors);
internal void FixUpUnionSize (s32 UnionIndex, type_table TypeTable, errors* Errors);
internal void FixUpStructSize (type_table_handle TypeHandle, type_table TypeTable, errors* Errors);
internal void FixUpUnionSize (type_table_handle TypeHandle, type_table TypeTable, errors* Errors);
internal void
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
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
// 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)
{
FixUpStructSize(Member->TypeIndex, TypeTable, Errors);
FixUpStructSize(Member->TypeHandle, TypeTable, Errors);
}
else if (MemberTypeDef->Type == TypeDef_Union)
{
FixUpUnionSize(Member->TypeIndex, TypeTable, Errors);
FixUpUnionSize(Member->TypeHandle, TypeTable, Errors);
}
else
{
@ -353,9 +484,9 @@ FixupStructMember (variable_decl* Member, type_definition* MemberTypeDef, type_t
}
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);
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);
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);
u32 MemberSize = CalculateStructMemberSize(*Member, *MemberTypeDef);
SizeAcc += MemberSize;
}
@ -400,9 +529,9 @@ FixUpStructSize (s32 StructIndex, type_table TypeTable, errors* Errors)
}
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);
s32 BiggestMemberSize = 0;
@ -411,9 +540,9 @@ FixUpUnionSize (s32 UnionIndex, type_table TypeTable, errors* Errors)
variable_decl* Member = Union->Struct.MemberDecls.GetElementAtIndex(j);
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);
s32 MemberSize = CalculateStructMemberSize(*Member, *MemberTypeDef);
BiggestMemberSize = GSMax(BiggestMemberSize, MemberSize);

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -121,8 +121,7 @@ GetNextToken (tokenizer* Tokenizer)
Tokenizer->At += 2;
break;
}
EatToNewLine(Tokenizer);
EatWhitespace(Tokenizer);
Tokenizer->At++;
}
EatWhitespace(Tokenizer);
}

View File

@ -3,15 +3,21 @@
// Author: Peter Slattery
// Creation Date: 2020-01-19
//
// Usage
// TODO
//
//
#ifndef GS_META_TYPEINFO_GENERATOR_H
#include <gs_language.h>
#include <gs_string.h>
#include <gs_string_builder.h>
#include "gs_meta_code_generator.h"
struct typeinfo_generator
{
string_builder TypeList;
string_builder TypeListString;
gsm_code_generator TypeList;
string_builder StructMembers;
string_builder TypeDefinitions;
@ -20,16 +26,17 @@ struct typeinfo_generator
b8* TypesGeneratedMask;
};
#define TypeHandleToIndex(handle) ((handle.BucketIndex * TYPE_TABLE_BUCKET_MAX) + handle.IndexInBucket)
internal typeinfo_generator
InitTypeInfoGenerator(type_table TypeTable)
{
typeinfo_generator Result = {};
Result.TypesMax = TypeTable.Types.Used;
Result.TypesMax = TypeTable.TypeBucketsCount * TYPE_TABLE_BUCKET_MAX;
Result.TypesGeneratedMask = (b8*)malloc(sizeof(b8) * 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");
return Result;
@ -38,12 +45,12 @@ InitTypeInfoGenerator(type_table TypeTable)
internal void
FinishGeneratingTypes(typeinfo_generator* Generator)
{
WriteF(&Generator->TypeList, "gsm_StructTypeCount,\n};\n\n");
FinishEnumGeneration(&Generator->TypeList);
WriteF(&Generator->StructMembers, "\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
@ -71,9 +78,12 @@ GenerateStructMemberInfo (variable_decl* Member, string StructIdentifier, type_t
}
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++;
{
@ -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
// up array ordering
// Lookup Enum
WriteF(&Generator->TypeList, "gsm_StructType_%S,\n", Type->Identifier);
AddEnumElement(&Generator->TypeList, Type->Identifier);
// Type Info
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++)
{
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 (Generator->TypesGeneratedMask[Member->TypeIndex]) { continue; }
if ((MemberType->Type == TypeDef_Struct ||
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++)
{
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);
}
else if (MemberType->Type == TypeDef_Struct ||
MemberType->Type == TypeDef_Union)
else if (MemberType->Struct.IsAnonymous)
{
// Anonymous Members
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
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])
{
continue;
}
type_table_hash_bucket Bucket = TypeTable.Types[b];
type_definition* Type = TypeTable.Types.GetElementAtIndex(i);
if (HasTag(MetaTagFilter, Type->MetaTags))
for (u32 i = 0; i < TYPE_TABLE_BUCKET_MAX; i++)
{
GenerateTypeInfo(Type, i, TypeTable, Generator);
type_table_handle TypeHandle = {};
TypeHandle.BucketIndex = b;
TypeHandle.IndexInBucket = i;
if (Generator->TypesGeneratedMask[TypeHandleToIndex(TypeHandle)])
{
continue;
}
type_definition* Type = GetTypeDefinitionUnsafe(TypeHandle, TypeTable);
if (Type)
{
if (HasTag(MetaTagFilter, Type->MetaTags))
{
GenerateTypeInfo(Type, TypeHandle, TypeTable, Generator);
}
}
}
}
}

View File

@ -26,7 +26,7 @@ node_specification* NodeSpecifications = 0;
#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
// from foldhaus_pane.h. It should just emit lists of things that the app can iterate over and

View File

@ -1,22 +1,5 @@
#define GENERATED_NODE_TYPES \
NodeType_MultiplyNodeProc, \
NodeType_AddNodeProc, \
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; \
enum node_type
{
NodeType_Count,
};

View File

@ -1,16 +1,16 @@
enum gsm_struct_type
{
gsm_StructType_sin_wave_data,
gsm_StructType_r32,
gsm_StructType_multiply_patterns_data,
gsm_StructType_color_buffer,
gsm_StructType_led,
gsm_StructType_s32,
gsm_StructType_v4,
gsm_StructType_float,
gsm_StructType_pixel,
gsm_StructType_u8,
gsm_StructTypeCount,
gsm_StructType_sin_wave_data,
gsm_StructType_r32,
gsm_StructType_multiply_patterns_data,
gsm_StructType_color_buffer,
gsm_StructType_led,
gsm_StructType_s32,
gsm_StructType_v4,
gsm_StructType_float,
gsm_StructType_pixel,
gsm_StructType_u8,
gsm_StructType_Count,
};
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_u8, "u8", 2, 1, 0, 0, 0, 0 },
};
gsm_u32 StructTypesCount = 10;
static gsm_u32 StructTypesCount = 10;

View File

@ -5,7 +5,6 @@
//
#ifndef TEST_PATTERNS_H
GSMetaTag(node_struct)
struct solid_color_data
{
@ -17,20 +16,20 @@ struct solid_color_data
};
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 G = (u8)GSClamp(0.f, (Data->Color.g * 255), 255.f);
u8 B = (u8)GSClamp(0.f, (Data->Color.b * 255), 255.f);
led* LED = Data->ResultLEDs;
for (s32 l = 0; l < Data->ResultLEDCount; l++)
led* LED = Data->Result.LEDs;
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->ResultColors[LED->Index].G = G;
Data->ResultColors[LED->Index].B = B;
Data->Result.Colors[LED->Index].R = R;
Data->Result.Colors[LED->Index].G = G;
Data->Result.Colors[LED->Index].B = B;
LED++;
}
}
@ -52,7 +51,7 @@ struct vertical_color_fade_data
};
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 G = (Data->Color.g * 255);
@ -60,17 +59,17 @@ void VerticalColorFadeProc, vertical_color_fade_data* Data)
r32 Range = Data->Max - Data->Min;
led* LED = Data->ResultLEDs;
for (s32 l = 0; l < Data->ResultLEDCount; l++)
led* LED = Data->Result.LEDs;
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;
Amount = GSClamp01(1.0f - Amount);
Data->ResultColors[LED->Index].R = (u8)(R * Amount);
Data->ResultColors[LED->Index].G = (u8)(G * Amount);
Data->ResultColors[LED->Index].B = (u8)(B * Amount);
Data->Result.Colors[LED->Index].R = (u8)(R * Amount);
Data->Result.Colors[LED->Index].G = (u8)(G * Amount);
Data->Result.Colors[LED->Index].B = (u8)(B * Amount);
LED++;
}
}
@ -105,7 +104,7 @@ struct revolving_discs_data
};
GSMetaTag(node_proc); // :TagParamsForNodeParamStructs
void RevolvingDiscs, revolving_discs_data* Data)
void RevolvingDiscs(revolving_discs_data* Data)
{
DEBUG_TRACK_FUNCTION;
@ -125,8 +124,8 @@ void RevolvingDiscs, revolving_discs_data* Data)
r32 OuterRadiusSquared = Data->OuterRadius * Data->OuterRadius;
r32 InnerRadiusSquared = Data->InnerRadius * Data->InnerRadius;
led* LED = Data->ResultLEDs;
for (s32 l = 0; l < Data->ResultLEDCount; l++)
led* LED = Data->Result.LEDs;
for (s32 l = 0; l < Data->Result.LEDCount; l++)
{
v4 Position = LED->Position;
@ -144,7 +143,7 @@ void RevolvingDiscs, revolving_discs_data* Data)
{
if (XOR(ToFrontDotNormal > 0, ToBackDotNormal > 0))
{
Data->ResultColors[LED->Index] = Color;
Data->Result.Colors[LED->Index] = Color;
}
}
LED++;

View File

@ -11,6 +11,7 @@
#include <windowsx.h>
#include <gl/gl.h>
#include "../meta/foldhaus_meta_include.h"
#include "foldhaus_platform.h"
#include "gs_win32.cpp"