worked more on arc chemical, need to add way to parse with seperate create and destroy function for unload
This commit is contained in:
parent
7316f7c779
commit
bb3601b8f2
2 changed files with 142 additions and 94 deletions
|
|
@ -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){
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue