Lots of work on the meta system. Most changes in src are just due to me putting test data in place

This commit is contained in:
Peter Slattery 2020-01-18 22:07:59 -08:00
parent af68881e04
commit b11d9da9e4
11 changed files with 1615 additions and 691 deletions

View File

@ -20,7 +20,7 @@ del *.pdb > NUL 2> NUL
REM Run the Preprocessor REM Run the Preprocessor
pushd ..\src\ pushd ..\src\
..\build\foldhaus_meta.exe C:\projects\foldhaus\src\ ..\build\foldhaus_meta.exe C:\projects\foldhaus\src\foldhaus_app.cpp
popd popd
REM cl %CommonCompilerFlags% F:\src\foldhaus_util_radialumia_file_converter.cpp /link %CommonLinkerFlags% REM cl %CommonCompilerFlags% F:\src\foldhaus_util_radialumia_file_converter.cpp /link %CommonLinkerFlags%

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,409 @@
//
// File: foldhaus_meta_type_table.h
// Author: Peter Slattery
// Creation Date: 2020-01-17
//
#ifndef FOLDHAUS_META_TYPE_TABLE_H
enum type_definition_type
{
TypeDef_Invalid,
TypeDef_Unknown, // NOTE(Peter): these require fixup later
TypeDef_Struct,
TypeDef_Union,
TypeDef_BasicType,
TypeDef_FunctionPointer,
TypeDef_Count,
};
struct meta_tag
{
string Identifier;
};
struct struct_member_decl
{
// NOTE(Peter): Because of the way the tokenizer works, we don't lex and parse
// 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;
string Identifier;
b32 Pointer;
// NOTE(Peter): Zero means its not an array, since you cannot initialize a static
// array to size 0. ie this is invalid: r32 x[0]; and will throw a compiler error
u32 ArrayCount;
// :SmallAllocationsAllOver
gs_bucket<meta_tag> MetaTags;
};
// TODO(Peter): This is just a struct_decl
struct struct_decl
{
// TODO(Peter): Lots of tiny arrays everywhere! Pull these into a central allocation
// buffer somewhere
// :SmallAllocationsAllOver
gs_bucket<struct_member_decl> MemberDecls;
};
struct type_definition
{
string Identifier;
s32 Size;
gs_bucket<meta_tag> MetaTags;
type_definition_type Type;
union
{
struct_decl Struct;
};
b32 Pointer;
};
struct type_table
{
gs_bucket<type_definition> Types;
};
internal void
CopyMetaTagsAndClear(gs_bucket<token*>* Source, gs_bucket<meta_tag>* Dest)
{
for (u32 i = 0; i < Source->Used; i++)
{
token* TagToken = *Source->GetElementAtIndex(i);
meta_tag TagDest = {0};
TagDest.Identifier = TagToken->Text;
Dest->PushElementOnBucket(TagDest);
}
Source->Used = 0;
}
internal type_definition*
PushStructOnTypeTable(string Identifier, type_definition_type DeclType, gs_bucket<token*>* TagList, type_table* TypeTable)
{
Assert(DeclType == TypeDef_Struct || DeclType == TypeDef_Union);
type_definition* Result = TypeTable->Types.TakeElement();
*Result = {0};
Result->Type = DeclType;
Result->Identifier = Identifier;
CopyMetaTagsAndClear(TagList, &Result->MetaTags);
return Result;
}
internal s32
PushTypeDefOnTypeTable(type_definition TypeDef, type_table* TypeTable)
{
s32 Index = -1;
if (TypeDef.Type != TypeDef_BasicType)
{
printf("Invalid TypeDef: %.*s\n", StringExpand(TypeDef.Identifier));
}
else
{
Index = TypeTable->Types.PushElementOnBucket(TypeDef);
}
return Index;
}
internal s32
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;
}
internal s32
GetIndexOfType (string Identifier, type_table TypeTable)
{
s32 Result = -1;
for (u32 i = 0; i < TypeTable.Types.Used; i++)
{
type_definition* TypeDef = TypeTable.Types.GetElementAtIndex(i);
if (StringsEqual(Identifier, TypeDef->Identifier))
{
Result = i;
break;
}
}
return Result;
}
internal s32
GetSizeOfType (s32 TypeIndex, type_table TypeTable)
{
s32 Result = -1;
Assert(TypeIndex >= 0 && (u32)TypeIndex < TypeTable.Types.Used);
type_definition* TypeDef = TypeTable.Types.GetElementAtIndex(TypeIndex);
Result = TypeDef->Size;
return Result;
}
internal s32
GetSizeOfType (string Identifier, type_table TypeTable)
{
s32 Result = -1;
for (u32 i = 0; i < TypeTable.Types.Used; i++)
{
type_definition* TypeDef = TypeTable.Types.GetElementAtIndex(i);
if (StringsEqual(Identifier, TypeDef->Identifier))
{
Result = TypeDef->Size;
break;
}
}
return Result;
}
internal b32
StructMembersEqual (struct_member_decl A, struct_member_decl B)
{
b32 Result = false;
if (A.TypeIndex == B.TypeIndex &&
A.ArrayCount == B.ArrayCount &&
StringsEqual(A.Identifier, B.Identifier))
{
Result = true;
}
return Result;
}
internal b32
StructOrUnionsEqual (type_definition A, type_definition B)
{
// NOTE(Peter): Fairly certain the only places this is used are when we
// already know the identifiers match
Assert(StringsEqual(A.Identifier, B.Identifier));
Assert(A.Type == TypeDef_Struct || A.Type == TypeDef_Union);
Assert(B.Type == TypeDef_Struct || B.Type == TypeDef_Union);
b32 Result = false;
if (A.Struct.MemberDecls.Used == B.Struct.MemberDecls.Used)
{
Result = true;
for (u32 i = 0; i < A.Struct.MemberDecls.Used; i++)
{
struct_member_decl* AMember = A.Struct.MemberDecls.GetElementAtIndex(i);
struct_member_decl* BMember = A.Struct.MemberDecls.GetElementAtIndex(i);
if (!StructMembersEqual(*AMember, *BMember))
{
Result = false;
break;
}
}
}
return Result;
}
internal s32
FindIndexOfMatchingType (type_definition Match, type_table TypeTable)
{
s32 Result = -1;
for (u32 i = 0; i < TypeTable.Types.Used; i++)
{
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;
}
}
}
return Result;
}
internal void FixUpStructSize (type_definition* Struct, type_table TypeTable);
internal void FixUpUnionSize (type_definition* Union, type_table TypeTable);
internal void
FixupMemberType (struct_member_decl* Member, type_table TypeTable)
{
if (Member->TypeIndex == -1)
{
Member->TypeIndex = GetIndexOfType(Member->Identifier, TypeTable);
}
Assert(Member->TypeIndex >= 0);
}
internal s32
CalculateStructMemberSize (struct_member_decl Member, type_definition MemberType)
{
Assert(Member.TypeIndex >= 0);
// TODO(Peter): Assert(MemberType.Size != 0);
s32 Result = MemberType.Size;
if (Member.ArrayCount > 0)
{
Result *= Member.ArrayCount;
}
if (Member.Pointer)
{
Result = sizeof(void*);
}
return Result;
}
internal void
FixUpStructSize (type_definition* Struct, type_table TypeTable)
{
Assert(Struct->Type == TypeDef_Struct);
s32 SizeAcc = 0;
for (u32 j = 0; j < Struct->Struct.MemberDecls.Used; j++)
{
struct_member_decl* Member = Struct->Struct.MemberDecls.GetElementAtIndex(j);
FixupMemberType(Member, TypeTable);
if (Member->TypeIndex >= 0)
{
type_definition* MemberTypeDef = TypeTable.Types.GetElementAtIndex(Member->TypeIndex);
if (MemberTypeDef->Size == 0)
{
if (MemberTypeDef->Type == TypeDef_Struct)
{
FixUpStructSize(MemberTypeDef, TypeTable);
}
else if(MemberTypeDef->Type == TypeDef_Union)
{
FixUpUnionSize(MemberTypeDef, 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("Error: TypeDef Size = 0. %.*s\n", StringExpand(MemberTypeDef->Identifier));
#endif
}
}
u32 MemberSize = CalculateStructMemberSize(*Member, *MemberTypeDef);
SizeAcc += MemberSize;
}
}
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)
{
printf("Error: Struct Size = 0. %.*s\n", StringExpand(Struct->Identifier));
}
#endif
}
internal void
FixUpUnionSize (type_definition* Union, type_table TypeTable)
{
Assert(Union->Type == TypeDef_Union);
s32 BiggestMemberSize = 0;
for (u32 j = 0; j < Union->Struct.MemberDecls.Used; j++)
{
struct_member_decl* Member = Union->Struct.MemberDecls.GetElementAtIndex(j);
FixupMemberType(Member, TypeTable);
if (Member->TypeIndex >= 0)
{
type_definition* MemberTypeDef = TypeTable.Types.GetElementAtIndex(Member->TypeIndex);
if (MemberTypeDef->Size == 0)
{
if (MemberTypeDef->Type == TypeDef_Struct)
{
FixUpStructSize(MemberTypeDef, TypeTable);
}
else if(MemberTypeDef->Type == TypeDef_Union)
{
FixUpUnionSize(MemberTypeDef, 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("Error: TypeDef Size = 0. %.*s\n", StringExpand(MemberTypeDef->Identifier));
#endif
}
}
s32 MemberSize = CalculateStructMemberSize(*Member, *MemberTypeDef);
BiggestMemberSize = GSMax(BiggestMemberSize, MemberSize);
}
}
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)
{
printf("Error: Struct Size = 0. %.*s\n", StringExpand(Union->Identifier));
}
#endif
}
type_definition CPPBasicTypes[] = {
{ MakeStringLiteral("float"), sizeof(float), {}, TypeDef_BasicType, {}, false },
{ MakeStringLiteral("double"), sizeof(double), {}, TypeDef_BasicType, {}, false },
{ MakeStringLiteral("char"), sizeof(char), {}, TypeDef_BasicType, {}, false },
{ MakeStringLiteral("wchar_t"), sizeof(wchar_t), {}, TypeDef_BasicType, {}, false },
{ MakeStringLiteral("int"), sizeof(int), {}, TypeDef_BasicType, {}, false },
{ MakeStringLiteral("short"), sizeof(short), {}, TypeDef_BasicType, {}, false },
{ MakeStringLiteral("short int"), sizeof(short int), {}, TypeDef_BasicType, {}, false },
{ MakeStringLiteral("long int"), sizeof(long int), {}, TypeDef_BasicType, {}, false },
{ MakeStringLiteral("long long int"), sizeof(long long int), {}, TypeDef_BasicType, {}, false },
{ MakeStringLiteral("void"), sizeof(void*), {}, TypeDef_BasicType, {}, false },
{ MakeStringLiteral("bool"), sizeof(bool), {}, TypeDef_BasicType, {}, false },
};
internal void
PopulateTableWithDefaultCPPTypes(type_table* TypeTable)
{
for (u32 i = 0; i < GSArrayLength(CPPBasicTypes); i++)
{
PushTypeDefOnTypeTable(CPPBasicTypes[i], TypeTable);
}
}
#define FOLDHAUS_META_TYPE_TABLE_H
#endif // FOLDHAUS_META_TYPE_TABLE_H

View File

@ -5,18 +5,32 @@ struct token_selection_spec
}; };
internal s32 internal s32
EatPreprocessor (tokenizer* Tokenizer, token_type* Type) EatPreprocessor (tokenizer* Tokenizer)
{ {
s32 Length = 0; char* TStart = Tokenizer->At;
while (AtValidPosition(*Tokenizer) && !IsNewline(*Tokenizer->At))
// TODO(Peter): Make this actually separate out the different arguments?
while (Tokenizer->At[0] && !IsNewline(Tokenizer->At[0]))
{ {
++Tokenizer->At; if (Tokenizer->At[0] == '\\')
Length++; {
EatChar(Tokenizer);
while (IsWhitespace(*Tokenizer->At))
{
EatChar(Tokenizer);
}
if (IsNewline(*Tokenizer->At))
{
EatPastNewLine(Tokenizer);
}
}
else if (!IsNewline(*Tokenizer->At))
{
EatChar(Tokenizer);
}
} }
return Length; return Tokenizer->At - TStart;
} }
internal s32 internal s32
@ -55,6 +69,34 @@ EatIdentifier (tokenizer* Tokenizer)
return Length; return Length;
} }
internal b32
TokenAtEquals(tokenizer* Tokenizer, char* Needle)
{
b32 Result = true;
char* TokenizerStart = Tokenizer->At;
char* NeedleAt = Needle;
while (AtValidPosition(*Tokenizer) && *NeedleAt)
{
if (*NeedleAt != *Tokenizer->At)
{
Result = false;
break;
}
NeedleAt++;
EatChar(Tokenizer);
}
// NOTE(Peter): rewind tokenizer
if (!Result)
{
Tokenizer->At = TokenizerStart;
}
return Result;
}
internal token internal token
GetNextToken (tokenizer* Tokenizer) GetNextToken (tokenizer* Tokenizer)
{ {
@ -64,6 +106,9 @@ GetNextToken (tokenizer* Tokenizer)
Result.Text = MakeString(Tokenizer->At, 1, 1); Result.Text = MakeString(Tokenizer->At, 1, 1);
// NOTE(Peter): Adding one because I want the tokenizer to work with clear to zero
// but line numbers generally start at 1, not 0
Result.LineNumber = Tokenizer->LineNumber + 1;
char C = Tokenizer->At[0]; char C = Tokenizer->At[0];
++Tokenizer->At; ++Tokenizer->At;
@ -86,37 +131,82 @@ GetNextToken (tokenizer* Tokenizer)
} }
else if (C == '#') else if (C == '#')
{ {
Result.Text.Length += EatPreprocessor(Tokenizer, &Result.Type); // NOTE(Peter): Technically correct to do things like "# define"
EatWhitespace(Tokenizer);
if (CharArraysEqual(Result.Text.Memory, Result.Text.Length, "#define", 7)) if (TokenAtEquals(Tokenizer, "define"))
{ Result.Type = Token_PoundDefine; } {
else if (CharArraysEqual(Result.Text.Memory, Result.Text.Length, "#undef", 6)) Result.Type = Token_PoundDefine;
{ Result.Type = Token_PoundUndef; } EatPreprocessor(Tokenizer);
else if (CharArraysEqual(Result.Text.Memory, Result.Text.Length, "#include", 8)) Result.Text.Length = Tokenizer->At - Result.Text.Memory;
{ Result.Type = Token_PoundInclude; } }
else if (CharArraysEqual(Result.Text.Memory, Result.Text.Length, "#ifdef", 6)) else if (TokenAtEquals(Tokenizer, "undef"))
{ Result.Type = Token_PoundIfDef; } {
else if (CharArraysEqual(Result.Text.Memory, Result.Text.Length, "#ifndef", 7)) Result.Type = Token_PoundUndef;
{ Result.Type = Token_PoundIfNDef; } EatToNewLine(Tokenizer);
else if (CharArraysEqual(Result.Text.Memory, Result.Text.Length, "#if", 3)) Result.Text.Length = Tokenizer->At - Result.Text.Memory;
{ Result.Type = Token_PoundIf; } }
else if (CharArraysEqual(Result.Text.Memory, Result.Text.Length, "#elif", 5)) else if (TokenAtEquals(Tokenizer, "include"))
{ Result.Type = Token_PoundElif; } {
else if (CharArraysEqual(Result.Text.Memory, Result.Text.Length, "#else", 5)) Result.Type = Token_PoundInclude;
{ Result.Type = Token_PoundElse; } Result.Text.Length = Tokenizer->At - Result.Text.Memory;
else if (CharArraysEqual(Result.Text.Memory, Result.Text.Length, "#endif", 6)) }
{ Result.Type = Token_PoundEndif; } else if (TokenAtEquals(Tokenizer, "ifdef"))
else if (CharArraysEqual(Result.Text.Memory, Result.Text.Length, "#error", 6)) {
{ Result.Type = Token_PoundError; } Result.Type = Token_PoundIfDef;
else if (CharArraysEqual(Result.Text.Memory, Result.Text.Length, "#pragma", 7)) EatToNewLine(Tokenizer);
{ Result.Type = Token_PoundPragma; } Result.Text.Length = Tokenizer->At - Result.Text.Memory;
}
else if (TokenAtEquals(Tokenizer, "ifndef"))
{
Result.Type = Token_PoundIfNDef;
EatToNewLine(Tokenizer);
Result.Text.Length = Tokenizer->At - Result.Text.Memory;
}
else if (TokenAtEquals(Tokenizer, "if"))
{
Result.Type = Token_PoundIf;
EatToNewLine(Tokenizer);
Result.Text.Length = Tokenizer->At - Result.Text.Memory;
}
else if (TokenAtEquals(Tokenizer, "elif"))
{
Result.Type = Token_PoundElif;
EatToNewLine(Tokenizer);
Result.Text.Length = Tokenizer->At - Result.Text.Memory;
}
else if (TokenAtEquals(Tokenizer, "else"))
{
Result.Type = Token_PoundElse;
EatToNewLine(Tokenizer);
Result.Text.Length = Tokenizer->At - Result.Text.Memory;
}
else if (TokenAtEquals(Tokenizer, "endif"))
{
Result.Type = Token_PoundEndif;
EatToNewLine(Tokenizer);
Result.Text.Length = Tokenizer->At - Result.Text.Memory;
}
else if (TokenAtEquals(Tokenizer, "error"))
{
Result.Type = Token_PoundError;
EatToNewLine(Tokenizer);
Result.Text.Length = Tokenizer->At - Result.Text.Memory;
}
else if (TokenAtEquals(Tokenizer, "pragma"))
{
Result.Type = Token_PoundPragma;
EatToNewLine(Tokenizer);
Result.Text.Length = Tokenizer->At - Result.Text.Memory;
}
} }
else if (IsNumeric(C)) else if (IsNumeric(C))
{ {
Result.Type = Token_Number; Result.Type = Token_Number;
char* Start = Tokenizer->At;
EatNumber(Tokenizer); // NOTE(Peter): adding 1 to account for the fact that we've already advanced
Result.Text.Length = Tokenizer->At - Start; // Tokenizer once
Result.Text.Length = 1 + EatNumber(Tokenizer);
} }
else if (C == '\'') else if (C == '\'')
{ {
@ -139,9 +229,7 @@ GetNextToken (tokenizer* Tokenizer)
else if (C == '/' && Tokenizer->At[0] && Tokenizer->At[0] == '/') else if (C == '/' && Tokenizer->At[0] && Tokenizer->At[0] == '/')
{ {
Result.Type = Token_Comment; Result.Type = Token_Comment;
char* Start = Tokenizer->At; Result.Text.Length += 1 + EatToNewLine(Tokenizer);
EatToNewLine(Tokenizer);
Result.Text.Length += 1 + (Tokenizer->At - Start);
} }
else if (C == '/' && Tokenizer->At[0] && Tokenizer->At[0] == '*') else if (C == '/' && Tokenizer->At[0] && Tokenizer->At[0] == '*')
{ {
@ -167,46 +255,44 @@ GetNextToken (tokenizer* Tokenizer)
return Result; return Result;
} }
internal token* internal s32
FindNextMatchingToken (token* Tokens, token_selection_spec Spec) FindNextMatchingToken (u32 TokenAt, u32 TokenMax, gs_bucket<token> Tokens, token_selection_spec Spec)
{ {
token* Result = 0; s32 Result = -1;
token* Token = Tokens; s32 Start = (s32)TokenAt + 1;
while (Token) for (s32 i = Start; i < (s32)TokenMax; i++)
{ {
token* Token = Tokens.GetElementAtIndex(i);
if (Token->Text.Memory) if (Token->Text.Memory)
{ {
b32 Matches = false;
if (Spec.MatchText && StringsEqual(Spec.Text, Token->Text)) if (Spec.MatchText && StringsEqual(Spec.Text, Token->Text))
{ {
Matches = true; Result = i;
}
if (Matches)
{
Result = Token;
break; break;
} }
} }
Token = Token->Next;
} }
return Result; return Result;
} }
internal token* internal s32
GetNextTokenOfType (token* Tokens, token_type Type) GetNextTokenOfType (s32 TokenAtIndex, s32 Max, gs_bucket<token> Tokens, token_type Type)
{ {
token* Result = 0; s32 Result = -1;
token* Iter = Tokens->Next; s32 Start = TokenAtIndex + 1;
while((Iter != 0) && (Iter->Type != Type)) for (s32 i = Start; i < Max; i++)
{ {
Iter = Iter->Next; token* At = Tokens.GetElementAtIndex(i);
if (At->Type == Type)
{
Result = i;
break;
}
} }
Result = Iter;
return Result; return Result;
} }

View File

@ -12,7 +12,7 @@ ParseToken (tokenizer* Tokenizer)
assembly_token Result = {}; assembly_token Result = {};
Result.Token = Tokenizer->At; Result.Token = Tokenizer->At;
Result.Length = 1; Result.Length = 1;
Tokenizer->At++; EatChar(Tokenizer);
if (*Result.Token == ':'){ Result.Type = AssemblyToken_Colon; } if (*Result.Token == ':'){ Result.Type = AssemblyToken_Colon; }
else if (*Result.Token == ';'){ Result.Type = AssemblyToken_SemiColon; } else if (*Result.Token == ';'){ Result.Type = AssemblyToken_SemiColon; }
@ -21,20 +21,20 @@ ParseToken (tokenizer* Tokenizer)
else if (*Result.Token ==','){ Result.Type = AssemblyToken_Comma; } else if (*Result.Token ==','){ Result.Type = AssemblyToken_Comma; }
else if (IsNumericExtended(*Result.Token)) else if (IsNumericExtended(*Result.Token))
{ {
while(*Tokenizer->At && IsNumericExtended(*Tokenizer->At)) { Tokenizer->At++; } while(*Tokenizer->At && IsNumericExtended(*Tokenizer->At)) { EatChar(Tokenizer); }
Result.Type = AssemblyToken_Number; Result.Type = AssemblyToken_Number;
Result.Length = Tokenizer->At - Result.Token; Result.Length = Tokenizer->At - Result.Token;
} }
else if (*Result.Token =='\"') else if (*Result.Token =='\"')
{ {
while(*Tokenizer->At && *Tokenizer->At != '\"') { Tokenizer->At++; } while(*Tokenizer->At && *Tokenizer->At != '\"') { EatChar(Tokenizer); }
Result.Token++; // Skip the quote Result.Token++; // Skip the quote
Result.Type = AssemblyToken_String; Result.Type = AssemblyToken_String;
Result.Length = (Tokenizer->At - Result.Token) - 1; Result.Length = (Tokenizer->At - Result.Token) - 1;
} }
else if (*Result.Token == '(') else if (*Result.Token == '(')
{ {
while(*Tokenizer->At && *Tokenizer->At != ')') { Tokenizer->At++; } while(*Tokenizer->At && *Tokenizer->At != ')') { EatChar(Tokenizer); }
Result.Token++; // Skip the paren Result.Token++; // Skip the paren
Result.Type = AssemblyToken_Vector; Result.Type = AssemblyToken_Vector;
Result.Length = (Tokenizer->At - Result.Token) - 1; Result.Length = (Tokenizer->At - Result.Token) - 1;
@ -54,7 +54,7 @@ ParseToken (tokenizer* Tokenizer)
else else
{ {
Result.Type = AssemblyToken_Identifier; Result.Type = AssemblyToken_Identifier;
while(*Tokenizer->At && !IsWhitespace(*Tokenizer->At)) { Tokenizer->At++; } while(*Tokenizer->At && !IsWhitespace(*Tokenizer->At)) { EatChar(Tokenizer); }
} }
return Result; return Result;
@ -116,7 +116,7 @@ ParseLEDStrip (tokenizer* Tokenizer)
led_strip_definition Result = {}; led_strip_definition Result = {};
// Control Box Index // Control Box Index
while (*Tokenizer->At && !IsNumericExtended(*Tokenizer->At)) { Tokenizer->At++; } while (*Tokenizer->At && !IsNumericExtended(*Tokenizer->At)) { EatChar(Tokenizer); }
assembly_token BoxIDToken = ParseToken(Tokenizer); assembly_token BoxIDToken = ParseToken(Tokenizer);
Assert(BoxIDToken.Type == AssemblyToken_Number); Assert(BoxIDToken.Type == AssemblyToken_Number);
Result.ControlBoxID = ParseSignedIntUnsafe(BoxIDToken.Token).SignedIntValue; Result.ControlBoxID = ParseSignedIntUnsafe(BoxIDToken.Token).SignedIntValue;

View File

@ -1,3 +1,5 @@
typedef INITIALIZE_APPLICATION(initialize_application);
// //
// File: foldhaus_app.cpp // File: foldhaus_app.cpp
// Author: Peter Slattery // Author: Peter Slattery
@ -5,9 +7,25 @@
// //
#ifndef FOLDHAUS_APP_CPP #ifndef FOLDHAUS_APP_CPP
#define GSMetaTag(ident) // this is purely for the sake of the meta layer
#include "foldhaus_platform.h" #include "foldhaus_platform.h"
#include "foldhaus_app.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;
};
internal v4 internal v4
MouseToWorldRay(r32 MouseX, r32 MouseY, camera* Camera, rect WindowBounds) MouseToWorldRay(r32 MouseX, r32 MouseY, camera* Camera, rect WindowBounds)
{ {

View File

@ -21,7 +21,7 @@
#include "foldhaus_node.h" #include "foldhaus_node.h"
#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
@ -210,7 +210,7 @@ TestPatternThree(assembly* Assembly, r32 Time)
#include "foldhaus_text_entry.cpp" #include "foldhaus_text_entry.cpp"
#include "foldhaus_search_lister.cpp" #include "foldhaus_search_lister.cpp"
#include "foldhaus_default_nodes.h" //#include "foldhaus_default_nodes.h"
#include "generated/foldhaus_nodes_generated.cpp" #include "generated/foldhaus_nodes_generated.cpp"
#include "foldhaus_node.cpp" #include "foldhaus_node.cpp"

View File

@ -113,12 +113,12 @@ void proc_name(input_type* Data, r32 DeltaTime)
// OUTPUT NODE // OUTPUT NODE
/////////////////////////////////////////////// ///////////////////////////////////////////////
NODE_STRUCT(output_node_data) struct output_node_data
{ {
NODE_COLOR_BUFFER_IN(Result); NODE_COLOR_BUFFER_IN(Result);
}; };
NODE_PROC(OutputNode, output_node_data) void OutputNode(output_node_data* Data, r32 DeltaTime)
{ {
} }

View File

@ -9,17 +9,17 @@
#include <stdio.h> #include <stdio.h>
#define GS_LANGUAGE_NO_PROFILER_DEFINES #define GS_LANGUAGE_NO_PROFILER_DEFINES
#include <gs_language.h> #include "C:\programs-dev\gs_libs\src\gs_language.h"
#include "gs_platform.h" #include "gs_platform.h"
#include <gs_radix_sort.h> #include "C:\programs-dev\gs_libs\src\gs_radix_sort.h"
#include <gs_list.h> #include "C:\programs-dev\gs_libs\src\gs_list.h"
#include <gs_bucket.h> #include "C:\programs-dev\gs_libs\src\gs_bucket.h"
#define GS_MEMORY_TRACK_ALLOCATIONS #define GS_MEMORY_TRACK_ALLOCATIONS
#include <gs_memory_arena.h> #include "C:\programs-dev\gs_libs\src\gs_memory_arena.h"
#include <gs_string.h> #include "C:\programs-dev\gs_libs\src\gs_string.h"
#include "foldhaus_debug.h" #include "foldhaus_debug.h"
global_variable debug_services* GlobalDebugServices; global_variable debug_services* GlobalDebugServices;
@ -27,7 +27,7 @@ global_variable debug_services* GlobalDebugServices;
global_variable platform_alloc* GSAlloc; global_variable platform_alloc* GSAlloc;
global_variable platform_free* GSFree; global_variable platform_free* GSFree;
#include <gs_vector_matrix.h> #include "C:\programs-dev\gs_libs\src\gs_vector_matrix.h"
#include "gs_input.h" #include "gs_input.h"

View File

@ -1,111 +1,16 @@
enum node_type enum node_type
{ {
NodeType_FloatValue,
NodeType_VectorValue,
NodeType_MultiplyNodeProc,
NodeType_AddNodeProc,
NodeType_SinWave,
NodeType_MultiplyPatterns,
NodeType_OutputNode,
NodeType_SolidColorProc,
NodeType_VerticalColorFadeProc,
NodeType_RevolvingDiscs,
NodeType_Count, NodeType_Count,
}; };
node_struct_member MemberList_float_value_data[] = {
{ MemberType_r32, "Value", (u64)&((float_value_data*)0)->Value, IsInputMember },
{ MemberType_r32, "Result", (u64)&((float_value_data*)0)->Result, IsOutputMember},
};
node_struct_member MemberList_vector_data[] = {
{ MemberType_r32, "X", (u64)&((vector_data*)0)->X, IsInputMember },
{ MemberType_r32, "Y", (u64)&((vector_data*)0)->Y, IsInputMember },
{ MemberType_r32, "Z", (u64)&((vector_data*)0)->Z, IsInputMember },
{ MemberType_r32, "W", (u64)&((vector_data*)0)->W, IsInputMember },
{ MemberType_v4, "Result", (u64)&((vector_data*)0)->Result, IsOutputMember},
};
node_struct_member MemberList_multiply_data[] = {
{ MemberType_r32, "A", (u64)&((multiply_data*)0)->A, IsInputMember },
{ MemberType_r32, "B", (u64)&((multiply_data*)0)->B, IsInputMember },
{ MemberType_r32, "Result", (u64)&((multiply_data*)0)->Result, IsOutputMember},
};
node_struct_member MemberList_add_data[] = {
{ MemberType_v4, "A", (u64)&((add_data*)0)->A, IsInputMember },
{ MemberType_v4, "B", (u64)&((add_data*)0)->B, IsInputMember },
{ MemberType_v4, "Result", (u64)&((add_data*)0)->Result, IsOutputMember},
};
node_struct_member MemberList_sin_wave_data[] = {
{ MemberType_r32, "Period", (u64)&((sin_wave_data*)0)->Period, IsInputMember },
{ MemberType_r32, "Min", (u64)&((sin_wave_data*)0)->Min, IsInputMember },
{ MemberType_r32, "Max", (u64)&((sin_wave_data*)0)->Max, IsInputMember },
{ MemberType_r32, "Result", (u64)&((sin_wave_data*)0)->Result, IsOutputMember},
};
node_struct_member MemberList_multiply_patterns_data[] = {
{ MemberType_NODE_COLOR_BUFFER, "ALEDs", (u64)&((multiply_patterns_data*)0)->ALEDs, IsInputMember },
{ MemberType_NODE_COLOR_BUFFER, "BLEDs", (u64)&((multiply_patterns_data*)0)->BLEDs, IsInputMember },
{ MemberType_NODE_COLOR_BUFFER, "ResultLEDs", (u64)&((multiply_patterns_data*)0)->ResultLEDs, IsOutputMember},
};
node_struct_member MemberList_output_node_data[] = {
{ MemberType_NODE_COLOR_BUFFER, "ResultLEDs", (u64)&((output_node_data*)0)->ResultLEDs, IsInputMember },
};
node_struct_member MemberList_solid_color_data[] = {
{ MemberType_v4, "Color", (u64)&((solid_color_data*)0)->Color, IsInputMember },
{ MemberType_NODE_COLOR_BUFFER, "ResultLEDs", (u64)&((solid_color_data*)0)->ResultLEDs, IsOutputMember},
};
node_struct_member MemberList_vertical_color_fade_data[] = {
{ MemberType_v4, "Color", (u64)&((vertical_color_fade_data*)0)->Color, IsInputMember },
{ MemberType_r32, "Min", (u64)&((vertical_color_fade_data*)0)->Min, IsInputMember },
{ MemberType_r32, "Max", (u64)&((vertical_color_fade_data*)0)->Max, IsInputMember },
{ MemberType_NODE_COLOR_BUFFER, "ResultLEDs", (u64)&((vertical_color_fade_data*)0)->ResultLEDs, IsOutputMember},
};
node_struct_member MemberList_revolving_discs_data[] = {
{ MemberType_r32, "Rotation", (u64)&((revolving_discs_data*)0)->Rotation, IsInputMember },
{ MemberType_r32, "ThetaZ", (u64)&((revolving_discs_data*)0)->ThetaZ, IsInputMember },
{ MemberType_r32, "ThetaY", (u64)&((revolving_discs_data*)0)->ThetaY, IsInputMember },
{ MemberType_r32, "DiscWidth", (u64)&((revolving_discs_data*)0)->DiscWidth, IsInputMember },
{ MemberType_r32, "InnerRadius", (u64)&((revolving_discs_data*)0)->InnerRadius, IsInputMember },
{ MemberType_r32, "OuterRadius", (u64)&((revolving_discs_data*)0)->OuterRadius, IsInputMember },
{ MemberType_v4, "Color", (u64)&((revolving_discs_data*)0)->Color, IsInputMember },
{ MemberType_NODE_COLOR_BUFFER, "ResultLEDs", (u64)&((revolving_discs_data*)0)->ResultLEDs, IsOutputMember},
};
node_specification NodeSpecifications[] = { node_specification NodeSpecifications[] = {
{ NodeType_FloatValue, "FloatValue", 10, MemberList_float_value_data, 8, 2, false},
{ NodeType_VectorValue, "VectorValue", 11, MemberList_vector_data, 32, 5, false},
{ NodeType_MultiplyNodeProc, "MultiplyNodeProc", 16, MemberList_multiply_data, 12, 3, false},
{ NodeType_AddNodeProc, "AddNodeProc", 11, MemberList_add_data, 48, 3, false},
{ NodeType_SinWave, "SinWave", 7, MemberList_sin_wave_data, 20, 4, false},
{ NodeType_MultiplyPatterns, "MultiplyPatterns", 16, MemberList_multiply_patterns_data, 60, 3, false},
{ NodeType_OutputNode, "OutputNode", 10, MemberList_output_node_data, 20, 1, false},
{ NodeType_SolidColorProc, "SolidColorProc", 14, MemberList_solid_color_data, 36, 2, false},
{ NodeType_VerticalColorFadeProc, "VerticalColorFadeProc", 21, MemberList_vertical_color_fade_data, 44, 4, false},
{ NodeType_RevolvingDiscs, "RevolvingDiscs", 14, MemberList_revolving_discs_data, 60, 8, false},
}; };
s32 NodeSpecificationsCount = 10; s32 NodeSpecificationsCount = 0;
internal void CallNodeProc(u32 SpecificationIndex, u8* Data, led* LEDs, s32 LEDsCount, r32 DeltaTime) internal void CallNodeProc(u32 SpecificationIndex, u8* Data, led* LEDs, s32 LEDsCount, r32 DeltaTime)
{ {
node_specification Spec = NodeSpecifications[SpecificationIndex]; node_specification Spec = NodeSpecifications[SpecificationIndex];
switch (Spec.Type) switch (Spec.Type)
{ {
case NodeType_FloatValue: { FloatValue((float_value_data*)Data, DeltaTime); } break;
case NodeType_VectorValue: { VectorValue((vector_data*)Data, DeltaTime); } break;
case NodeType_MultiplyNodeProc: { MultiplyNodeProc((multiply_data*)Data, DeltaTime); } break;
case NodeType_AddNodeProc: { AddNodeProc((add_data*)Data, DeltaTime); } break;
case NodeType_SinWave: { SinWave((sin_wave_data*)Data, DeltaTime); } break;
case NodeType_MultiplyPatterns: { MultiplyPatterns((multiply_patterns_data*)Data, DeltaTime); } break;
case NodeType_OutputNode: { OutputNode((output_node_data*)Data, DeltaTime); } break;
case NodeType_SolidColorProc: { SolidColorProc((solid_color_data*)Data, DeltaTime); } break;
case NodeType_VerticalColorFadeProc: { VerticalColorFadeProc((vertical_color_fade_data*)Data, DeltaTime); } break;
case NodeType_RevolvingDiscs: { RevolvingDiscs((revolving_discs_data*)Data, DeltaTime); } break;
} }
} }

View File

@ -1,5 +1,69 @@
TODO FOLDHAUS TODO FOLDHAUS
Ground Up Reengineering
- Metaprogramming
- refactor for speed
- use #include statements to crawl through the codebase
- generalize the system
- panels metaprogramming
- Rendering
- OpenGL 3
- Vertex Buffers
- Layers
- Lighting
- Clipping (with error checking)
- Asset Loading
- images
- icon system
- Sculptures
- cache led vertex buffers
- custom sculpture update functions (for motion)
- placing sculptures
- editing sculpture files (change universe output)
- Network
- Artnet
- Universe offsets (per sculpture)
- Interface
- Layout functionality
- styling
- text input
- lister with icon options
- Sculpture View
- mouse spatial interaction - handles, and hover for info
- debug capabilities (toggle strip/led/universe colors)
- Animation System
- snapping clips
- blending between animation
- layers
- layer masks by sculpture
- blend modes
- Node System
- automatic node layout
- blending node layouts
- workspace -> animation block
- generating node workspace as code
- compiling node workspace
- hotload compiled pattern sets
- Serialization
- saving scenes
- saving node graphs
- saving animation timelines
- saving projects
- Settings
- Platform Layer
- Mac Platform Layer
Reimplement Node View Reimplement Node View
- probably want to take a fresh pass at nodes all together - probably want to take a fresh pass at nodes all together