Got the meta layer generating files, and incorporated it into the system. Replaced old node meta stuff with the new.
This commit is contained in:
parent
22c6fe15b6
commit
7cdb300388
|
@ -27,6 +27,74 @@
|
|||
#include "gs_meta_error.h"
|
||||
#include "gs_meta_lexer.h"
|
||||
|
||||
struct error_buffer
|
||||
{
|
||||
char* Backbuffer;
|
||||
string* Contents;
|
||||
};
|
||||
|
||||
#define ERROR_MAX_LENGTH 256
|
||||
#define ERROR_BUFFER_SIZE 256
|
||||
struct errors
|
||||
{
|
||||
error_buffer* Buffers;
|
||||
u32 BuffersCount;
|
||||
u32 Used;
|
||||
};
|
||||
|
||||
internal void
|
||||
PushFError (errors* Errors, char* Format, ...)
|
||||
{
|
||||
if (Errors->Used >= (Errors->BuffersCount * ERROR_BUFFER_SIZE))
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
NewError->Length = PrintFArgsList(NewError->Memory, NewError->Max, Format, Args);
|
||||
va_end(Args);
|
||||
}
|
||||
|
||||
internal string*
|
||||
TakeError (errors* Errors)
|
||||
{
|
||||
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
|
||||
PrintAllErrors (errors Errors)
|
||||
{
|
||||
for (u32 i = 0; i < Errors.Used; i++)
|
||||
{
|
||||
u32 BufferIndex = i / ERROR_BUFFER_SIZE;
|
||||
u32 IndexInBuffer = i % ERROR_BUFFER_SIZE;
|
||||
string Error = Errors.Buffers[BufferIndex].Contents[IndexInBuffer];
|
||||
printf("%.*s\n", StringExpand(Error));
|
||||
}
|
||||
}
|
||||
|
||||
#include "foldhaus_meta_type_table.h"
|
||||
error_list GlobalErrorList = {};
|
||||
|
||||
|
@ -57,6 +125,8 @@ struct token_iter
|
|||
#define TOKEN_ITER_SNAPSHOTS_MAX 64
|
||||
u32 SnapshotsUsed;
|
||||
u32 Snapshots[TOKEN_ITER_SNAPSHOTS_MAX];
|
||||
|
||||
errors* Errors;
|
||||
};
|
||||
|
||||
internal token*
|
||||
|
@ -308,7 +378,7 @@ GetSecondsElapsed(s64 StartCycles, s64 EndCycles)
|
|||
}
|
||||
|
||||
internal void
|
||||
AddFileToSource(string RelativePath, gs_bucket<source_code_file>* SourceFiles)
|
||||
AddFileToSource(string RelativePath, gs_bucket<source_code_file>* SourceFiles, errors* Errors)
|
||||
{
|
||||
source_code_file File = {0};
|
||||
|
||||
|
@ -328,7 +398,7 @@ AddFileToSource(string RelativePath, gs_bucket<source_code_file>* SourceFiles)
|
|||
}
|
||||
else
|
||||
{
|
||||
printf("Error: Could not load file %.*s\n", StringExpand(RelativePath));
|
||||
PushFError(Errors, "Error: Could not load file %S\n", RelativePath);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -448,7 +518,6 @@ LongInt (token_iter* Iter, s32* TypeIndexOut, type_table TypeTable)
|
|||
if (TokenAtEquals(Iter, "unsigned") ||
|
||||
TokenAtEquals(Iter, "signed"))
|
||||
{
|
||||
Result = true;
|
||||
}
|
||||
|
||||
if (TokenAtEquals(Iter, "long"))
|
||||
|
@ -598,12 +667,8 @@ ParseType(token_iter* Iter, type_table* TypeTable, s32* TypeIndexOut)
|
|||
{
|
||||
NextToken(Iter);
|
||||
Result = true;
|
||||
}
|
||||
else if (ShortInt(Iter, TypeIndexOut, *TypeTable))
|
||||
{
|
||||
Result = true;
|
||||
}
|
||||
else if (Int(Iter, TypeIndexOut, *TypeTable))
|
||||
else if (LongLongInt(Iter, TypeIndexOut, *TypeTable))
|
||||
{
|
||||
Result = true;
|
||||
}
|
||||
|
@ -611,7 +676,11 @@ ParseType(token_iter* Iter, type_table* TypeTable, s32* TypeIndexOut)
|
|||
{
|
||||
Result = true;
|
||||
}
|
||||
else if (LongLongInt(Iter, TypeIndexOut, *TypeTable))
|
||||
else if (ShortInt(Iter, TypeIndexOut, *TypeTable))
|
||||
{
|
||||
Result = true;
|
||||
}
|
||||
else if (Int(Iter, TypeIndexOut, *TypeTable))
|
||||
{
|
||||
Result = true;
|
||||
}
|
||||
|
@ -883,6 +952,7 @@ ParseFunctionDeclaration (token_iter* Iter, token* Identifier, gs_bucket<token*>
|
|||
CopyMetaTagsAndClear(TagList, &FunctionPtr.MetaTags);
|
||||
FunctionPtr.Type = TypeDef_FunctionPointer;
|
||||
FunctionPtr.Pointer = true;
|
||||
FunctionPtr.FunctionPtr = {};
|
||||
FunctionPtr.FunctionPtr.ReturnTypeIndex = ReturnTypeIndex;
|
||||
|
||||
*Identifier = *Iter->TokenAt;
|
||||
|
@ -959,13 +1029,14 @@ ParseTypedef(token_iter* Iter, gs_bucket<token*>* TagList, type_table* TypeTable
|
|||
}
|
||||
else
|
||||
{
|
||||
printf("unhandled typedef ");
|
||||
string* Error = TakeError(Iter->Errors);
|
||||
PrintF(Error, "unhandled typedef ");
|
||||
while (!TokenAtEquals(Iter, ";"))
|
||||
{
|
||||
printf("%.*s ", StringExpand(Iter->TokenAt->Text));
|
||||
PrintF(Error, "%S ", Iter->TokenAt->Text);
|
||||
NextToken(Iter);
|
||||
}
|
||||
printf("\n");
|
||||
PrintF(Error, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -974,6 +1045,91 @@ ParseTypedef(token_iter* Iter, gs_bucket<token*>* TagList, type_table* TypeTable
|
|||
return Result;
|
||||
}
|
||||
|
||||
internal b32
|
||||
ParseEnum (token_iter* Iter, gs_bucket<token*>* TagList, type_table* TypeTable)
|
||||
{
|
||||
b32 Result = false;
|
||||
PushSnapshot(Iter);
|
||||
|
||||
if (TokenAtEquals(Iter, "enum"))
|
||||
{
|
||||
if (Iter->TokenAt->Type == Token_Identifier)
|
||||
{
|
||||
type_definition EnumDecl = {};
|
||||
EnumDecl.Identifier = Iter->TokenAt->Text;
|
||||
EnumDecl.Size = sizeof(u32);
|
||||
CopyMetaTagsAndClear(TagList, &EnumDecl.MetaTags);
|
||||
EnumDecl.Type = TypeDef_Enum;
|
||||
|
||||
NextToken(Iter);
|
||||
|
||||
if (TokenAtEquals(Iter, "{"))
|
||||
{
|
||||
u32 EnumeratorAcc = 0;
|
||||
|
||||
while (!StringsEqual(Iter->TokenAt->Text, MakeStringLiteral("}")))
|
||||
{
|
||||
if (Iter->TokenAt->Type == Token_Identifier)
|
||||
{
|
||||
string EnumeratorIdentifier = Iter->TokenAt->Text;
|
||||
NextToken(Iter);
|
||||
|
||||
if (TokenAtEquals(Iter, "="))
|
||||
{
|
||||
// TODO(Peter): TempValue is just here until we handle all
|
||||
// const expr that could define an enum value. Its there so
|
||||
// that if the first token of an expression is a number,
|
||||
// we can avoid using anything from the expression.
|
||||
u32 TempValue = EnumeratorAcc;
|
||||
if (Iter->TokenAt->Type == Token_Number)
|
||||
{
|
||||
parse_result ParsedExpr = ParseSignedInt(StringExpand(Iter->TokenAt->Text));
|
||||
TempValue = ParsedExpr.SignedIntValue;
|
||||
NextToken(Iter);
|
||||
}
|
||||
|
||||
// TODO(Peter): Handle setting enums equal to other kinds
|
||||
// of const exprs.
|
||||
// We're skipping a whole bunch of stuff now
|
||||
while (!(StringsEqual(Iter->TokenAt->Text, MakeStringLiteral(",")) ||
|
||||
StringsEqual(Iter->TokenAt->Text, MakeStringLiteral("}"))))
|
||||
{
|
||||
TempValue = EnumeratorAcc;
|
||||
NextToken(Iter);
|
||||
}
|
||||
|
||||
EnumeratorAcc = TempValue;
|
||||
}
|
||||
|
||||
s32 EnumeratorValue = EnumeratorAcc++;
|
||||
if (TokenAtEquals(Iter, ",") ||
|
||||
StringsEqual(Iter->TokenAt->Text, MakeStringLiteral("}")))
|
||||
{
|
||||
EnumDecl.Enum.Identifiers.PushElementOnBucket(EnumeratorIdentifier);
|
||||
EnumDecl.Enum.Values.PushElementOnBucket(EnumeratorValue);
|
||||
}
|
||||
else if (!StringsEqual(Iter->TokenAt->Text, MakeStringLiteral("}")))
|
||||
{
|
||||
Result = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (TokenAtEquals(Iter, "}") &&
|
||||
TokenAtEquals(Iter, ";"))
|
||||
{
|
||||
PushTypeDefOnTypeTable(EnumDecl, TypeTable);
|
||||
Result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ApplySnapshotIfNotParsedAndPop(Result, Iter);
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal void
|
||||
PrintIndent (u32 Indent)
|
||||
{
|
||||
|
@ -1072,6 +1228,159 @@ PrintFunctionPtrDecl (type_definition* FnPtrDecl, type_table TypeTable)
|
|||
printf(");");
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Step 1: Get All Tokens, for every file
|
||||
// Step 2: Identify all preprocessor directives
|
||||
// Step 3: Apply Preprocessor Directives && Generate Code
|
||||
|
@ -1087,29 +1396,31 @@ int main(int ArgCount, char** ArgV)
|
|||
return 0;
|
||||
}
|
||||
|
||||
errors Errors = {0};
|
||||
|
||||
memory_arena SourceFileArena = {};
|
||||
gs_bucket<source_code_file> SourceFiles;
|
||||
gs_bucket<token> Tokens;
|
||||
|
||||
string_builder NodeTypeBlock = {};
|
||||
Write(MakeStringLiteral("enum node_type\n{\n"), &NodeTypeBlock);
|
||||
WriteF(&NodeTypeBlock, "enum node_type\n{\n");
|
||||
|
||||
string_builder NodeMembersBlock = {};
|
||||
|
||||
string_builder NodeSpecificationsBlock = {};
|
||||
Write(MakeStringLiteral("node_specification NodeSpecifications[] = {\n"), &NodeSpecificationsBlock);
|
||||
WriteF(&NodeSpecificationsBlock, "node_specification NodeSpecifications[] = {\n");
|
||||
|
||||
string_builder CallNodeProcBlock = {};
|
||||
Write(MakeStringLiteral("internal void CallNodeProc(u32 SpecificationIndex, u8* Data, led* LEDs, s32 LEDsCount, r32 DeltaTime)\n{\n"), &CallNodeProcBlock);
|
||||
Write(MakeStringLiteral("node_specification Spec = NodeSpecifications[SpecificationIndex];\n"), &CallNodeProcBlock);
|
||||
Write(MakeStringLiteral("switch (Spec.Type)\n{\n"), &CallNodeProcBlock);
|
||||
WriteF(&CallNodeProcBlock, "internal void CallNodeProc(u32 SpecificationIndex, u8* Data, led* LEDs, s32 LEDsCount, r32 DeltaTime)\n{\n");
|
||||
WriteF(&CallNodeProcBlock, "node_specification Spec = NodeSpecifications[SpecificationIndex];\n");
|
||||
WriteF(&CallNodeProcBlock, "switch (Spec.Type)\n{\n");
|
||||
|
||||
string CurrentWorkingDirectory = MakeString((char*)malloc(1024), 0, 1024);
|
||||
|
||||
if (ArgCount > 1)
|
||||
{
|
||||
string RootFile = MakeString(ArgV[1]);
|
||||
AddFileToSource(RootFile, &SourceFiles);
|
||||
AddFileToSource(RootFile, &SourceFiles, &Errors);
|
||||
|
||||
s32 LastSlash = ReverseSearchForCharInSet(RootFile, "\\/");
|
||||
Assert(LastSlash > 0);
|
||||
|
@ -1137,6 +1448,7 @@ int main(int ArgCount, char** ArgV)
|
|||
Iter.LastToken = File->LastTokenIndex;
|
||||
Iter.TokenAtIndex = Iter.FirstToken;
|
||||
Iter.TokenAt = Tokens.GetElementAtIndex(Iter.TokenAtIndex);
|
||||
Iter.Errors = &Errors;
|
||||
|
||||
while (Iter.TokenAtIndex < Iter.LastToken)
|
||||
{
|
||||
|
@ -1170,7 +1482,7 @@ int main(int ArgCount, char** ArgV)
|
|||
ParseSuccess = true;
|
||||
if (!FileAlreadyInSource(TempFilePath, SourceFiles))
|
||||
{
|
||||
AddFileToSource(TempFilePath, &SourceFiles);
|
||||
AddFileToSource(TempFilePath, &SourceFiles, &Errors);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1178,6 +1490,10 @@ int main(int ArgCount, char** ArgV)
|
|||
{
|
||||
ParseSuccess = true;
|
||||
}
|
||||
else if (ParseEnum(&Iter, &TagList, &TypeTable))
|
||||
{
|
||||
ParseSuccess = true;
|
||||
}
|
||||
else if (ParseStruct(&Iter, &TypeIndex, &TagList, &TypeTable))
|
||||
{
|
||||
ParseSuccess = true;
|
||||
|
@ -1200,48 +1516,29 @@ int main(int ArgCount, char** ArgV)
|
|||
type_definition* TypeDef = TypeTable.Types.GetElementAtIndex(i);
|
||||
if (TypeDef->Type == TypeDef_Struct)
|
||||
{
|
||||
FixUpStructSize(i, TypeTable);
|
||||
FixUpStructSize(i, TypeTable, &Errors);
|
||||
}
|
||||
else if (TypeDef->Type == TypeDef_Union)
|
||||
{
|
||||
FixUpUnionSize(i, TypeTable);
|
||||
FixUpUnionSize(i, TypeTable, &Errors);
|
||||
}
|
||||
}
|
||||
|
||||
// Print All Structs
|
||||
for (u32 i = 0; i < TypeTable.Types.Used; i++)
|
||||
{
|
||||
type_definition* TypeDef = TypeTable.Types.GetElementAtIndex(i);
|
||||
#if 0
|
||||
if ((TypeDef->Type == TypeDef_Struct || TypeDef->Type == TypeDef_Union) && TypeDef->Identifier.Length > 0)
|
||||
{
|
||||
PrintStructDecl(TypeDef, TypeTable);
|
||||
printf("\n\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (TypeDef->Type == TypeDef_FunctionPointer)
|
||||
{
|
||||
PrintFunctionPtrDecl(TypeDef, TypeTable);
|
||||
printf("\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
s64 Cycles_Preprocess = GetWallClock();
|
||||
|
||||
PrintAllErrors(Errors);
|
||||
|
||||
MakeStringBuffer(Buffer, 256);
|
||||
|
||||
// Close Types Block - overwrite the last comma and '\' newline character with newlines.
|
||||
Write(MakeStringLiteral("NodeType_Count,\n};\n\n"), &NodeTypeBlock);
|
||||
WriteF(&NodeTypeBlock, "NodeType_Count,\n};\n\n");
|
||||
|
||||
// Close Specifications Block
|
||||
Write(MakeStringLiteral("};\n"), &NodeSpecificationsBlock);
|
||||
PrintF(&Buffer, "s32 NodeSpecificationsCount = %d;\n\n", NodeProcCount);
|
||||
Write(Buffer, &NodeSpecificationsBlock);
|
||||
WriteF(&NodeSpecificationsBlock, "};\n");
|
||||
WriteF(&NodeSpecificationsBlock, "s32 NodeSpecificationsCount = %d;\n\n", NodeProcCount);
|
||||
|
||||
// Close Call Node Proc Block
|
||||
Write(MakeStringLiteral("}\n}\n"), &CallNodeProcBlock);
|
||||
WriteF(&CallNodeProcBlock, "}\n}\n");
|
||||
|
||||
FILE* NodeGeneratedCPP = fopen("C:\\projects\\foldhaus\\src\\generated\\foldhaus_nodes_generated.cpp", "w");
|
||||
if (NodeGeneratedCPP)
|
||||
|
@ -1253,47 +1550,24 @@ int main(int ArgCount, char** ArgV)
|
|||
fclose(NodeGeneratedCPP);
|
||||
}
|
||||
|
||||
typeinfo_generator TypeGenerator = InitTypeInfoGenerator(TypeTable);
|
||||
GenerateFilteredTypeInfo(MakeStringLiteral("node_struct"), TypeTable, &TypeGenerator);
|
||||
FinishGeneratingTypes(&TypeGenerator);
|
||||
FILE* TypeInfoH = fopen("C:\\projects\\foldhaus\\src\\generated\\gs_meta_generated_typeinfo.h", "w");
|
||||
if (TypeInfoH)
|
||||
{
|
||||
WriteStringBuilderToFile(TypeGenerator.TypeList, TypeInfoH);
|
||||
WriteStringBuilderToFile(TypeGenerator.StructMembers, TypeInfoH);
|
||||
WriteStringBuilderToFile(TypeGenerator.TypeDefinitions, TypeInfoH);
|
||||
fclose(NodeGeneratedCPP);
|
||||
}
|
||||
|
||||
PrintErrorList(GlobalErrorList);
|
||||
|
||||
s64 TotalEnd = GetWallClock();
|
||||
|
||||
r32 TotalTime = GetSecondsElapsed(TotalStart, TotalEnd);
|
||||
|
||||
printf("Metaprogram Preproc Time: %.*f sec\n", 6, TotalTime);
|
||||
|
||||
#if 0
|
||||
for (u32 i = 0; i < Structs.Used; i++)
|
||||
{
|
||||
seen_node_struct* Struct = Structs.GetElementAtIndex(i);
|
||||
|
||||
#ifdef PRINT_ALL_INFO
|
||||
printf("\n");
|
||||
for (u32 j = 0; j < Struct->MetaTags.Used; j++)
|
||||
{
|
||||
token* MetaTag = Struct->MetaTags.GetElementAtIndex(j);
|
||||
printf("GSMetaTag(%.*s)\n", StringExpand(MetaTag->Text));
|
||||
}
|
||||
#endif
|
||||
|
||||
printf("struct %.*s\n", StringExpand(Struct->Name));
|
||||
|
||||
#ifdef PRINT_ALL_INFO
|
||||
for (u32 j = 0; j < Struct->MemberDecls.Used; j++)
|
||||
{
|
||||
struct_member_decl* Member = Struct->MemberDecls.GetElementAtIndex(j);
|
||||
|
||||
for (u32 k = 0; k < Member->MetaTags.Used; k++)
|
||||
{
|
||||
token* MetaTag = Member->MetaTags.GetElementAtIndex(k);
|
||||
printf(" GSMetaTag(%.*s)\n", StringExpand(MetaTag->Text));
|
||||
}
|
||||
|
||||
printf(" %.*s %.*s\n", StringExpand(Member->Type), StringExpand(Member->Identifier));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
__debugbreak();
|
||||
//__debugbreak();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
//
|
||||
// File: foldhaus_meta_include.h
|
||||
// Author: Peter Slattery
|
||||
// Creation Date: 2020-01-19
|
||||
//
|
||||
#ifndef FOLDHAUS_META_INCLUDE_H
|
||||
|
||||
//
|
||||
// NOTE
|
||||
// Include this file FIRST in any application utilizing the Foldhaus Meta system
|
||||
// Include the generated files you wish to take advantage of at convenient locations
|
||||
// in your application
|
||||
//
|
||||
|
||||
typedef unsigned int gsm_u32;
|
||||
typedef unsigned long long int gsm_u64;
|
||||
|
||||
#define GSMetaTag(ident, ...)
|
||||
|
||||
struct gsm_meta_tag
|
||||
{
|
||||
char* Tag;
|
||||
gsm_u32 TagLength;
|
||||
};
|
||||
|
||||
struct gsm_struct_member_type_info
|
||||
{
|
||||
char* Identifier;
|
||||
gsm_u32 IdentifierLength;
|
||||
gsm_u64 Offset;
|
||||
};
|
||||
|
||||
struct gsm_struct_type_info
|
||||
{
|
||||
gsm_u32 Type;
|
||||
char* Identifier;
|
||||
gsm_u32 IdentifierLength;
|
||||
|
||||
gsm_u32 Size;
|
||||
|
||||
gsm_meta_tag* Tags;
|
||||
gsm_u32 TagsCount;
|
||||
|
||||
gsm_struct_member_type_info* Members;
|
||||
gsm_u32 MembersCount;
|
||||
};
|
||||
|
||||
|
||||
#define FOLDHAUS_META_INCLUDE_H
|
||||
#endif // FOLDHAUS_META_INCLUDE_H
|
|
@ -11,6 +11,7 @@ enum type_definition_type
|
|||
|
||||
// NOTE(Peter): tokens with this type require fixup later
|
||||
TypeDef_Unknown,
|
||||
TypeDef_Enum,
|
||||
TypeDef_Struct,
|
||||
TypeDef_Union,
|
||||
TypeDef_BasicType,
|
||||
|
@ -57,6 +58,15 @@ struct function_pointer_decl
|
|||
gs_bucket<variable_decl> Parameters;
|
||||
};
|
||||
|
||||
struct enum_decl
|
||||
{
|
||||
gs_bucket<string> Identifiers;
|
||||
|
||||
// TODO(Peter): I suppose there are ways to make an enum a 64 bit number
|
||||
// for values. Probably need to handle that at some point
|
||||
gs_bucket<u32> Values;
|
||||
};
|
||||
|
||||
struct type_definition
|
||||
{
|
||||
string Identifier;
|
||||
|
@ -67,6 +77,7 @@ struct type_definition
|
|||
type_definition_type Type;
|
||||
union
|
||||
{
|
||||
enum_decl Enum;
|
||||
struct_decl Struct;
|
||||
function_pointer_decl FunctionPtr;
|
||||
};
|
||||
|
@ -78,17 +89,19 @@ struct type_table
|
|||
gs_bucket<type_definition> Types;
|
||||
};
|
||||
|
||||
internal void
|
||||
MetaTagBreakpoint(gs_bucket<meta_tag> Tags)
|
||||
internal b32
|
||||
HasTag(string Needle, gs_bucket<meta_tag> Tags)
|
||||
{
|
||||
b32 Result = false;
|
||||
for (u32 i = 0; i < Tags.Used; i++)
|
||||
{
|
||||
meta_tag* Tag = Tags.GetElementAtIndex(i);
|
||||
if (StringsEqual(Tag->Identifier, MakeStringLiteral("breakpoint")))
|
||||
if (StringsEqual(Tag->Identifier, Needle))
|
||||
{
|
||||
__debugbreak();
|
||||
Result = true;
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal void
|
||||
|
@ -136,7 +149,11 @@ PushTypeDefOnTypeTable(type_definition TypeDef, type_table* TypeTable)
|
|||
s32 Index = -1;
|
||||
|
||||
s32 ExistingUndeclaredTypeIndex = GetIndexOfType(TypeDef.Identifier, *TypeTable);
|
||||
if (ExistingUndeclaredTypeIndex < 0)
|
||||
|
||||
// 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)
|
||||
{
|
||||
Index = TypeTable->Types.PushElementOnBucket(TypeDef);
|
||||
}
|
||||
|
@ -245,8 +262,8 @@ FindIndexOfMatchingType (type_definition Match, type_table TypeTable)
|
|||
return Result;
|
||||
}
|
||||
|
||||
internal void FixUpStructSize (s32 StructIndex, type_table TypeTable);
|
||||
internal void FixUpUnionSize (s32 UnionIndex, type_table TypeTable);
|
||||
internal void FixUpStructSize (s32 StructIndex, type_table TypeTable, errors* Errors);
|
||||
internal void FixUpUnionSize (s32 UnionIndex, type_table TypeTable, errors* Errors);
|
||||
|
||||
internal void
|
||||
FixupMemberType (variable_decl* Member, type_table TypeTable)
|
||||
|
@ -279,12 +296,69 @@ CalculateStructMemberSize (variable_decl Member, type_definition MemberType)
|
|||
}
|
||||
|
||||
internal void
|
||||
FixUpStructSize (s32 StructIndex, type_table TypeTable)
|
||||
FixupStructMember (variable_decl* Member, type_definition* MemberTypeDef, type_table TypeTable, errors* Errors)
|
||||
{
|
||||
// NOTE(Peter): There are a lot of cases where struct members which are pointers
|
||||
// to other structs cause interesting behavior here.
|
||||
// For example:
|
||||
// struct foo { foo* Next; }
|
||||
// could cause infinite loops if we try and fixup all structs with a size of 0
|
||||
// which would happen in this case, because we wouldn't have parsed foo's size
|
||||
// yet, but would begin fixing up foo because of the type of Next
|
||||
// Another example:
|
||||
// typedef struct bar bar;
|
||||
// struct foo { bar* Bar; }
|
||||
// struct bar { foo* Foo; }
|
||||
// causes the exact same problem, but we cant detect it by just excluding
|
||||
// fixing up StructIndex recursively.
|
||||
//
|
||||
// TL;DR
|
||||
// The solution I've chosen to go with is just exclude all pointer members from
|
||||
// causing recursive fixups. Those types should be fixed up at some point in the
|
||||
// process, and we already know how big a pointer is in memory, no matter the type
|
||||
if (!Member->Pointer)
|
||||
{
|
||||
if (MemberTypeDef->Size == 0)
|
||||
{
|
||||
if (MemberTypeDef->Type == TypeDef_Struct)
|
||||
{
|
||||
FixUpStructSize(Member->TypeIndex, TypeTable, Errors);
|
||||
}
|
||||
else if (MemberTypeDef->Type == TypeDef_Union)
|
||||
{
|
||||
FixUpUnionSize(Member->TypeIndex, TypeTable, Errors);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MemberTypeDef->Type == TypeDef_Unknown)
|
||||
{
|
||||
PushFError(Errors, "Union Error: TypeDef Unknown: %S\n", MemberTypeDef->Identifier);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO(Peter): We don't parse all types yet, so for now, this is just an alert,
|
||||
// not an assert;
|
||||
#if 0
|
||||
InvalidCodePath;
|
||||
#else
|
||||
PushFError(Errors, "Struct Error: TypeDef Size = 0. %S\n", MemberTypeDef->Identifier);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
FixUpStructSize (s32 StructIndex, type_table TypeTable, errors* Errors)
|
||||
{
|
||||
type_definition* Struct = TypeTable.Types.GetElementAtIndex(StructIndex);
|
||||
Assert(Struct->Type == TypeDef_Struct);
|
||||
|
||||
MetaTagBreakpoint(Struct->MetaTags);
|
||||
if (HasTag(MakeStringLiteral("breakpoint"), Struct->MetaTags))
|
||||
{
|
||||
__debugbreak();
|
||||
}
|
||||
|
||||
s32 SizeAcc = 0;
|
||||
for (u32 j = 0; j < Struct->Struct.MemberDecls.Used; j++)
|
||||
|
@ -292,52 +366,12 @@ FixUpStructSize (s32 StructIndex, type_table TypeTable)
|
|||
variable_decl* Member = Struct->Struct.MemberDecls.GetElementAtIndex(j);
|
||||
FixupMemberType(Member, TypeTable);
|
||||
|
||||
// TODO(Peter):
|
||||
if (Member->TypeIndex >= 0)
|
||||
{
|
||||
type_definition* MemberTypeDef = TypeTable.Types.GetElementAtIndex(Member->TypeIndex);
|
||||
|
||||
// NOTE(Peter): There are a lot of cases where struct members which are pointers
|
||||
// to other structs cause interesting behavior here.
|
||||
// For example:
|
||||
// struct foo { foo* Next; }
|
||||
// could cause infinite loops if we try and fixup all structs with a size of 0
|
||||
// which would happen in this case, because we wouldn't have parsed foo's size
|
||||
// yet, but would begin fixing up foo because of the type of Next
|
||||
// Another example:
|
||||
// typedef struct bar bar;
|
||||
// struct foo { bar* Bar; }
|
||||
// struct bar { foo* Foo; }
|
||||
// causes the exact same problem, but we cant detect it by just excluding
|
||||
// fixing up StructIndex recursively.
|
||||
//
|
||||
// TL;DR
|
||||
// The solution I've chosen to go with is just exclude all pointer members from
|
||||
// causing recursive fixups. Those types should be fixed up at some point in the
|
||||
// process, and we already know how big a pointer is in memory, no matter the type
|
||||
if (!Member->Pointer)
|
||||
{
|
||||
if (MemberTypeDef->Size == 0)
|
||||
{
|
||||
if (MemberTypeDef->Type == TypeDef_Struct)
|
||||
{
|
||||
FixUpStructSize(Member->TypeIndex, TypeTable);
|
||||
}
|
||||
else if (MemberTypeDef->Type == TypeDef_Union)
|
||||
{
|
||||
FixUpUnionSize(Member->TypeIndex, TypeTable);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO(Peter): We don't parse all types yet, so for now, this is just an alert,
|
||||
// not an assert;
|
||||
#if 0
|
||||
InvalidCodePath;
|
||||
#else
|
||||
printf("Struct Error: TypeDef Size = 0. %.*s\n", StringExpand(MemberTypeDef->Identifier));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
FixupStructMember(Member, MemberTypeDef, TypeTable, Errors);
|
||||
|
||||
u32 MemberSize = CalculateStructMemberSize(*Member, *MemberTypeDef);
|
||||
SizeAcc += MemberSize;
|
||||
|
@ -346,23 +380,25 @@ FixUpStructSize (s32 StructIndex, type_table TypeTable)
|
|||
|
||||
Struct->Size = SizeAcc;
|
||||
|
||||
// NOTE(Peter): Because its recursive (it makes sure all type sizes become known
|
||||
// if it needs them) we should never get to the end of this function and not have
|
||||
// the ability to tell how big something is.
|
||||
// TODO(Peter): We don't parse all types yet however, so for now, this is just an alert,
|
||||
// not an assert;
|
||||
#if 0
|
||||
Assert(Struct->Size != 0);
|
||||
#else
|
||||
if (Struct->Size == 0)
|
||||
// NOTE(Peter): It is valid to have an empty struct, which would have a size of
|
||||
// zero, hence the check here.
|
||||
if (Struct->Size == 0 && Struct->Struct.MemberDecls.Used > 0)
|
||||
{
|
||||
printf("Struct Error: Struct Size = 0. %.*s\n", StringExpand(Struct->Identifier));
|
||||
}
|
||||
// NOTE(Peter): Because its recursive (it makes sure all type sizes become known
|
||||
// if it needs them) we should never get to the end of this function and not have
|
||||
// the ability to tell how big something is.
|
||||
// TODO(Peter): We don't parse all types yet however, so for now, this is just an alert,
|
||||
// not an assert;
|
||||
#if 0
|
||||
Assert(Struct->Size != 0);
|
||||
#else
|
||||
PushFError(Errors, "Struct Error: Struct Size = 0. %S\n", Struct->Identifier);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
FixUpUnionSize (s32 UnionIndex, type_table TypeTable)
|
||||
FixUpUnionSize (s32 UnionIndex, type_table TypeTable, errors* Errors)
|
||||
{
|
||||
type_definition* Union = TypeTable.Types.GetElementAtIndex(UnionIndex);
|
||||
Assert(Union->Type == TypeDef_Union);
|
||||
|
@ -376,28 +412,7 @@ FixUpUnionSize (s32 UnionIndex, type_table TypeTable)
|
|||
if (Member->TypeIndex >= 0)
|
||||
{
|
||||
type_definition* MemberTypeDef = TypeTable.Types.GetElementAtIndex(Member->TypeIndex);
|
||||
if (MemberTypeDef->Size == 0)
|
||||
{
|
||||
if (MemberTypeDef->Type == TypeDef_Struct)
|
||||
{
|
||||
FixUpStructSize(Member->TypeIndex, TypeTable);
|
||||
}
|
||||
else if(MemberTypeDef->Type == TypeDef_Union)
|
||||
{
|
||||
FixUpUnionSize(Member->TypeIndex, TypeTable);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO(Peter): We don't parse all types yet, so for now, this is just an alert,
|
||||
// not an assert;
|
||||
#if 0
|
||||
InvalidCodePath;
|
||||
#else
|
||||
printf("Union Error: TypeDef Size = 0. %.*s\n", StringExpand(MemberTypeDef->Identifier));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
FixupStructMember(Member, MemberTypeDef, TypeTable, Errors);
|
||||
s32 MemberSize = CalculateStructMemberSize(*Member, *MemberTypeDef);
|
||||
BiggestMemberSize = GSMax(BiggestMemberSize, MemberSize);
|
||||
}
|
||||
|
@ -405,19 +420,21 @@ FixUpUnionSize (s32 UnionIndex, type_table TypeTable)
|
|||
|
||||
Union->Size = BiggestMemberSize;
|
||||
|
||||
// NOTE(Peter): Because its recursive (it makes sure all type sizes become known
|
||||
// if it needs them) we should never get to the end of this function and not have
|
||||
// the ability to tell how big something is
|
||||
// TODO(Peter): We don't parse all types yet however, so for now, this is just an alert,
|
||||
// not an assert;
|
||||
#if 0
|
||||
Assert(Union->Size != 0);
|
||||
#else
|
||||
if (Union->Size == 0)
|
||||
// NOTE(Peter): It is valid to have an empty struct, which would have a size of
|
||||
// zero, hence the check here.
|
||||
if (Union->Size == 0 && Union->Struct.MemberDecls.Used > 0)
|
||||
{
|
||||
printf("Union Error: Struct Size = 0. %.*s\n", StringExpand(Union->Identifier));
|
||||
}
|
||||
// NOTE(Peter): Because its recursive (it makes sure all type sizes become known
|
||||
// if it needs them) we should never get to the end of this function and not have
|
||||
// the ability to tell how big something is
|
||||
// TODO(Peter): We don't parse all types yet however, so for now, this is just an alert,
|
||||
// not an assert;
|
||||
#if 0
|
||||
Assert(Union->Size != 0);
|
||||
#else
|
||||
PushFError(Errors, "Union Error: Struct Size = 0. %S\n", Union->Identifier);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
type_definition CPPBasicTypes[] = {
|
||||
|
|
|
@ -104,6 +104,29 @@ GetNextToken (tokenizer* Tokenizer)
|
|||
|
||||
EatWhitespace(Tokenizer);
|
||||
|
||||
// Don't include comments in tokens
|
||||
while (Tokenizer->At[0] && Tokenizer->At[0] == '/' && Tokenizer->At[1] && Tokenizer->At[1] == '/')
|
||||
{
|
||||
EatToNewLine(Tokenizer);
|
||||
EatWhitespace(Tokenizer);
|
||||
}
|
||||
|
||||
while(Tokenizer->At[0] && Tokenizer->At[0] == '/' && Tokenizer->At[1] && Tokenizer->At[1] == '*')
|
||||
{
|
||||
Tokenizer->At += 2;
|
||||
while (*Tokenizer->At)
|
||||
{
|
||||
if (Tokenizer->At[0] && Tokenizer->At[0] == '*' && Tokenizer->At[1] && Tokenizer->At[1] == '/')
|
||||
{
|
||||
Tokenizer->At += 2;
|
||||
break;
|
||||
}
|
||||
EatToNewLine(Tokenizer);
|
||||
EatWhitespace(Tokenizer);
|
||||
}
|
||||
EatWhitespace(Tokenizer);
|
||||
}
|
||||
|
||||
Result.Text = MakeString(Tokenizer->At, 1, 1);
|
||||
|
||||
// NOTE(Peter): Adding one because I want the tokenizer to work with clear to zero
|
||||
|
@ -226,23 +249,6 @@ GetNextToken (tokenizer* Tokenizer)
|
|||
Result.Text.Memory = Tokenizer->At;
|
||||
Result.Text.Length = EatString(Tokenizer);
|
||||
}
|
||||
else if (C == '/' && Tokenizer->At[0] && Tokenizer->At[0] == '/')
|
||||
{
|
||||
Result.Type = Token_Comment;
|
||||
Result.Text.Length += 1 + EatToNewLine(Tokenizer);
|
||||
}
|
||||
else if (C == '/' && Tokenizer->At[0] && Tokenizer->At[0] == '*')
|
||||
{
|
||||
s32 CommentLength = 1;
|
||||
while (Tokenizer->At[0] && Tokenizer->At[0] != '*' &&
|
||||
Tokenizer->At[1] && Tokenizer->At[1] != '/')
|
||||
{
|
||||
++Tokenizer->At;
|
||||
CommentLength++;
|
||||
}
|
||||
|
||||
Result.Text.Length += CommentLength;
|
||||
}
|
||||
// NOTE(Peter): This is after comment parsing so that the division operator
|
||||
// falls through the comment case
|
||||
else if (IsOperator(C)) { Result.Type = Token_Operator; }
|
||||
|
|
|
@ -5,24 +5,12 @@
|
|||
//
|
||||
#ifndef FOLDHAUS_APP_CPP
|
||||
|
||||
#define GSMetaTag(ident) // this is purely for the sake of the meta layer
|
||||
|
||||
#include "../meta/foldhaus_meta_include.h"
|
||||
|
||||
#include "foldhaus_platform.h"
|
||||
#include "foldhaus_app.h"
|
||||
|
||||
GSMetaTag(node_struct);
|
||||
struct test_data
|
||||
{
|
||||
r32* Ptr;
|
||||
|
||||
GSMetaTag(output_member);
|
||||
u32 Output;
|
||||
|
||||
GSMetaTag(foo);
|
||||
GSMetaTag(input_member);
|
||||
u32 Input;
|
||||
};
|
||||
#include "./generated/gs_meta_generated_typeinfo.h"
|
||||
|
||||
internal v4
|
||||
MouseToWorldRay(r32 MouseX, r32 MouseY, camera* Camera, rect WindowBounds)
|
||||
|
|
|
@ -20,6 +20,11 @@
|
|||
|
||||
#include "foldhaus_node.h"
|
||||
|
||||
// TODO(Peter): TEMPORARY
|
||||
u32 NodeSpecificationsCount = 0;
|
||||
node_specification* NodeSpecifications = 0;
|
||||
|
||||
|
||||
#include "assembly_parser.cpp"
|
||||
//#include "test_patterns.h"
|
||||
|
||||
|
@ -210,8 +215,8 @@ TestPatternThree(assembly* Assembly, r32 Time)
|
|||
#include "foldhaus_text_entry.cpp"
|
||||
#include "foldhaus_search_lister.cpp"
|
||||
|
||||
//#include "foldhaus_default_nodes.h"
|
||||
#include "generated/foldhaus_nodes_generated.cpp"
|
||||
#include "foldhaus_default_nodes.h"
|
||||
|
||||
#include "foldhaus_node.cpp"
|
||||
|
||||
FOLDHAUS_INPUT_COMMAND_PROC(EndCurrentOperationMode)
|
||||
|
|
|
@ -72,12 +72,20 @@ NODE_PROC(AddNodeProc, add_data)
|
|||
//
|
||||
/////////////////////////////////
|
||||
|
||||
NODE_STRUCT(sin_wave_data)
|
||||
GSMetaTag(node_struct);
|
||||
struct sin_wave_data
|
||||
{
|
||||
NODE_IN(r32, Period);
|
||||
NODE_IN(r32, Min);
|
||||
NODE_IN(r32, Max);
|
||||
NODE_OUT(r32, Result);
|
||||
GSMetaTag(node_input);
|
||||
r32 Period;
|
||||
|
||||
GSMetaTag(node_input);
|
||||
r32 Min;
|
||||
|
||||
GSMetaTag(node_input);
|
||||
r32 Max;
|
||||
|
||||
GSMetaTag(node_input);
|
||||
r32 Result;
|
||||
|
||||
r32 Accumulator;
|
||||
};
|
||||
|
@ -109,35 +117,41 @@ NODE_PROC(SinWave, sin_wave_data)
|
|||
//
|
||||
/////////////////////////////////
|
||||
|
||||
NODE_STRUCT(multiply_patterns_data)
|
||||
GSMetaTag(node_struct);
|
||||
struct multiply_patterns_data
|
||||
{
|
||||
NODE_COLOR_BUFFER_IN(A);
|
||||
NODE_COLOR_BUFFER_IN(B);
|
||||
NODE_COLOR_BUFFER_OUT(Result);
|
||||
GSMetaTag(node_input);
|
||||
color_buffer A;
|
||||
|
||||
GSMetaTag(node_input);
|
||||
color_buffer B;
|
||||
|
||||
GSMetaTag(node_output);
|
||||
color_buffer Result;
|
||||
};
|
||||
|
||||
NODE_PROC(MultiplyPatterns, multiply_patterns_data)
|
||||
{
|
||||
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);
|
||||
|
||||
s32 AR = Data->AColors[LED->Index].R;
|
||||
s32 AG = Data->AColors[LED->Index].G;
|
||||
s32 AB = Data->AColors[LED->Index].B;
|
||||
s32 AR = Data->A.Colors[LED->Index].R;
|
||||
s32 AG = Data->A.Colors[LED->Index].G;
|
||||
s32 AB = Data->A.Colors[LED->Index].B;
|
||||
|
||||
s32 BR = Data->BColors[LED->Index].R;
|
||||
s32 BG = Data->BColors[LED->Index].G;
|
||||
s32 BB = Data->BColors[LED->Index].B;
|
||||
s32 BR = Data->B.Colors[LED->Index].R;
|
||||
s32 BG = Data->B.Colors[LED->Index].G;
|
||||
s32 BB = Data->B.Colors[LED->Index].B;
|
||||
|
||||
s32 RCombined = (AR * BR) / 255;
|
||||
s32 GCombined = (AG * BG) / 255;
|
||||
s32 BCombined = (AB * BB) / 255;
|
||||
|
||||
Data->ResultColors[LED->Index].R = (u8)RCombined;
|
||||
Data->ResultColors[LED->Index].G = (u8)GCombined;
|
||||
Data->ResultColors[LED->Index].B = (u8)BCombined;
|
||||
Data->Result.Colors[LED->Index].R = (u8)RCombined;
|
||||
Data->Result.Colors[LED->Index].G = (u8)GCombined;
|
||||
Data->Result.Colors[LED->Index].B = (u8)BCombined;
|
||||
|
||||
LED++;
|
||||
}
|
||||
|
|
|
@ -12,19 +12,12 @@ typedef enum node_type node_type;
|
|||
|
||||
#define DEFAULT_NODE_DIMENSION v2{125, 150}
|
||||
|
||||
#define NODE_COLOR_BUFFER \
|
||||
led* LEDs; \
|
||||
pixel* Colors; \
|
||||
s32 LEDCount;
|
||||
|
||||
#define NAMED_NODE_COLOR_BUFFER(name) \
|
||||
led* name##LEDs; \
|
||||
pixel* name##Colors; \
|
||||
s32 name##LEDCount;
|
||||
|
||||
#define NODE_COLOR_BUFFER_INOUT NODE_COLOR_BUFFER
|
||||
#define NODE_COLOR_BUFFER_IN(name) NAMED_NODE_COLOR_BUFFER(name)
|
||||
#define NODE_COLOR_BUFFER_OUT(name) NAMED_NODE_COLOR_BUFFER(name)
|
||||
struct color_buffer
|
||||
{
|
||||
led* LEDs;
|
||||
pixel* Colors;
|
||||
s32 LEDCount;
|
||||
};
|
||||
|
||||
// TODO(Peter): Generate this
|
||||
enum struct_member_type
|
||||
|
@ -115,7 +108,8 @@ void proc_name(input_type* Data, r32 DeltaTime)
|
|||
|
||||
struct output_node_data
|
||||
{
|
||||
NODE_COLOR_BUFFER_IN(Result);
|
||||
GSMetaTag(node_input);
|
||||
color_buffer Result;
|
||||
};
|
||||
|
||||
void OutputNode(output_node_data* Data, r32 DeltaTime)
|
||||
|
|
|
@ -24,7 +24,7 @@ PipeSearchStringToDestination (text_entry* Input)
|
|||
|
||||
case TextTranslateTo_R32:
|
||||
{
|
||||
parse_result FloatParseResult = ParseFloat(Input->Buffer.Memory, Input->Buffer.Length);
|
||||
parse_result FloatParseResult = ParseFloat(StringExpand(Input->Buffer));
|
||||
*Input->Destination.FloatDest = FloatParseResult.FloatValue;
|
||||
}break;
|
||||
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
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,
|
||||
};
|
||||
|
||||
static gsm_struct_member_type_info StructMembers_sin_wave_data[] = {
|
||||
{ "Period", 6, (u64)&((sin_wave_data*)0)->Period },
|
||||
{ "Min", 3, (u64)&((sin_wave_data*)0)->Min },
|
||||
{ "Max", 3, (u64)&((sin_wave_data*)0)->Max },
|
||||
{ "Result", 6, (u64)&((sin_wave_data*)0)->Result },
|
||||
{ "Accumulator", 11, (u64)&((sin_wave_data*)0)->Accumulator },
|
||||
};
|
||||
static gsm_struct_member_type_info StructMembers_v4[] = {
|
||||
{ "x", 1, (u64)&((v4*)0)->x },
|
||||
{ "y", 1, (u64)&((v4*)0)->y },
|
||||
{ "z", 1, (u64)&((v4*)0)->z },
|
||||
{ "w", 1, (u64)&((v4*)0)->w },
|
||||
{ "r", 1, (u64)&((v4*)0)->r },
|
||||
{ "g", 1, (u64)&((v4*)0)->g },
|
||||
{ "b", 1, (u64)&((v4*)0)->b },
|
||||
{ "a", 1, (u64)&((v4*)0)->a },
|
||||
{ "E", 1, (u64)&((v4*)0)->E },
|
||||
};
|
||||
static gsm_struct_member_type_info StructMembers_led[] = {
|
||||
{ "Index", 5, (u64)&((led*)0)->Index },
|
||||
{ "Position", 8, (u64)&((led*)0)->Position },
|
||||
};
|
||||
static gsm_struct_member_type_info StructMembers_pixel[] = {
|
||||
{ "R", 1, (u64)&((pixel*)0)->R },
|
||||
{ "G", 1, (u64)&((pixel*)0)->G },
|
||||
{ "B", 1, (u64)&((pixel*)0)->B },
|
||||
{ "Channels", 8, (u64)&((pixel*)0)->Channels },
|
||||
};
|
||||
static gsm_struct_member_type_info StructMembers_color_buffer[] = {
|
||||
{ "LEDs", 4, (u64)&((color_buffer*)0)->LEDs },
|
||||
{ "Colors", 6, (u64)&((color_buffer*)0)->Colors },
|
||||
{ "LEDCount", 8, (u64)&((color_buffer*)0)->LEDCount },
|
||||
};
|
||||
static gsm_struct_member_type_info StructMembers_multiply_patterns_data[] = {
|
||||
{ "A", 1, (u64)&((multiply_patterns_data*)0)->A },
|
||||
{ "B", 1, (u64)&((multiply_patterns_data*)0)->B },
|
||||
{ "Result", 6, (u64)&((multiply_patterns_data*)0)->Result },
|
||||
};
|
||||
|
||||
static gsm_struct_type_info StructTypes[] = {
|
||||
{ gsm_StructType_sin_wave_data, "sin_wave_data", 13, 20, 0, 0, StructMembers_sin_wave_data, 5 },
|
||||
{ gsm_StructType_r32, "r32", 3, 4, 0, 0, 0, 0 },
|
||||
{ gsm_StructType_multiply_patterns_data, "multiply_patterns_data", 22, 60, 0, 0, StructMembers_multiply_patterns_data, 3 },
|
||||
{ gsm_StructType_color_buffer, "color_buffer", 12, 20, 0, 0, StructMembers_color_buffer, 3 },
|
||||
{ gsm_StructType_led, "led", 3, 20, 0, 0, StructMembers_led, 2 },
|
||||
{ gsm_StructType_s32, "s32", 3, 4, 0, 0, 0, 0 },
|
||||
{ gsm_StructType_v4, "v4", 2, 16, 0, 0, StructMembers_v4, 3 },
|
||||
{ gsm_StructType_float, "float", 5, 4, 0, 0, 0, 0 },
|
||||
{ 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;
|
|
@ -491,7 +491,7 @@ PANEL_RENDER_PROC(NodeGraph_Render)
|
|||
string TitleString = MakeStringLiteral("Available Nodes");
|
||||
DrawListElement(TitleString, &List, Mouse, RenderBuffer, State->Interface);
|
||||
|
||||
for (s32 i = 0; i < NodeSpecificationsCount; i++)
|
||||
for (u32 i = 0; i < NodeSpecificationsCount; i++)
|
||||
{
|
||||
node_specification Spec = NodeSpecifications[i];
|
||||
string NodeName = MakeString(Spec.Name, Spec.NameLength);
|
||||
|
|
|
@ -6,13 +6,18 @@
|
|||
#ifndef TEST_PATTERNS_H
|
||||
|
||||
|
||||
NODE_STRUCT(solid_color_data)
|
||||
GSMetaTag(node_struct)
|
||||
struct solid_color_data
|
||||
{
|
||||
NODE_IN(v4, Color);
|
||||
NODE_COLOR_BUFFER_OUT(Result);
|
||||
GSMetaTag(node_input);
|
||||
v4 Color;
|
||||
|
||||
GSMetaTag(node_output);
|
||||
color_buffer Result;
|
||||
};
|
||||
|
||||
NODE_PROC(SolidColorProc, solid_color_data)
|
||||
GSMetaTag(node_proc); // :TagParamsForNodeParamStructs
|
||||
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);
|
||||
|
@ -30,15 +35,24 @@ NODE_PROC(SolidColorProc, solid_color_data)
|
|||
}
|
||||
}
|
||||
|
||||
NODE_STRUCT(vertical_color_fade_data)
|
||||
GSMetaTag(node_struct)
|
||||
struct vertical_color_fade_data
|
||||
{
|
||||
NODE_IN(v4, Color);
|
||||
NODE_IN(r32, Min);
|
||||
NODE_IN(r32, Max);
|
||||
NODE_COLOR_BUFFER_OUT(Result);
|
||||
GSMetaTag(node_input);
|
||||
v4 Color;
|
||||
|
||||
GSMetaTag(node_input);
|
||||
r32 Min;
|
||||
|
||||
GSMetaTag(node_input);
|
||||
r32 Max;
|
||||
|
||||
GSMetaTag(node_output);
|
||||
color_buffer Result;
|
||||
};
|
||||
|
||||
NODE_PROC(VerticalColorFadeProc, vertical_color_fade_data)
|
||||
GSMetaTag(node_proc); // :TagParamsForNodeParamStructs
|
||||
void VerticalColorFadeProc, vertical_color_fade_data* Data)
|
||||
{
|
||||
r32 R = (Data->Color.r * 255);
|
||||
r32 G = (Data->Color.g * 255);
|
||||
|
@ -62,19 +76,36 @@ NODE_PROC(VerticalColorFadeProc, vertical_color_fade_data)
|
|||
}
|
||||
|
||||
// Original -> DiscPatterns.pde : Revolving Discs
|
||||
NODE_STRUCT(revolving_discs_data)
|
||||
GSMetaTag(node_struct)
|
||||
struct revolving_discs_data
|
||||
{
|
||||
NODE_IN(r32, Rotation);
|
||||
NODE_IN(r32, ThetaZ);
|
||||
NODE_IN(r32, ThetaY);
|
||||
NODE_IN(r32, DiscWidth);
|
||||
NODE_IN(r32, InnerRadius);
|
||||
NODE_IN(r32, OuterRadius);
|
||||
NODE_IN(v4, Color);
|
||||
NODE_COLOR_BUFFER_OUT(Result);
|
||||
GSMetaTag(node_input);
|
||||
r32 Rotation;
|
||||
|
||||
GSMetaTag(node_input);
|
||||
r32 ThetaZ;
|
||||
|
||||
GSMetaTag(node_input);
|
||||
r32 ThetaY;
|
||||
|
||||
GSMetaTag(node_input);
|
||||
r32 DiscWidth;
|
||||
|
||||
GSMetaTag(node_input);
|
||||
r32 InnerRadius;
|
||||
|
||||
GSMetaTag(node_input);
|
||||
r32 OuterRadius;
|
||||
|
||||
GSMetaTag(node_input);
|
||||
v4 Color;
|
||||
|
||||
GSMetaTag(node_output);
|
||||
color_buffer Result;
|
||||
};
|
||||
|
||||
NODE_PROC(RevolvingDiscs, revolving_discs_data)
|
||||
GSMetaTag(node_proc); // :TagParamsForNodeParamStructs
|
||||
void RevolvingDiscs, revolving_discs_data* Data)
|
||||
{
|
||||
DEBUG_TRACK_FUNCTION;
|
||||
|
||||
|
|
Loading…
Reference in New Issue