diff --git a/src/std/parser/parserlang.c b/src/std/parser/parserlang.c index 0d0a6c2..589cf25 100644 --- a/src/std/parser/parserlang.c +++ b/src/std/parser/parserlang.c @@ -39,24 +39,15 @@ void ARC_ParserLang_InitLexerRulesFn(ARC_Lexer *lexer){ ARC_String_Destroy(arrowString); } -/* - -> NEWLINE | | NEWLINE | LAMBDA - -> WHITESPACE ARROW WHITESPACE +void ARC_ParserLang_VectorDestroyVector(void *data){ + ARC_Vector *vector = (ARC_Vector *)data; + ARC_Vector_Destroy(vector); +} - -> WHITESPACE OR WHITESPACE | - -> WHITESPACE | - -> | - - -> ALPHA_UPPER_CHAR - -> | LAMBDA - -> ALPHA_UPPER_CHAR | UNDERSCORE - - -> LESS_THAN GREATER_THAN - -> | UNDERSCORE - -> | LAMBDA - -> | NUMBER | UNDERSCORE - -> ALPHA_LOWER_CHAR | ALPHA_UPPER_CHAR -*/ +void ARC_ParserLang_VectorDestroyUInt32(void *data){ + uint32_t *uint = (uint32_t *)data; + free(uint); +} void ARC_ParserLang_VectorDestroyParserTagFn(void *data){ ARC_ParserTag *currentTag = (ARC_ParserTag *)data; @@ -113,11 +104,98 @@ void ARC_ParserLangParsedData_CreateTagString(ARC_String **tagString, ARC_Parser } } +/* + -> WHITESPACE | +*/ +void ARC_ParserLangParsedData_GetArgumentTag(ARC_Vector *orTokensOrTags, ARC_ParserTagToken *tagToken, ARC_ParserLang_GetIdFn *getIdFn){ + for(uint32_t index = 0; index < ARC_Vector_GetSize(tagToken->tagTokens); index++){ + ARC_ParserTagToken *childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(tagToken->tagTokens, index); + + //switch variables + ARC_String *tagOrConstantString = NULL; + uint32_t *id = NULL; + + switch(childTagToken->id){ + case ARC_PARSERLANG_ARGUMENT: + //recurse to check all the arguments + ARC_ParserLangParsedData_GetArgumentTag(orTokensOrTags, childTagToken, getIdFn); + continue; + + case ARC_PARSERLANG_TAG_OR_CONSTANT: + //get the id of the tag/constant + ARC_ParserLangParsedData_RecurseStringAdd(&tagOrConstantString, childTagToken); + id = (uint32_t *)malloc(sizeof(uint32_t)); + *id = (*getIdFn)(tagOrConstantString); + + //add the id to the matching or vector + ARC_Vector_Add(orTokensOrTags, (void *)id); + + //cleanup + ARC_String_Destroy(tagOrConstantString); + continue; + + default: + //this should only be whitespace + continue; + } + } +} + +/* + -> WHITESPACE OR WHITESPACE | +*/ void ARC_ParserLangParsedData_GetArgumentsTag(ARC_Vector *tokensOrTags, ARC_ParserTagToken *tagToken, ARC_ParserLang_GetIdFn *getIdFn){ for(uint32_t index = 0; index < ARC_Vector_GetSize(tagToken->tagTokens); index++){ - //TODO: write this - //ARC_ParserTagToken *childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(tagToken->tagTokens, index); + ARC_ParserTagToken *childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(tagToken->tagTokens, index); + //switch variables + ARC_String *tagOrConstantString; + ARC_String_Create(&tagOrConstantString, NULL, 0); + + uint32_t *id = NULL; + uint32_t tokensOrTagsIndex = 0; + ARC_Vector *orTokensOrTags = NULL; + + ARC_Vector_DestroyDataFn destroyUint32Fn = ARC_ParserLang_VectorDestroyUInt32; + + switch(childTagToken->id){ + case ARC_PARSERLANG_ARGUMENT: + continue; + + case ARC_PARSERLANG_TOKEN_OR_ID: + //add a new vector to tagsOrTokens for the or statment + ARC_Vector_Create(&orTokensOrTags, NULL, &destroyUint32Fn); + + //add the first or vector to the tokensOrTags + ARC_Vector_Add(tokensOrTags, (void *)orTokensOrTags); + continue; + + case ARC_PARSERLANG_ARGUMENTS: + //recurse to check all the arguments + ARC_ParserLangParsedData_GetArgumentsTag(tokensOrTags, childTagToken, getIdFn); + continue; + + case ARC_PARSERLANG_TAG_OR_CONSTANT: + //get the id of the tag/constant + ARC_ParserLangParsedData_RecurseStringAdd(&tagOrConstantString, childTagToken); + id = (uint32_t *)malloc(sizeof(uint32_t)); + *id = (*getIdFn)(tagOrConstantString); + + //get the last vector within tokens or tags to add the tag/constant to + tokensOrTagsIndex = ARC_Vector_GetSize(tokensOrTags); + orTokensOrTags = (ARC_Vector *)ARC_Vector_Get(tokensOrTags, tokensOrTagsIndex - 1); + + //add the id to the last or vector + ARC_Vector_Add(orTokensOrTags, (void *)id); + + //cleanup + ARC_String_Destroy(tagOrConstantString); + continue; + + default: + //this should only be whitespace + continue; + } } } @@ -140,20 +218,24 @@ void ARC_ParserLangParsedData_CreateBodyTag(ARC_ParserTag **tag, ARC_ParserTagTo ARC_String_Destroy(tagIdString); /* ~ Tokens Or Tags Array ~ */ - //create a vector to store the tokens and tags in, we will not add a destroy as we will move those values to an array (instead of copying them) + //create a vector to store another vector of data ARC_Vector *tokensOrTags; - ARC_Vector_Create(&tokensOrTags, NULL, NULL); + ARC_Vector_DestroyDataFn destroyVectorFn = ARC_ParserLang_VectorDestroyVector; + ARC_Vector_Create(&tokensOrTags, NULL, &destroyVectorFn); + + //create vector within the tokens or tags vector to store the or rule in + ARC_Vector *orTokensOrTags; + ARC_Vector_DestroyDataFn destroyUint32Fn = ARC_ParserLang_VectorDestroyUInt32; + ARC_Vector_Create(&orTokensOrTags, NULL, &destroyUint32Fn); + + //add the first or vector to the tokensOrTags + ARC_Vector_Add(tokensOrTags, (void *)orTokensOrTags); //skipping whitespace and arrow tokens, the arguments index starts at 4 ARC_ParserTagToken *argumentsToken = (ARC_ParserTagToken *)ARC_Vector_Get(tagToken->tagTokens, 4); ARC_ParserLangParsedData_GetArgumentsTag(tokensOrTags, argumentsToken, getIdFn); - //move the data from the vector to an array - bodyTag->tokensOrTagsSize = ARC_Vector_GetSize(tokensOrTags); - bodyTag->tokensOrTags = (uint32_t **)malloc(sizeof(uint32_t *) * bodyTag->tokensOrTagsSize); - for(uint32_t index = 0; index < bodyTag->tokensOrTagsSize; index++){ - bodyTag->tokensOrTags[index] = (uint32_t *)ARC_Vector_Get(tokensOrTags, index); - } + //TODO: move the data from the vector to an array //cleanup ARC_Vector_Destroy(tokensOrTags); diff --git a/tests/std/parser.c b/tests/std/parser.c index 357a8bd..43a1cfe 100644 --- a/tests/std/parser.c +++ b/tests/std/parser.c @@ -201,6 +201,7 @@ ARC_TEST(Parser_Basic_GetParsedValue){ /* ~ parserlang tests ~ */ uint32_t TEST_ParserLang_GetIdFn(ARC_String *constant){ + printf("tag: %s\n", constant->data); return 0; } @@ -209,7 +210,7 @@ ARC_TEST(Parser_ParserLang_BasicTest){ ARC_Parser_CreateAsParserLang(&parser, TEST_ParserLang_GetIdFn); ARC_String *tempString; - ARC_String_CreateWithStrlen(&tempString, " -> \n"); + ARC_String_CreateWithStrlen(&tempString, " -> CHAR \n"); //this destroys string, so no need for cleanup ARC_Parser_Parse(parser, &tempString);