Lumenarium/src/app/engine/foldhaus_serializer.h

384 lines
8.7 KiB
C

//
// File: foldhaus_serializer.h
// Author: Peter Slattery
// Creation Date: 2020-10-09
//
#ifndef FOLDHAUS_SERIALIZER_H
struct serializer
{
gs_string String;
u32 Indent;
gs_const_string* Identifiers;
u32 IdentifiersCount;
};
internal gs_const_string
Serializer_GetIdent(serializer* Serializer, u32 Index)
{
gs_const_string Result = Serializer->Identifiers[Index];
return Result;
}
// Serializing
internal void
Serializer_WriteIndent(serializer* Serializer)
{
for (u32 i = 0; i < Serializer->Indent; i++)
{
AppendPrintF(&Serializer->String, " ");
}
}
internal void
Serializer_WriteF(serializer* Serializer, char* Format, ...)
{
Serializer_WriteIndent(Serializer);
va_list Args;
va_start(Args, Format);
PrintFArgsList(&Serializer->String, Format, Args);
va_end(Args);
}
internal void
Serializer_OpenStruct(serializer* Serializer, gs_const_string StructName)
{
Serializer_WriteF(Serializer, "%S:{\n", StructName);
Serializer->Indent++;
}
internal void
Serializer_OpenStruct(serializer* Serializer, u32 StructIdentifier)
{
gs_const_string Ident = Serializer_GetIdent(Serializer, StructIdentifier);
Serializer_WriteF(Serializer, "%S:{\n", Ident);
Serializer->Indent++;
}
internal void
Serializer_CloseStruct(serializer* Serializer)
{
Serializer->Indent--;
Serializer_WriteF(Serializer, "};\n");
}
internal void
Serializer_WriteValue(serializer* Serializer, gs_const_string Ident, gs_const_string Value)
{
Serializer_WriteF(Serializer, "%S: %S;\n", Ident, Value);
}
internal void
Serializer_WriteValue(serializer* Serializer, u32 IdentIndex, gs_const_string Value)
{
gs_const_string Ident = Serializer_GetIdent(Serializer, IdentIndex);
Serializer_WriteValue(Serializer, Ident, Value);
}
internal void
Serializer_WriteValue(serializer* Serializer, gs_const_string Ident, u32 Value)
{
Serializer_WriteF(Serializer, "%S: %d;\n", Ident, Value);
}
internal void
Serializer_WriteValue(serializer* Serializer, u32 IdentIndex, u32 Value)
{
gs_const_string Ident = Serializer_GetIdent(Serializer, IdentIndex);
Serializer_WriteValue(Serializer, Ident, Value);
}
internal void
Serializer_WriteValue(serializer* Serializer, gs_const_string Ident, r32 Value)
{
Serializer_WriteF(Serializer, "%S: %f;\n", Ident, Value);
}
internal void
Serializer_WriteValue(serializer* Serializer, u32 IdentIndex, r32 Value)
{
gs_const_string Ident = Serializer_GetIdent(Serializer, IdentIndex);
Serializer_WriteValue(Serializer, Ident, Value);
}
internal void
Serializer_WriteStringValue(serializer* Serializer, gs_const_string Ident, gs_const_string Value)
{
Serializer_WriteF(Serializer, "%S: \"%S\";\n", Ident, Value);
}
internal void
Serializer_WriteStringValue(serializer* Serializer, u32 IdentIndex, gs_const_string Value)
{
gs_const_string Ident = Serializer_GetIdent(Serializer, IdentIndex);
Serializer_WriteStringValue(Serializer, Ident, Value);
}
internal void
Serializer_WriteV3Value(serializer* Serializer, gs_const_string Ident, v3 Value)
{
Serializer_WriteF(Serializer, "%S: (%f, %f, %f);\n", Ident, Value.x, Value.y, Value.z);
}
internal void
Serializer_WriteV3Value(serializer* Serializer, u32 IdentIndex, v3 Value)
{
gs_const_string Ident = Serializer_GetIdent(Serializer, IdentIndex);
Serializer_WriteV3Value(Serializer, Ident, Value);
}
// Parsing
struct parser
{
gs_string String;
gs_const_string* Identifiers;
u32 IdentifiersCount;
u32 Line;
char* LineStart;
char* At;
gs_memory_arena* Arena;
};
internal gs_const_string
Parser_GetIdent(parser Parser, u32 Index)
{
gs_const_string Result = Parser.Identifiers[Index];
return Result;
}
internal bool
Parser_AtValidPosition(parser Parser)
{
u64 Offset = Parser.At - Parser.String.Str;
bool Result = (Offset < Parser.String.Length);
return Result;
}
internal void
Parser_AdvanceChar(parser* P)
{
if (IsNewline(P->At[0]))
{
P->Line += 1;
P->LineStart = P->At + 1;
}
P->At++;
}
internal void
Parser_EatWhitespace(parser* P)
{
while(Parser_AtValidPosition(*P) && IsNewlineOrWhitespace(P->At[0]))
{
Parser_AdvanceChar(P);
}
}
internal void
Parser_EatToNewLine(parser* P)
{
while(Parser_AtValidPosition(*P) && !IsNewline(P->At[0]))
{
Parser_AdvanceChar(P);
}
Parser_EatWhitespace(P);
}
internal bool
Parser_AdvanceIfTokenEquals(parser* P, gs_const_string Value)
{
bool Result = true;
char* PAt = P->At;
char* VAt = Value.Str;
while (*VAt != 0)
{
if (*PAt != *VAt)
{
Result = false;
break;
}
PAt += 1;
VAt += 1;
}
// TODO(Peter): What if the token is a subset of Value? ie. this would return true for
// T->At = hello_world and Value = hello_
// But the next token we read would fail
if (Result)
{
P->At = PAt;
Parser_EatWhitespace(P);
}
return Result;
}
internal bool
Parser_AdvanceIfLineEnd(parser* P)
{
bool Result = Parser_AdvanceIfTokenEquals(P, ConstString(";"));
return Result;
}
internal bool
Parser_ReadString(parser* P, gs_const_string String)
{
// string;
bool Result = Parser_AdvanceIfTokenEquals(P, String);
Result &= Parser_AdvanceIfLineEnd(P);
return Result;
}
internal bool
Parser_ReadString(parser* P, u32 IdentIndex)
{
gs_const_string Ident = Parser_GetIdent(*P, IdentIndex);
return Parser_ReadString(P, Ident);
}
internal gs_string
Parser_ReadStringValue(parser* P, gs_const_string Ident)
{
// ident: "value";
gs_string Result = {};
if (Parser_AdvanceIfTokenEquals(P, Ident) &&
Parser_AdvanceIfTokenEquals(P, ConstString(":")) &&
Parser_AdvanceIfTokenEquals(P, ConstString("\"")))
{
gs_const_string FileString = {0};
FileString.Str = P->At;
while (Parser_AtValidPosition(*P) && P->At[0] != '"')
{
Parser_AdvanceChar(P);
}
FileString.Length = P->At - FileString.Str;
if (Parser_AdvanceIfTokenEquals(P, ConstString("\"")) &&
Parser_AdvanceIfLineEnd(P))
{
Result = PushStringF(P->Arena, FileString.Length, "%S", FileString);
}
else
{
// TODO(pjs): Error
}
}
return Result;
}
internal gs_string
Parser_ReadStringValue(parser* P, u32 IdentIndex)
{
gs_const_string Ident = Parser_GetIdent(*P, IdentIndex);
return Parser_ReadStringValue(P, Ident);
}
internal bool
Parser_ReadOpenStruct(parser* P, gs_const_string Ident)
{
// ident: {
bool Result = Parser_AdvanceIfTokenEquals(P, Ident);
Result &= Parser_AdvanceIfTokenEquals(P, ConstString(":"));
Result &= Parser_AdvanceIfTokenEquals(P, ConstString("{"));
return Result;
}
internal bool
Parser_ReadOpenStruct(parser* P, u32 IdentIndex)
{
gs_const_string Ident = Parser_GetIdent(*P, IdentIndex);
return Parser_ReadOpenStruct(P, Ident);
}
internal bool
Parser_ReadCloseStruct(parser* P)
{
// }
bool Result = Parser_AdvanceIfTokenEquals(P, ConstString("}"));
Result &= Parser_AdvanceIfLineEnd(P);
return Result;
}
internal gs_const_string
Parser_ReadNumberString(parser* P)
{
gs_const_string Result = {};
Result.Str = P->At;
while(Parser_AtValidPosition(*P) && IsNumericExtended(P->At[0]))
{
Parser_AdvanceChar(P);
}
Result.Length = P->At - Result.Str;
return Result;
}
internal u32
Parser_ReadU32Value(parser* P, gs_const_string Ident)
{
// ident: value;
u32 Result = 0;
if (Parser_AdvanceIfTokenEquals(P, Ident) &&
Parser_AdvanceIfTokenEquals(P, ConstString(":")))
{
gs_const_string NumStr = Parser_ReadNumberString(P);
if (Parser_AdvanceIfLineEnd(P))
{
Result = (u32)ParseInt(NumStr);
}
else
{
// TODO(pjs): Error
}
}
return Result;
}
internal u32
Parser_ReadU32Value(parser* P, u32 IdentIndex)
{
gs_const_string Ident = Parser_GetIdent(*P, IdentIndex);
return Parser_ReadU32Value(P, Ident);
}
internal r32
Parser_ReadR32Value(parser* P, gs_const_string Ident)
{
// ident: value;
r32 Result = 0;
if (Parser_AdvanceIfTokenEquals(P, Ident) &&
Parser_AdvanceIfTokenEquals(P, ConstString(":")))
{
gs_const_string NumStr = Parser_ReadNumberString(P);
if (Parser_AdvanceIfLineEnd(P))
{
Result = (r32)ParseFloat(NumStr);
}
else
{
// TODO(pjs): Error
}
}
return Result;
}
internal u32
Parser_ReadR32Value(parser* P, u32 IdentIndex)
{
gs_const_string Ident = Parser_GetIdent(*P, IdentIndex);
return Parser_ReadR32Value(P, Ident);
}
#define FOLDHAUS_SERIALIZER_H
#endif // FOLDHAUS_SERIALIZER_H