worked more on arc chemical, need to add way to parse with seperate create and destroy function for unload

This commit is contained in:
herbglitch 2025-03-06 04:21:01 -07:00
parent 7316f7c779
commit bb3601b8f2
2 changed files with 142 additions and 94 deletions

View file

@ -1,26 +1,30 @@
#include "arc/std/chemical.h"
#include "arc/std/parser/helpers.h"
#include "arc/std/bool.h"
#include "arc/std/errno.h"
#include "arc/std/hashtable.h"
#include "arc/std/parser.h"
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
struct ARC_Chemical {
ARC_Parser *parser;
ARC_Hashtable *groups;
ARC_Hashtable *types;
ARC_Hashtable *groups;
ARC_Hashtable *currentGroup;
};
typedef struct ARC_ChemicalTypeData {
void *data;
ARC_ChemicalType_DestroyFn *destroyFn;
ARC_ChemicalType_DestroyFn destroyFn;
} ARC_ChemicalTypeData;
static const char *ARC_CHEMICAL_DEFAULT_GROUP = " ";
//the grouping is based on the ascii table, but the ids are sequential to make finding tokens quicker (look at the lexer continious for more explanation)
static const uint32_t ARC_CHEMICAL_TAB = 0x01;
static const uint32_t ARC_CHEMICAL_NEWLINE = 0x02;
@ -328,6 +332,32 @@ void ARC_ChemicalData_DestroyFn(void *data, ARC_Bool clear, void *userData){
return;
}
//private function to check hashtable keys used by chemical
ARC_Bool ARC_Chemical_HashtableKeyCompareFn(void *key1, void *key2){
return (ARC_Bool)strcmp((const char *)key1, (const char *)key2) == 0;
}
//private function to clean up types
void ARC_Chemical_TypeHashtableDestroyKeyValueFn(void *key, void *value){
free((char *)key);
free((ARC_ChemicalType *)value);
}
//private function to clean up groups
void ARC_Chemical_GroupHashtableDestroyKeyValueFn(void *key, void *value){
free((char *)key);
ARC_Hashtable_Destroy((ARC_Hashtable *)value);
}
//private function to clean up goup data
void ARC_Chemical_GroupDataHashtableDestroyKeyValueFn(void *key, void *value){
free((char *)key);
ARC_ChemicalTypeData *typeData = (ARC_ChemicalTypeData *)value;
typeData->destroyFn(typeData->data);
free(typeData);
}
void ARC_Chemical_Create(ARC_Chemical **chemical){
*chemical = (ARC_Chemical *)malloc(sizeof(ARC_Chemical));
@ -370,57 +400,96 @@ void ARC_Chemical_Create(ARC_Chemical **chemical){
ARC_ParserData_DestroyFn destroyCharFn = ARC_ChemicalData_DestroyFn;
ARC_Parser_CreateFromString(&((*chemical)->parser), languageString, ARC_Chemical_InitLexerRulesFn, ARC_Chemical_GetStringIdFn, &createCharFn, &destroyCharFn, userdata);
/* ~ init types ~ */
ARC_Hashtable_KeyCompareFn keyCompareFn = ARC_Chemical_HashtableKeyCompareFn;
ARC_Hashtable_DestroyKeyValueFn typeDestroyKeyValueFn = ARC_Chemical_TypeHashtableDestroyKeyValueFn;
ARC_Hashtable_Create(&((*chemical)->types), NULL, &keyCompareFn, &typeDestroyKeyValueFn);
/* ~ init groups ~ */
ARC_Hashtable_DestroyKeyValueFn groupDestroyKeyValueFn = ARC_Chemical_GroupHashtableDestroyKeyValueFn;
ARC_Hashtable_Create(&((*chemical)->groups), NULL, &keyCompareFn, &groupDestroyKeyValueFn);
//add the default/empty group into the groups
ARC_Hashtable_DestroyKeyValueFn groupDataDestroyKeyValueFn = ARC_Chemical_GroupDataHashtableDestroyKeyValueFn;
ARC_Hashtable_Create(&((*chemical)->currentGroup), NULL, &keyCompareFn, &groupDataDestroyKeyValueFn);
ARC_Hashtable_Add((*chemical)->groups, (void *)ARC_CHEMICAL_DEFAULT_GROUP, (*chemical)->currentGroup);
//cleanup
ARC_String_Destroy(languageString);
}
void ARC_Chemical_Destroy(ARC_Chemical *chemical){
//NOTE: chemical->currentGroup does not need to be freed as it is stored in chemical->groups
ARC_Hashtable_Destroy(chemical->groups);
ARC_Hashtable_Destroy(chemical->types);
free(chemical);
}
void ARC_Chemical_HashtableCheckKeyIteratorFn(void *key, void *value){
}
void ARC_Chemical_RegisterType(ARC_Chemical *chemical, ARC_String *typeName, ARC_ChemicalType type){
//TODO: check if name currently exists
ARC_String *typeNameCopy;
ARC_String_Copy(&typeNameCopy, typeName);
ARC_ChemicalType *typeCopy = (ARC_ChemicalType *)malloc(sizeof(ARC_ChemicalType));
*typeCopy = type;
ARC_Hashtable_Add(chemical->types, typeName, typeCopy);
ARC_Chemical_RegisterTypeWithCStr(chemical, typeName->data, type);
}
void ARC_Chemical_RegisterTypeWithCStr(ARC_Chemical *chemical, const char *typeNameCStr, ARC_ChemicalType type){
//TODO: check if name currently exists
ARC_String *typeName;
ARC_String_CreateWithStrlen(&typeName, (char *)typeNameCStr);
//check if the type key already exists and error if it does
if(ARC_Hashtable_Get(chemical->types, (void *)typeNameCStr) != NULL){
arc_errno = ARC_ERRNO_EXISTS;
ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_Chemical_RegisterTypeWithCStr(chemical, typeName, type), type \"%s\" has already been registered", typeNameCStr);
return;
}
//copy the string into a cstring for long term storage
char *typeNameCopy = malloc(sizeof(char) * strlen(typeNameCStr));
strcpy(typeNameCopy, typeNameCStr);
//copy the type for long term storage
ARC_ChemicalType *typeCopy = (ARC_ChemicalType *)malloc(sizeof(ARC_ChemicalType));
*typeCopy = type;
ARC_Hashtable_Add(chemical->types, typeName, typeCopy);
//add the type to a hashtable containing all the types
ARC_Hashtable_Add(chemical->types, typeNameCopy, typeCopy);
}
void ARC_Chemical_SetGroup(ARC_Chemical *chemical, ARC_String *groupName){
ARC_Chemical_SetGroupWithCStr(chemical, groupName->data);
}
void ARC_Chemical_SetGroupWithCStr(ARC_Chemical *chemical, const char *groupName){
//try to get the current group
void *currentGroup = ARC_Hashtable_Get(chemical->groups, (void *)groupName);
//error if the current group does not exist
if(currentGroup == NULL){
arc_errno = ARC_ERRNO_NULL;
ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_Chemical_SetGroupWithCStr(chemical, groupName), no group with name \"%s\"", groupName);
return;
}
//set the current group
chemical->currentGroup = currentGroup;
}
void *ARC_Chemical_Get(ARC_Chemical *chemical, ARC_String *element){
return NULL;
return ARC_Chemical_GetWithCStr(chemical, element->data);
}
void ARC_Chemical_LoadFromString(ARC_String *path){
void *ARC_Chemical_GetWithCStr(ARC_Chemical *chemical, const char *element){
//TODO: set the parent group
//this will either return the value or NULL
return ARC_Hashtable_Get(chemical->currentGroup, (void *)element);
}
void ARC_Chemical_LoadFromFile(ARC_String *path){
void ARC_Chemical_LoadFromString(ARC_Chemical *chemical, ARC_String **string){
ARC_Parser_Parse(chemical->parser, string);
}
void ARC_Chemical_UnloadFromString(ARC_String *data){
void ARC_Chemical_LoadFromFile(ARC_Chemical *chemical, ARC_String *path){
ARC_Parser_ParseFile(chemical->parser, path);
}
void ARC_Chemical_UnloadFromFile(ARC_String *data){
void ARC_Chemical_UnloadFromString(ARC_Chemical *chemical, ARC_String **string){
}
void ARC_Chemical_UnloadFromFile(ARC_Chemical *chemical, ARC_String *data){
}