From c598f3e1062f53ae4fd3b256c7dab44e18f544db Mon Sep 17 00:00:00 2001 From: herbglitch Date: Mon, 23 Dec 2024 00:16:32 -0700 Subject: [PATCH] outlined chemical --- include/arc/std/chemical.h | 92 ++++++++++- src/std/chemical.c | 310 +++++++------------------------------ tests/std/chemical.c | 2 +- 3 files changed, 150 insertions(+), 254 deletions(-) diff --git a/include/arc/std/chemical.h b/include/arc/std/chemical.h index 2d44df3..93e5dc8 100644 --- a/include/arc/std/chemical.h +++ b/include/arc/std/chemical.h @@ -6,8 +6,11 @@ extern "C" { #endif #include +#include "arc/std/parser.h" /* + * TODO: note here in header that this uses parser + * TODO: note here in header that group being used is persistant -> | | -> LEFT_CURLY_BRACE RIGHT_CURLY_BRACE @@ -29,19 +32,102 @@ extern "C" { -> SPACE | TAB | NEWLINE | LAMBDA */ +/** + * @brief TODO: write this +*/ +typedef void (* ARC_ChemicalData_CopyToTypeFn)(void **data, ARC_ParserTagToken *parsedData); + +/** + * @brief TODO: write this +*/ +typedef void (* ARC_ParserCSV_DestroyTypeFn)(void *data); + +/** + * @brief a function to read a key from string to a ARC_ConfigTypeTemplate + * + * @param config ARC_Config to store data to + * @param string ARC_String of data that is being read in + * @param value value that is read in + * + * @note use ARC_Config_StoreValue(ARC_Config *config, ARC_String *name, void *value); to store a value to the config + * if there is an error, set arc_errno + * + * @return 0 if value not a reference, 1 if value is a reference + */ +//typedef uint8_t (* ARC_ConfigKeyRead)(ARC_Config* config, ARC_String *string, void **value); + +/** + * @brief a function to delete a value from a key in ARC_Config + * + * @param config ARC_Config that can be used to check for references in data + * @param value pointer of data to be deleted + * + * @note this function can be NULL if memory does not need to be cleaned for this type + * if there is an error, set arc_errno + */ +//typedef void (* ARC_ConfigKeyDelete)(ARC_Config* config, ARC_String *string, void *value); + +/** + * @brief TODO: write this +*/ typedef struct ARC_Chemical ARC_Chemical; /** * @brief TODO: write this */ -void ARC_Chemical_Create(ARC_Chemical **parser); - +void ARC_Chemical_Create(ARC_Chemical **chemical); /** * @brief TODO: write this */ -void ARC_Chemical_Destroy(ARC_Chemical *parser); +void ARC_Chemical_Destroy(ARC_Chemical *chemical); +/** + * @brief TODO: write this +*/ +void ARC_Chemical_RegisterType(ARC_Chemical *chemical, ARC_String *typeName, ARC_ChemicalData_CopyToTypeFn *copyToTypeFn, ARC_ParserCSV_DestroyTypeFn destroyTypeFn); + +/** + * @brief sets current group in config + * + * @note ARC_Chemical_Get will use this set group + * + * @param[in] chemical ARC_Config we are setting current group in + * @param[in] groupname name of group that will be set + */ +void ARC_Chemical_SetGroup(ARC_Chemical *chemical, ARC_String *groupName); + +/** + * @brief get a value from a given keyname + * + * @note name may be prefaced with :: to specify group + * + * @param[in] chemical ARC_Chemical to get value from + * @param[in] element name of a variable that has been read in + * + * @return the stored element on success, or NULL on failure + */ +void *ARC_Chemical_Get(ARC_Chemical *chemical, ARC_String *element); + +/** + * @brief TODO: write this +*/ +void ARC_Chemical_LoadFromString(ARC_String *path); + +/** + * @brief TODO: write this +*/ +void ARC_Chemical_LoadFromFile(ARC_String *path); + +/** + * @brief TODO: write this +*/ +void ARC_Chemical_UnloadFromString(ARC_String *data); + +/** + * @brief TODO: write this +*/ +void ARC_Chemical_UnloadFromFile(ARC_String *data); #ifdef __cplusplus } diff --git a/src/std/chemical.c b/src/std/chemical.c index f586235..8a79045 100644 --- a/src/std/chemical.c +++ b/src/std/chemical.c @@ -1,22 +1,22 @@ -#include "arc/std/parser/csv.h" +#include "arc/std/chemical.h" #include "arc/std/parser/helpers.h" #include "arc/std/bool.h" +#include "arc/std/hashtable.h" #include "arc/std/parser.h" #include #include #include -typedef struct ARC_ParserCSVUserData { - ARC_Bool header; - ARC_ParserCSV_CastTypeFn castTypeFn; - ARC_ParserCSV_DestroyTypeFn destroyTypeFn; -} ARC_ParserCSVUserData; +struct ARC_Chemical { + ARC_Parser *parser; -void ARC_ParserCSV_InitLexerRulesFn(ARC_Lexer *lexer){ + ARC_Hashtable *groups; +}; +void ARC_Chemical_InitLexerRulesFn(ARC_Lexer *lexer){ } -uint32_t ARC_ParserCSV_GetStringIdFn(ARC_String *string){ +uint32_t ARC_Chemical_GetStringIdFn(ARC_String *string){ if(ARC_String_EqualsCStringWithStrlen(string, "LAMBDA")){ return ARC_PARSER_TAG_LAMBDA; } @@ -24,266 +24,76 @@ uint32_t ARC_ParserCSV_GetStringIdFn(ARC_String *string){ return ~(uint32_t)0; } -void ARC_ParserCSVData_VectorDestroyVectorFn(void *data){ - ARC_Vector *vector = (ARC_Vector *)data; - ARC_Vector_Destroy(vector); -} - -void ARC_ParserCSVData_GetDataTag(ARC_Vector *dataVector, ARC_ParserTagToken *tagToken, ARC_ParserCSVUserData *userData){ - //cast the csv data back to its original type - ARC_ParserCSVUserData *csvUserData = (ARC_ParserCSVUserData *)userData; - - //loop through the tags either recursing to next body or adding data to vector - for(uint32_t index = 0; index < ARC_Vector_GetSize(tagToken->tagTokens); index++){ - ARC_ParserTagToken *childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(tagToken->tagTokens, index); - - ARC_String *stringData = NULL; - ARC_Vector *row = NULL; - uint32_t rowIndex = 0; - - switch(childTagToken->id){ - //recuse to run the next line - case ARC_PARSER_CSV_STRING: - //get the string of the data - ARC_String_Create(&stringData, NULL, 0); - ARC_ParserData_HelperRecurseStringAdd(&stringData, childTagToken); - - //move data string and cleanup - void *data = (void *)stringData; - - //get the last row vector - rowIndex = ARC_Vector_GetSize(dataVector) - 1; - row = (ARC_Vector *)ARC_Vector_Get(dataVector, rowIndex); - - //only call the userData cast type callback if it is not a header - if(rowIndex != 0 || csvUserData->header == ARC_False){ - data = NULL; - userData->castTypeFn(&data, stringData); - ARC_String_Destroy(stringData); - } - - //add the data to the row vector - ARC_Vector_Add(row, data); - continue; - - case ARC_PARSER_CSV_DATA: - ARC_ParserCSVData_GetDataTag(dataVector, childTagToken, userData); - continue; - - default: - //this should only be the case for the comma - continue; - } - } -} - -// -> NEWLINE | | NEWLINE | LAMBDA -void ARC_ParserCSVData_RunLineTag(ARC_Vector *dataVector, ARC_ParserTagToken *tagToken, ARC_ParserCSVUserData *userData){ - //loop through the tags either going to the next line or the next body - for(uint32_t index = 0; index < ARC_Vector_GetSize(tagToken->tagTokens); index++){ - ARC_ParserTagToken *childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(tagToken->tagTokens, index); - - ARC_Vector *row = NULL; - uint32_t rowIndex = 0; - - switch(childTagToken->id){ - //recuse to run the next line - case ARC_PARSER_CSV_LINE: - ARC_ParserCSVData_RunLineTag(dataVector, childTagToken, userData); - continue; - - //get the row data - case ARC_PARSER_CSV_DATA: - ARC_ParserCSVData_GetDataTag(dataVector, childTagToken, userData); - continue; - - //add a new row for each new line - case ARC_PARSER_CSV_CHAR_NEWLINE: - //check if current is not empty (no need to create another empty row) - rowIndex = ARC_Vector_GetSize(dataVector) - 1; - row = (ARC_Vector *)ARC_Vector_Get(dataVector, rowIndex); - if(ARC_Vector_GetSize(row) == 0){ - continue; - } - - //create and add a new row - ARC_Vector_Create(&row, NULL, NULL); - ARC_Vector_Add(dataVector, (void *)row); - continue; - - default: - continue; - } - } -} - -void ARC_ParserCSVData_CreateFn(void **data, ARC_ParserTagToken *parsedData, void *userData){ +void ARC_ChemicalData_CreateFn(void **data, ARC_ParserTagToken *parsedData, void *userData){ *data = NULL; if(data == NULL || userData == NULL){ //TODO: error here? *data = NULL; return; } - - //cast the csv data back to its original type - ARC_ParserCSVUserData *csvUserData = (ARC_ParserCSVUserData *)userData; - - //crate a vector for the data to be stored in before being copied to a 2d array - ARC_Vector *dataVector; - ARC_Vector_DestroyDataFn destroyVectorFn = ARC_ParserCSVData_VectorDestroyVectorFn; - ARC_Vector_Create(&dataVector, NULL, &destroyVectorFn); - - //create the first row vector, does not need a destroy function as its contents will be moved - ARC_Vector *dataRowVector; - ARC_Vector_Create(&dataRowVector, NULL, NULL); - - //add the row to the dataVector - ARC_Vector_Add(dataVector, (void *)dataRowVector); - - //recursively add data from the parsedData to the data vector - ARC_ParserCSVData_RunLineTag(dataVector, parsedData, csvUserData); - - //get the first line to check if it has any values - dataRowVector = ARC_Vector_Get(dataVector, 0); - if(ARC_Vector_GetSize(dataRowVector) == 0){ - //TODO: iterate and clear the vector - ARC_Vector_Destroy(dataVector); - return; - } - - //create the data that will be saved - ARC_ParserCSVData *csvData = (ARC_ParserCSVData *)malloc(sizeof(ARC_ParserCSVData)); - csvData->hasHeader = csvUserData->header; - csvData->headers = NULL; - csvData->height = 0; - csvData->width = ARC_Vector_GetSize(dataRowVector); - csvData->data = NULL; - - //create the starting index (to offset the header if it exists) - uint32_t heightStartIndex = 0; - - //store the headers if they exist - if(csvData->hasHeader == ARC_True){ - heightStartIndex++; - - //copy the headers - csvData->headers = (ARC_String **)malloc(sizeof(ARC_String *) * csvData->width); - for(uint32_t headerIndex = 0; headerIndex < csvData->width; headerIndex++){ - csvData->headers[headerIndex] = (ARC_String *)ARC_Vector_Get(dataRowVector, headerIndex); - } - } - - //check that all the rows are the same size - for(uint32_t rowIndex = heightStartIndex; rowIndex < ARC_Vector_GetSize(dataVector); rowIndex++){ - ARC_Vector *currentRowVector = (ARC_Vector *)ARC_Vector_Get(dataVector, rowIndex); - - //skip an empty line (this should only be the case for the last line) - uint32_t currentRowVectorSize = ARC_Vector_GetSize(currentRowVector); - if(currentRowVectorSize == 0){ - continue; - } - - //a row was found so update the height - csvData->height++; - - //TODO: probs want to error - //cleanup and exit if they don't match - if(csvData->width != currentRowVectorSize){ - //TODO: iterate and clear the vector - ARC_Vector_Destroy(dataVector); - return; - } - } - - //init location to copy data to - csvData->data = (void ***)malloc(sizeof(void **) * csvData->height); - - //copy the data - uint32_t rowIndex = 0; - for(uint32_t y = 0; y < csvData->height; y++, rowIndex++){ - ARC_Vector *currentRowVector = (ARC_Vector *)ARC_Vector_Get(dataVector, rowIndex + heightStartIndex); - - //skip an empty line (should only be the case for the last line) - uint32_t currentRowVectorSize = ARC_Vector_GetSize(currentRowVector); - if(currentRowVectorSize == 0){ - y--; - continue; - } - - //create the current row - csvData->data[y] = (void **)malloc(sizeof(void *) * csvData->width); - - for(uint32_t x = 0; x < csvData->width; x++){ - csvData->data[y][x] = ARC_Vector_Get(currentRowVector, x); - } - } - - ARC_Vector_Destroy(dataVector); - - *data = (void *)csvData; } -void ARC_ParserCSVData_DestroyFn(void *data, ARC_Bool clear, void *userData){ - if(userData == NULL){ - return; - } +void ARC_Chemical_Create(ARC_Chemical **chemical){ + *chemical = (ARC_Chemical *)malloc(sizeof(ARC_Chemical)); - ARC_ParserCSVUserData *csvUserData = (ARC_ParserCSVUserData *)userData; - - if(data != NULL){ - ARC_ParserCSVData *csvData = (ARC_ParserCSVData *)data; - - //cleanup the headers if they exist - if(csvData->hasHeader == ARC_True){ - for(uint32_t x = 0; x < csvData->width; x++){ - ARC_String *string = csvData->headers[x]; - ARC_String_Destroy(string); - } - free(csvData->headers); - } - - for(uint32_t y = 0; y < csvData->height; y++){ - //cleanup each element in the data - for(uint32_t x = 0; x < csvData->width; x++){ - csvUserData->destroyTypeFn(csvData->data[y][x]); - } - - //cleanup each row of data - free(csvData->data[y]); - } - - //cleanup the data - free(csvData->data); - free(csvData); - } - - if(clear == ARC_False){ - free(csvUserData); - } -} - -void ARC_ParserCSV_CreateAsParser(ARC_Parser **parser, ARC_Bool header, ARC_ParserCSV_CastTypeFn castTypeFn, ARC_ParserCSV_DestroyTypeFn destroyTypeFn){ /* ~ define the language as a string ~ */ char *languageCString = - " -> NEWLINE | | NEWLINE | LAMBDA\n" - " -> COMMA | \n" - " -> | \n" - " -> CHAR_BEFORE_COMMA | CHAR_AFTER_COMMA\n"; + " -> | | \n" + " -> LEFT_CURLY_BRACE RIGHT_CURLY_BRACE\n" + + " -> EQUALS value SEMICOLON \n" + + " -> \n" + " -> \n" + " -> | | \n" + " -> OPEN_CURLY_BRACE CLOSE_CURLY_BRACE\n" + " -> | COMMA \n" + + " -> ALPHA_UPPER_CHAR | ALPHA_LOWER_CHAR | UNDERSCORE \n" + " -> | LAMBDA\n" + " -> ALPHA_UPPER_CHAR | ALPHA_LOWER_CHAR | UNDERSCORE | NUM\n" + + " -> NUMBER | NUMBER LAMBDA\n" + + " -> SPACE | TAB | NEWLINE | LAMBDA\n"; + + /* ~ define the language as a string ~ */ ARC_String *languageString; ARC_String_CreateWithStrlen(&languageString, languageCString); - /* ~ init the userdata ~ */ - ARC_ParserCSVUserData *userdata = (ARC_ParserCSVUserData *)malloc(sizeof(ARC_ParserCSVUserData)); - userdata->header = header; - userdata->castTypeFn = castTypeFn; - userdata->destroyTypeFn = destroyTypeFn; + /* ~ init the userdata? ~ */ /* ~ create the language ~ */ - ARC_ParserData_CreateFn createCharFn = ARC_ParserCSVData_CreateFn; - ARC_ParserData_DestroyFn destroyCharFn = ARC_ParserCSVData_DestroyFn; - ARC_Parser_CreateFromString(parser, languageString, ARC_ParserCSV_InitLexerRulesFn, ARC_ParserCSV_GetStringIdFn, &createCharFn, &destroyCharFn, userdata); + //ARC_ParserData_CreateFn createCharFn = ARC_ChemicalData_CreateFn; + //ARC_ParserData_DestroyFn destroyCharFn = ARC_ChemicalData_DestroyFn; + //ARC_Parser_CreateFromString(parser, languageString, ARC_ParserCSV_InitLexerRulesFn, ARC_ParserCSV_GetStringIdFn, &createCharFn, &destroyCharFn, userdata); //cleanup ARC_String_Destroy(languageString); } + +void ARC_Chemical_Destroy(ARC_Chemical *chemical){ +} + +void ARC_Chemical_RegisterType(ARC_Chemical *chemical, ARC_String *typeName, ARC_ChemicalData_CopyToTypeFn *copyToTypeFn, ARC_ParserCSV_DestroyTypeFn destroyTypeFn){ +} + +void ARC_Chemical_SetGroup(ARC_Chemical *chemical, ARC_String *groupName){ +} + +void *ARC_Chemical_Get(ARC_Chemical *chemical, ARC_String *element){ + return NULL; +} + +void ARC_Chemical_LoadFromString(ARC_String *path){ +} + +void ARC_Chemical_LoadFromFile(ARC_String *path){ +} + +void ARC_Chemical_UnloadFromString(ARC_String *data){ +} + +void ARC_Chemical_UnloadFromFile(ARC_String *data){ +} diff --git a/tests/std/chemical.c b/tests/std/chemical.c index 00fe960..6bb29de 100644 --- a/tests/std/chemical.c +++ b/tests/std/chemical.c @@ -1,4 +1,4 @@ -#include "../../test.h" +#include "../test.h" #include "arc/std/errno.h" #include "arc/std/chemical.h" //#include