assembly_parser now uses the standard parser
This commit is contained in:
parent
55284cde25
commit
e4266ba1ef
|
@ -45,362 +45,36 @@ enum assembly_field
|
|||
AssemblyField_Count,
|
||||
};
|
||||
|
||||
global char* AssemblyFieldIdentifiers[] = {
|
||||
"assembly_name", // AssemblyField_AssemblyName
|
||||
"assembly_scale", // AssemblyField_AssemblyScale
|
||||
"assembly_center", // AssemblyField_AssemblyCenter
|
||||
"led_strip_count", // AssemblyField_LedStripCount
|
||||
"output_mode", // AssemblyField_OutputMode
|
||||
global gs_const_string AssemblyFieldIdentifiers[] = {
|
||||
ConstString("assembly_name"), // AssemblyField_AssemblyName
|
||||
ConstString("assembly_scale"), // AssemblyField_AssemblyScale
|
||||
ConstString("assembly_center"), // AssemblyField_AssemblyCenter
|
||||
ConstString("led_strip_count"), // AssemblyField_LedStripCount
|
||||
ConstString("output_mode"), // AssemblyField_OutputMode
|
||||
|
||||
"led_strip", // AssemblyField_LedStrip
|
||||
ConstString("led_strip"), // AssemblyField_LedStrip
|
||||
|
||||
"output_sacn", // AssemblyField_OutputSACN
|
||||
"start_universe", // AssemblyField_SACN_StartUniverse
|
||||
"start_channel", // AssemblyField_SACN_StartChannel
|
||||
ConstString("output_sacn"), // AssemblyField_OutputSACN
|
||||
ConstString("start_universe"), // AssemblyField_SACN_StartUniverse
|
||||
ConstString("start_channel"), // AssemblyField_SACN_StartChannel
|
||||
|
||||
"output_uart", // AssemblyField_OutputUART
|
||||
"channel", // AssemblyField_UART_Channel
|
||||
"com_port", // AssemblyField_UART_ComPort
|
||||
ConstString("output_uart"), // AssemblyField_OutputUART
|
||||
ConstString("channel"), // AssemblyField_UART_Channel
|
||||
ConstString("com_port"), // AssemblyField_UART_ComPort
|
||||
|
||||
"point_placement_type", // AssemblyField_PointPlacementType
|
||||
"interpolate_points", // AssemblyField_InterpolatePoints
|
||||
"start", // AssemblyField_Start
|
||||
"end", // AssemblyField_End
|
||||
ConstString("point_placement_type"), // AssemblyField_PointPlacementType
|
||||
ConstString("interpolate_points"), // AssemblyField_InterpolatePoints
|
||||
ConstString("start"), // AssemblyField_Start
|
||||
ConstString("end"), // AssemblyField_End
|
||||
|
||||
"led_count", // AssemblyField_LedCount
|
||||
ConstString("led_count"), // AssemblyField_LedCount
|
||||
|
||||
"tags_count", // AssemblyField_TagCount
|
||||
"tag", // AssemblyField_Tag
|
||||
"name", // AssemblyField_Name
|
||||
"value", // AssemblyField_Value
|
||||
ConstString("tags_count"), // AssemblyField_TagCount
|
||||
ConstString("tag"), // AssemblyField_Tag
|
||||
ConstString("name"), // AssemblyField_Name
|
||||
ConstString("value"), // AssemblyField_Value
|
||||
};
|
||||
|
||||
struct assembly_error_list
|
||||
{
|
||||
gs_string String;
|
||||
assembly_error_list* Next;
|
||||
};
|
||||
|
||||
struct assembly_tokenizer
|
||||
{
|
||||
gs_string Text;
|
||||
char* At;
|
||||
|
||||
gs_const_string FileName;
|
||||
u32 LineNumber;
|
||||
|
||||
bool ParsingIsValid;
|
||||
|
||||
gs_memory_arena* ErrorArena;
|
||||
assembly_error_list* ErrorsRoot;
|
||||
assembly_error_list* ErrorsTail;
|
||||
};
|
||||
|
||||
internal bool
|
||||
AtValidPosition(assembly_tokenizer* T)
|
||||
{
|
||||
u64 Offset = T->At - T->Text.Str;
|
||||
bool Result = (Offset < T->Text.Length);
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal void
|
||||
AdvanceChar(assembly_tokenizer* T)
|
||||
{
|
||||
if (IsNewline(T->At[0]))
|
||||
{
|
||||
T->LineNumber += 1;
|
||||
}
|
||||
T->At++;
|
||||
}
|
||||
|
||||
internal void
|
||||
EatWhitespace(assembly_tokenizer* T)
|
||||
{
|
||||
while(AtValidPosition(T) && IsNewlineOrWhitespace(T->At[0]))
|
||||
{
|
||||
AdvanceChar(T);
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
EatToNewLine(assembly_tokenizer* T)
|
||||
{
|
||||
while(AtValidPosition(T) && !IsNewline(T->At[0]))
|
||||
{
|
||||
AdvanceChar(T);
|
||||
}
|
||||
EatWhitespace(T);
|
||||
}
|
||||
|
||||
internal bool
|
||||
AdvanceIfTokenEquals(assembly_tokenizer* T, char* Value)
|
||||
{
|
||||
bool Result = true;
|
||||
|
||||
char* TAt = T->At;
|
||||
char* VAt = Value;
|
||||
while (*VAt != 0)
|
||||
{
|
||||
if (*TAt != *VAt)
|
||||
{
|
||||
Result = false;
|
||||
break;
|
||||
}
|
||||
TAt += 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)
|
||||
{
|
||||
T->At = TAt;
|
||||
EatWhitespace(T);
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal void
|
||||
TokenizerPushError(assembly_tokenizer* T, char* ErrorString)
|
||||
{
|
||||
// NOTE(Peter): We can make this more expressive if we need to
|
||||
assembly_error_list* Error = PushStruct(T->ErrorArena, assembly_error_list);
|
||||
Error->String = PushString(T->ErrorArena, 512);
|
||||
PrintF(&Error->String, "%S(%d): %s", T->FileName, T->LineNumber, ErrorString);
|
||||
SLLPushOrInit(T->ErrorsRoot, T->ErrorsTail, Error);
|
||||
T->ParsingIsValid = false;
|
||||
|
||||
// NOTE(Peter): I'm not sure this is the best idea, but at least this way,
|
||||
// if there's multiple errors, you'll get a number of them, rather than
|
||||
// a bunch of erroneous errors happening on the same line
|
||||
EatToNewLine(T);
|
||||
}
|
||||
|
||||
#define PARSER_FIELD_REQUIRED true
|
||||
#define PARSER_FIELD_OPTIONAL false
|
||||
|
||||
internal bool
|
||||
ReadFieldIdentifier(assembly_field Field, assembly_tokenizer* T, bool Required = true)
|
||||
{
|
||||
bool Result = false;
|
||||
if (AdvanceIfTokenEquals(T, AssemblyFieldIdentifiers[Field]))
|
||||
{
|
||||
if (AdvanceIfTokenEquals(T, ":"))
|
||||
{
|
||||
Result = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We always throw an error if we get this far because we know you were trying to
|
||||
// open the identifier
|
||||
TokenizerPushError(T, "Field identifier is missing a colon");
|
||||
}
|
||||
}
|
||||
else if (Required)
|
||||
{
|
||||
TokenizerPushError(T, "Field Identifier Invalid");
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal bool
|
||||
ReadFieldEnd(assembly_tokenizer* T)
|
||||
{
|
||||
bool Result = AdvanceIfTokenEquals(T, ";");
|
||||
if (Result)
|
||||
{
|
||||
EatWhitespace(T);
|
||||
}
|
||||
else
|
||||
{
|
||||
TokenizerPushError(T, "Missing a semicolon");
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal gs_string
|
||||
ReadString(assembly_tokenizer* T)
|
||||
{
|
||||
gs_string Result = {};
|
||||
if (AdvanceIfTokenEquals(T, "\""))
|
||||
{
|
||||
char* StringStart = T->At;
|
||||
while(AtValidPosition(T) && T->At[0] != '\"')
|
||||
{
|
||||
T->At++;
|
||||
}
|
||||
Result.Str = StringStart;
|
||||
Result.Size = T->At - StringStart;
|
||||
Result.Length = Result.Size;
|
||||
if (AdvanceIfTokenEquals(T, "\""))
|
||||
{
|
||||
// Success
|
||||
}
|
||||
else
|
||||
{
|
||||
TokenizerPushError(T, "String not closed with a \"");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TokenizerPushError(T, "Expecting a string, but none was found");
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal gs_string
|
||||
GetNumberString(assembly_tokenizer* T)
|
||||
{
|
||||
gs_string Result = {};
|
||||
Result.Str = T->At;
|
||||
while(AtValidPosition(T) && IsNumericExtended(T->At[0]))
|
||||
{
|
||||
AdvanceChar(T);
|
||||
}
|
||||
Result.Length = T->At - Result.Str;
|
||||
Result.Size = Result.Length;
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal r32
|
||||
ReadFloat(assembly_tokenizer* T)
|
||||
{
|
||||
r32 Result = 0;
|
||||
gs_string NumberString = GetNumberString(T);
|
||||
Result = (r32)ParseFloat(NumberString.ConstString);
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal s32
|
||||
ReadInt(assembly_tokenizer* T)
|
||||
{
|
||||
s32 Result = 0;
|
||||
gs_string NumberString = GetNumberString(T);
|
||||
Result = (r32)ParseInt(NumberString.ConstString);
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal gs_string
|
||||
ReadStringField(assembly_field Field, assembly_tokenizer* T, gs_memory_arena* Arena, bool ShouldNullTerminate = false)
|
||||
{
|
||||
gs_string Result = {};
|
||||
if (ReadFieldIdentifier(Field, T))
|
||||
{
|
||||
gs_string ExistingString = ReadString(T);
|
||||
if (ReadFieldEnd(T))
|
||||
{
|
||||
// Success
|
||||
u64 Length = ExistingString.Length + (ShouldNullTerminate ? 1 : 0);
|
||||
Result = PushString(Arena, Length);
|
||||
PrintF(&Result, "%S", ExistingString);
|
||||
if (ShouldNullTerminate)
|
||||
{
|
||||
NullTerminate(&Result);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal r32
|
||||
ReadFloatField(assembly_field Field, assembly_tokenizer* T)
|
||||
{
|
||||
r32 Result = 0.0f;
|
||||
if (ReadFieldIdentifier(Field, T))
|
||||
{
|
||||
Result = ReadFloat(T);
|
||||
if (!ReadFieldEnd(T))
|
||||
{
|
||||
T->ParsingIsValid = false;
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal s32
|
||||
ReadIntField(assembly_field Field, assembly_tokenizer* T)
|
||||
{
|
||||
r32 Result = 0.0f;
|
||||
if (ReadFieldIdentifier(Field, T))
|
||||
{
|
||||
Result = ReadInt(T);
|
||||
if (!ReadFieldEnd(T))
|
||||
{
|
||||
T->ParsingIsValid = false;
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal v3
|
||||
ReadV3Field(assembly_field Field, assembly_tokenizer* T)
|
||||
{
|
||||
v3 Result = {};
|
||||
if (ReadFieldIdentifier(Field, T))
|
||||
{
|
||||
if (AdvanceIfTokenEquals(T, "("))
|
||||
{
|
||||
Result.x = ReadFloat(T);
|
||||
if (AdvanceIfTokenEquals(T, ","))
|
||||
{
|
||||
Result.y = ReadFloat(T);
|
||||
if (AdvanceIfTokenEquals(T, ","))
|
||||
{
|
||||
Result.z = ReadFloat(T);
|
||||
if (AdvanceIfTokenEquals(T, ")"))
|
||||
{
|
||||
if (!ReadFieldEnd(T))
|
||||
{
|
||||
T->ParsingIsValid = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TokenizerPushError(T, "Vector 3 doesn't end with a ')'");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TokenizerPushError(T, "Vector 3: unable to read a field");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TokenizerPushError(T, "Vector 3: unable to read a field");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TokenizerPushError(T, "Vector 3: unable to read a field");
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal bool
|
||||
ReadStructOpening(assembly_field Field, assembly_tokenizer* T, bool Required = true)
|
||||
{
|
||||
bool Result = false;
|
||||
if (ReadFieldIdentifier(Field, T, Required))
|
||||
{
|
||||
if (AdvanceIfTokenEquals(T, "{"))
|
||||
{
|
||||
Result = true;
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal bool
|
||||
ReadStructClosing(assembly_tokenizer* T)
|
||||
{
|
||||
bool Result = AdvanceIfTokenEquals(T, "};");
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal void
|
||||
StripSetTag(v2_strip* Strip, u32 TagIndex, gs_const_string TagName, gs_const_string TagValue)
|
||||
{
|
||||
|
@ -415,27 +89,26 @@ ParseAssemblyFile(assembly* Assembly, gs_const_string FileName, gs_string FileTe
|
|||
{
|
||||
Assembly->LedCountTotal = 0;
|
||||
|
||||
r32 Value = ParseFloat(ConstString("-2.355"));
|
||||
parser Parser = {0};
|
||||
Parser.String = FileText;
|
||||
Parser.Identifiers = &AssemblyFieldIdentifiers[0];
|
||||
Parser.IdentifiersCount = AssemblyField_Count;
|
||||
Parser.At = Parser.String.Str;
|
||||
Parser.LineStart = Parser.At;
|
||||
Parser.Arena = &Assembly->Arena;
|
||||
|
||||
assembly_tokenizer Tokenizer = {};
|
||||
Tokenizer.Text = FileText;
|
||||
Tokenizer.At = Tokenizer.Text.Str;
|
||||
Tokenizer.ParsingIsValid = true;
|
||||
Tokenizer.ErrorArena = Transient;
|
||||
Tokenizer.FileName = FileName;
|
||||
Assembly->Name = Parser_ReadStringValue(&Parser, AssemblyField_AssemblyName);
|
||||
Assembly->Scale = Parser_ReadR32Value(&Parser, AssemblyField_AssemblyScale);
|
||||
Assembly->Center = Parser_ReadV3Value(&Parser, AssemblyField_AssemblyCenter);
|
||||
Assembly->StripCount = Parser_ReadU32Value(&Parser, AssemblyField_LedStripCount);
|
||||
|
||||
Assembly->Name = ReadStringField(AssemblyField_AssemblyName, &Tokenizer, &Assembly->Arena);
|
||||
Assembly->Scale = ReadFloatField(AssemblyField_AssemblyScale, &Tokenizer);
|
||||
Assembly->Center = ReadV3Field(AssemblyField_AssemblyCenter, &Tokenizer);
|
||||
|
||||
Assembly->StripCount = ReadIntField(AssemblyField_LedStripCount, &Tokenizer);
|
||||
Assembly->Strips = PushArray(&Assembly->Arena, v2_strip, Assembly->StripCount);
|
||||
|
||||
gs_string OutputModeString = ReadStringField(AssemblyField_OutputMode, &Tokenizer, Transient);
|
||||
gs_string OutputModeString = Parser_ReadStringValue(&Parser, AssemblyField_OutputMode);
|
||||
if (StringsEqual(OutputModeString.ConstString, ConstString("UART")))
|
||||
{
|
||||
Assembly->OutputMode = NetworkProtocol_UART;
|
||||
Assembly->UARTComPort = ReadStringField(AssemblyField_UART_ComPort, &Tokenizer, &Assembly->Arena, true).ConstString;
|
||||
Assembly->UARTComPort = Parser_ReadStringValue(&Parser, AssemblyField_UART_ComPort, true).ConstString;
|
||||
}
|
||||
else if (StringsEqual(OutputModeString.ConstString, ConstString("SACN")))
|
||||
{
|
||||
|
@ -443,45 +116,44 @@ ParseAssemblyFile(assembly* Assembly, gs_const_string FileName, gs_string FileTe
|
|||
}
|
||||
else
|
||||
{
|
||||
TokenizerPushError(&Tokenizer, "Invalid output mode specified.");
|
||||
//TokenizerPushError(&Tokenizer, "Invalid output mode specified.");
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < Assembly->StripCount; i++)
|
||||
{
|
||||
v2_strip* StripAt = Assembly->Strips + i;
|
||||
if (ReadStructOpening(AssemblyField_LedStrip, &Tokenizer))
|
||||
if (Parser_ReadOpenStruct(&Parser, AssemblyField_LedStrip))
|
||||
{
|
||||
if (ReadStructOpening(AssemblyField_OutputSACN, &Tokenizer, PARSER_FIELD_OPTIONAL))
|
||||
if (Parser_ReadOpenStruct(&Parser, AssemblyField_OutputSACN))
|
||||
{
|
||||
StripAt->SACNAddr.StartUniverse = ReadIntField(AssemblyField_SACN_StartUniverse, &Tokenizer);
|
||||
StripAt->SACNAddr.StartChannel = ReadIntField(AssemblyField_SACN_StartChannel, &Tokenizer);
|
||||
StripAt->SACNAddr.StartUniverse = Parser_ReadU32Value(&Parser, AssemblyField_SACN_StartUniverse);
|
||||
StripAt->SACNAddr.StartChannel = Parser_ReadU32Value(&Parser, AssemblyField_SACN_StartChannel);
|
||||
|
||||
if (!ReadStructClosing(&Tokenizer))
|
||||
if (!Parser_ReadCloseStruct(&Parser))
|
||||
{
|
||||
TokenizerPushError(&Tokenizer, "Struct doesn't close where expected");
|
||||
//TokenizerPushError(&Tokenizer, "Struct doesn't close where expected");
|
||||
}
|
||||
}
|
||||
|
||||
if (ReadStructOpening(AssemblyField_OutputUART, &Tokenizer, PARSER_FIELD_OPTIONAL))
|
||||
if (Parser_ReadOpenStruct(&Parser, AssemblyField_OutputUART))
|
||||
{
|
||||
StripAt->UARTAddr.Channel = (u8)ReadIntField(AssemblyField_UART_Channel, &Tokenizer);
|
||||
StripAt->UARTAddr.Channel = (u8)Parser_ReadU32Value(&Parser, AssemblyField_UART_Channel);
|
||||
|
||||
if (!ReadStructClosing(&Tokenizer))
|
||||
if (!Parser_ReadCloseStruct(&Parser))
|
||||
{
|
||||
TokenizerPushError(&Tokenizer, "Struct doesn't close where expected");
|
||||
//TokenizerPushError(&Tokenizer, "Struct doesn't close where expected");
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(Peter): Need to store this
|
||||
gs_string PointPlacementType = ReadStringField(AssemblyField_PointPlacementType, &Tokenizer, &Assembly->Arena);
|
||||
gs_string PointPlacementType = Parser_ReadStringValue(&Parser, AssemblyField_PointPlacementType);
|
||||
// TODO(Peter): Switch on value of PointPlacementType
|
||||
if (ReadStructOpening(AssemblyField_InterpolatePoints, &Tokenizer))
|
||||
if (Parser_ReadOpenStruct(&Parser, AssemblyField_InterpolatePoints))
|
||||
{
|
||||
StripAt->StartPosition = ReadV3Field(AssemblyField_Start, &Tokenizer);
|
||||
StripAt->EndPosition = ReadV3Field(AssemblyField_End, &Tokenizer);
|
||||
if (!ReadStructClosing(&Tokenizer))
|
||||
StripAt->StartPosition = Parser_ReadV3Value(&Parser, AssemblyField_Start);
|
||||
StripAt->EndPosition = Parser_ReadV3Value(&Parser, AssemblyField_End);
|
||||
if (!Parser_ReadCloseStruct(&Parser))
|
||||
{
|
||||
Tokenizer.ParsingIsValid = false;
|
||||
// TODO(Peter): @ErrorHandling
|
||||
// Have this function prepend the filename and line number.
|
||||
// Create an error display popup window, or an error log window that takes over a panel automatically
|
||||
|
@ -489,48 +161,47 @@ ParseAssemblyFile(assembly* Assembly, gs_const_string FileName, gs_string FileTe
|
|||
}
|
||||
}
|
||||
|
||||
StripAt->LedCount = ReadIntField(AssemblyField_LedCount, &Tokenizer);
|
||||
StripAt->LedCount = Parser_ReadU32Value(&Parser, AssemblyField_LedCount);
|
||||
Assembly->LedCountTotal += StripAt->LedCount;
|
||||
|
||||
|
||||
StripAt->TagsCount = ReadIntField(AssemblyField_TagsCount, &Tokenizer);
|
||||
StripAt->TagsCount = Parser_ReadU32Value(&Parser, AssemblyField_TagsCount);
|
||||
// NOTE(pjs): Always add one tag to the input to leave room for the assembly name
|
||||
StripAt->TagsCount += 1;
|
||||
StripAt->Tags = PushArray(&Assembly->Arena, v2_tag, StripAt->TagsCount);
|
||||
StripSetTag(StripAt, 0, ConstString("assembly"), Assembly->Name.ConstString);
|
||||
for (u32 Tag = 1; Tag < StripAt->TagsCount; Tag++)
|
||||
{
|
||||
if (ReadStructOpening(AssemblyField_Tag, &Tokenizer))
|
||||
if (Parser_ReadOpenStruct(&Parser, AssemblyField_Tag))
|
||||
{
|
||||
// TODO(Peter): Need to store the gs_string somewhere we can look it up for display in the interface
|
||||
// right now they are stored in temp memory and won't persist
|
||||
gs_string TagName = ReadStringField(AssemblyField_Name, &Tokenizer, Transient);
|
||||
gs_string TagValue = ReadStringField(AssemblyField_Value, &Tokenizer, Transient);
|
||||
gs_string TagName = Parser_ReadStringValue(&Parser, AssemblyField_Name);
|
||||
gs_string TagValue = Parser_ReadStringValue(&Parser, AssemblyField_Value);
|
||||
StripSetTag(StripAt, Tag, TagName.ConstString, TagValue.ConstString);
|
||||
if (!ReadStructClosing(&Tokenizer))
|
||||
if (!Parser_ReadCloseStruct(&Parser))
|
||||
{
|
||||
TokenizerPushError(&Tokenizer, "Struct doesn't close where expected");
|
||||
//TokenizerPushError(&Tokenizer, "Struct doesn't close where expected");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TokenizerPushError(&Tokenizer, "Expected a struct opening, but none was found");
|
||||
//TokenizerPushError(&Tokenizer, "Expected a struct opening, but none was found");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!ReadStructClosing(&Tokenizer))
|
||||
if (!Parser_ReadCloseStruct(&Parser))
|
||||
{
|
||||
TokenizerPushError(&Tokenizer, "Struct doesn't close where expected");
|
||||
//TokenizerPushError(&Tokenizer, "Struct doesn't close where expected");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TokenizerPushError(&Tokenizer, "Expected a struct opening, but none was found");
|
||||
//TokenizerPushError(&Tokenizer, "Expected a struct opening, but none was found");
|
||||
}
|
||||
}
|
||||
|
||||
return Tokenizer.ParsingIsValid;
|
||||
return true; //Tokenizer.ParsingIsValid;
|
||||
}
|
||||
|
||||
#define ASSEMBLY_PARSER_CPP
|
||||
|
|
|
@ -245,7 +245,7 @@ Parser_ReadString(parser* P, u32 IdentIndex)
|
|||
}
|
||||
|
||||
internal gs_string
|
||||
Parser_ReadStringValue(parser* P, gs_const_string Ident)
|
||||
Parser_ReadStringValue(parser* P, gs_const_string Ident, bool ShouldNullTerminate = false)
|
||||
{
|
||||
// ident: "value";
|
||||
gs_string Result = {};
|
||||
|
@ -265,7 +265,16 @@ Parser_ReadStringValue(parser* P, gs_const_string Ident)
|
|||
if (Parser_AdvanceIfTokenEquals(P, ConstString("\"")) &&
|
||||
Parser_AdvanceIfLineEnd(P))
|
||||
{
|
||||
Result = PushStringF(P->Arena, FileString.Length, "%S", FileString);
|
||||
u32 StringLength = FileString.Length;
|
||||
if (ShouldNullTerminate)
|
||||
{
|
||||
StringLength += 1;
|
||||
}
|
||||
Result = PushStringF(P->Arena, StringLength, "%S", FileString);
|
||||
if (ShouldNullTerminate)
|
||||
{
|
||||
NullTerminate(&Result);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -277,10 +286,10 @@ Parser_ReadStringValue(parser* P, gs_const_string Ident)
|
|||
}
|
||||
|
||||
internal gs_string
|
||||
Parser_ReadStringValue(parser* P, u32 IdentIndex)
|
||||
Parser_ReadStringValue(parser* P, u32 IdentIndex, bool ShouldNullTerminate = false)
|
||||
{
|
||||
gs_const_string Ident = Parser_GetIdent(*P, IdentIndex);
|
||||
return Parser_ReadStringValue(P, Ident);
|
||||
return Parser_ReadStringValue(P, Ident, ShouldNullTerminate);
|
||||
}
|
||||
|
||||
internal bool
|
||||
|
@ -351,6 +360,15 @@ Parser_ReadU32Value(parser* P, u32 IdentIndex)
|
|||
return Parser_ReadU32Value(P, Ident);
|
||||
}
|
||||
|
||||
internal r32
|
||||
Parser_ReadR32(parser* P)
|
||||
{
|
||||
r32 Result = 0;
|
||||
gs_const_string NumStr = Parser_ReadNumberString(P);
|
||||
Result = (r32)ParseFloat(NumStr);
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal r32
|
||||
Parser_ReadR32Value(parser* P, gs_const_string Ident)
|
||||
{
|
||||
|
@ -359,15 +377,16 @@ Parser_ReadR32Value(parser* P, gs_const_string Ident)
|
|||
if (Parser_AdvanceIfTokenEquals(P, Ident) &&
|
||||
Parser_AdvanceIfTokenEquals(P, ConstString(":")))
|
||||
{
|
||||
gs_const_string NumStr = Parser_ReadNumberString(P);
|
||||
r32 Value = Parser_ReadR32(P);
|
||||
if (Parser_AdvanceIfLineEnd(P))
|
||||
{
|
||||
Result = (r32)ParseFloat(NumStr);
|
||||
Result = Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO(pjs): Error
|
||||
}
|
||||
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
@ -379,6 +398,43 @@ Parser_ReadR32Value(parser* P, u32 IdentIndex)
|
|||
return Parser_ReadR32Value(P, Ident);
|
||||
}
|
||||
|
||||
internal v3
|
||||
Parser_ReadV3Value(parser* P, gs_const_string Ident)
|
||||
{
|
||||
v3 Result = {0};
|
||||
if (Parser_AdvanceIfTokenEquals(P, Ident) &&
|
||||
Parser_AdvanceIfTokenEquals(P, ConstString(":")) &&
|
||||
Parser_AdvanceIfTokenEquals(P, ConstString("(")))
|
||||
{
|
||||
r32 X = Parser_ReadR32(P);
|
||||
Parser_AdvanceIfTokenEquals(P, ConstString(","));
|
||||
|
||||
r32 Y = Parser_ReadR32(P);
|
||||
Parser_AdvanceIfTokenEquals(P, ConstString(","));
|
||||
|
||||
r32 Z = Parser_ReadR32(P);
|
||||
if (Parser_AdvanceIfTokenEquals(P, ConstString(")")) &&
|
||||
Parser_AdvanceIfLineEnd(P))
|
||||
{
|
||||
Result.x = X;
|
||||
Result.y = Y;
|
||||
Result.z = Z;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO(pjs): error
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal v3
|
||||
Parser_ReadV3Value(parser* P, u32 IdentIndex)
|
||||
{
|
||||
gs_const_string Ident = Parser_GetIdent(*P, IdentIndex);
|
||||
return Parser_ReadV3Value(P, Ident);
|
||||
}
|
||||
|
||||
|
||||
#define FOLDHAUS_SERIALIZER_H
|
||||
#endif // FOLDHAUS_SERIALIZER_H
|
Loading…
Reference in New Issue