feat: line processing and basic variable support

This commit is contained in:
Matthieu Bessat 2022-05-06 11:49:09 +02:00
parent cb2a1df61f
commit 11fa2b1e6f
21 changed files with 893 additions and 136 deletions

View file

@ -6,6 +6,8 @@
#include "./operate.h"
#include "./number_parsing.h"
#include "./funcs.h"
#include "./var_store.h"
#include "./state.h"
/**
This sub script will look for pattern like Number Operator Number
@ -154,6 +156,31 @@ int evaluator_reduce_parenthesis_pattern(struct List* evalList) {
return 0;
}
int evaluator_reduce_var(struct StateContainer* state, struct List* evalList) {
int patternPos = -1;
for (int i = 0; i < evalList->num_elements; i++) {
if (
list_get_type(evalList, i) == TYPE_VAR_NAME
) {
patternPos = i;
break;
}
}
if (patternPos == -1) return -1;
int varKey;
list_get(evalList, patternPos, &varKey);
byte type = var_store_get_type_from_key(state->varStore, varKey);
byte varVal[get_size_of_type(type)];
var_store_copy_from_key(state->varStore, varKey, &varVal);
list_set(evalList, patternPos, type, &varVal);
return 0;
}
/*
This func will look for a function call pattern that is ready to be evaluated
First we will look for this kind of pattern
@ -169,10 +196,14 @@ if we don't find a comma next, we try to find a closing parenthesis
if we don't find that, we throw an error
*/
int evaluator_reduce_function_call(struct List* evalList) {
int evaluator_reduce_function_call(struct List* evalList, int initialPosition) {
int patternPos = -1;
for (int i = 0; i < evalList->num_elements; i++) {
if (initialPosition >= evalList->num_elements) {
return -1;
}
for (int i = initialPosition; i < evalList->num_elements; i++) {
if (
list_get_type(evalList, i) == TYPE_FUNC_NAME &&
list_get_type(evalList, i+1) == TYPE_OPEN_PARENTHESIS
@ -239,7 +270,10 @@ int evaluator_reduce_function_call(struct List* evalList) {
}
// we cannot reduce more, it's probably because the func call is not ready to be reduced, meaning that the arguments need to be evaluated
return -1;
// we need to return to the state of primitive function detection, just skip this primitive
// we need to revaluate at patternPos+2
return evaluator_reduce_function_call(evalList, patternPos+2);
}
// now pos is the index of the last component for this func call
@ -287,7 +321,7 @@ Arguments:
- Input String: char pointer (the source of the evaluation)
- Result: int pointer (where the result of the evaluation will be written)
*/
int evaluate(char* inputStr, int* resultPtr, unsigned char* typePtr) {
int evaluate(struct StateContainer* state, char* inputStr, int* resultPtr, unsigned char* typePtr) {
int i = 0;
int _len = strlen(inputStr);
// we want first to parse the expression and create a stack
@ -461,18 +495,27 @@ int evaluate(char* inputStr, int* resultPtr, unsigned char* typePtr) {
}
if (st != 0) {
// identify token
// first try a variable then a func name
// not a float, check if this is a common function name
short funcID = identify_func_name(buff);
if (funcID == -1) {
// did not find the func name
printf("ERR Evaluator: could not identify token \"%s\" \n", buff);
return 200;
short varKey = (short) var_store_get_key(state->varStore, buff);
if (varKey == -1) {
// did not find the var name
short funcID = identify_func_name(buff);
if (funcID == -1) {
// did not find the func name
printf("ERR Evaluator: could not identify token \"%s\" \n", buff);
return 200;
}
if (funcID >= 0) {
list_set(&evalList, evalList.num_elements, TYPE_FUNC_NAME, &funcID);
}
}
if (funcID >= 0) {
list_set(&evalList, evalList.num_elements, TYPE_FUNC_NAME, &funcID);
if (varKey >= 0) {
list_set(&evalList, evalList.num_elements, TYPE_VAR_NAME, &varKey);
}
}
printf("end of l\n");
printf("end of a token id\n");
}
// check the content of this thing
@ -484,15 +527,21 @@ int evaluate(char* inputStr, int* resultPtr, unsigned char* typePtr) {
// we are going to look for pattern to reduce
// the order is really important here
int reduceFuncOpStat = evaluator_reduce_function_call(&evalList);
int reduceVarOpStat = evaluator_reduce_var(state, &evalList);
int reduceFuncOpStat = evaluator_reduce_function_call(&evalList, 0);
int reduceMinusOpStat = evaluator_reduce_minus_pattern(&evalList);
int reduceOperatorOpStat = evaluator_reduce_operator_pattern(&evalList);
int reduceParenthesisOpStat = evaluator_reduce_parenthesis_pattern(&evalList);
if (reduceVarOpStat > 0) {
printf("ERR Evaluator: var name reducing failed, dumping evalList: \n");
list_print(&evalList);
return reduceVarOpStat;
}
if (reduceFuncOpStat > 0) {
printf("ERR Evaluator: function reducing failed, dumping evalList: \n");
list_print(&evalList);
return reduceOperatorOpStat;
return reduceFuncOpStat;
}
if (reduceOperatorOpStat > 0) {
printf("ERR Evaluator: operator reducing failed, dumping evalList: \n");
@ -501,6 +550,7 @@ int evaluate(char* inputStr, int* resultPtr, unsigned char* typePtr) {
}
if (
reduceVarOpStat == -1 &&
reduceFuncOpStat == -1 &&
reduceOperatorOpStat == -1 &&
reduceParenthesisOpStat == -1 &&

View file

@ -1,6 +1,7 @@
#include "./state.h"
#ifndef EVALUATOR_H_
#define EVALUATOR_H_
int evaluate(char* inputStr, int* resultPtr, unsigned char* typePtr);
int evaluate(struct StateContainer* state, char* inputStr, int* resultPtr, unsigned char* typePtr);
#endif

View file

@ -27,6 +27,25 @@ int abs_impl(int* res, unsigned char* resType, unsigned char* types, int* args)
return 1;
}
int print_number_impl(int* res, unsigned char* resType, unsigned char* types, int* args)
{
if (types[0] == TYPE_INT) {
int val = args[0];
printf("REAL_PRINT: %d\n", val);
}
if (types[0] == TYPE_FLOAT) {
float val = get_float_from_int_rep(args[0]);
printf("REAL_PRINT: %f\n", val);
}
if (is_type_number(types[0])) {
*res = 1;
*resType = TYPE_INT;
return 0;
}
return 1;
}
int simple_float_func(float (*func)(float), int* res, unsigned char* resType, unsigned char* types, int* args)
{
float x = 0;
@ -42,14 +61,15 @@ int simple_float_func(float (*func)(float), int* res, unsigned char* resType, un
return 0;
}
// #define SIMPLE_FUNC_BINDING(name) ({\
// int #name_impl(int* res, unsigned char* resType, unsigned char* types, int* args)\
// {\
// return simple_float_func(&m_#name, res, resType, types, args);\
// }\
// })
//
//
/*
#define SIMPLE_FUNC_BINDING(name) ({\
int #name_impl(int* res, unsigned char* resType, unsigned char* types, int* args)\
{\
return simple_float_func(&m_#name, res, resType, types, args);\
}\
})
*/
// SIMPLE_FUNC_BINDING(sqrt)
//
// SIMPLE_FUNC_BINDING(exp)
@ -162,8 +182,6 @@ int random_int_impl(int* res, unsigned char* resType, unsigned char* types, int*
upper = args[1];
}
int i;
// rand returns a value between 0 and RAND_MAX (which is close to infinite)
int num = (rand() % (upper - lower + 1)) + lower;
*resType = TYPE_INT;
@ -196,6 +214,8 @@ struct FuncIntro intros[] = {
{"max", &max_impl, 2},
{"get_pi", &get_pi_impl, 0},
{"print_number", &print_number_impl, 1},
{"", 0, 0}
};

255
src/line_processing.c Normal file
View file

@ -0,0 +1,255 @@
#include "./utils.h"
#include "./line_processing.h"
#include "./evaluator.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int cmp_str_in_place(char* against, char* str, int from)
{
int i = 0;
while (against[i] != '\0') {
if (against[i] != str[from+i]) {
return 0;
}
i++;
}
return 1;
}
int is_char_accepted_in_var_name(char symbol)
{
int c = (int) symbol;
return (
(c >= 65 && c <= 90) ||
(c >= 97 && c <= 122) ||
(c >= 48 && c <= 57) ||
c == 45 || c == 95
);
}
int recognize_comment_statement(char* lineStr)
{
int i = 0;
int mode = 1;
/*
recognize pattern : ^\s*#.*$
mode 1 any space
mode 2 the start of the comment
*/
while (lineStr[i] != '\0') {
if (mode == 1) {
if (lineStr[i] == '#') {
mode = 2;
continue;
}
if (lineStr[i] != ' ') {
break;
}
}
i++;
}
if (mode != 2) return 0;
return 1;
}
struct SetStatement {
short name_start;
short name_stop;
short expression_start;
};
int recognize_set_statement(char* lineStr, struct SetStatement* res)
{
int i = 0;
int mode = 1;
int arg = 0;
/*
recognize pattern : ^\s*set ([a-zA-Z0-9_-]+) to (\S)+
mode 1 any space
mode 2 set
mode 3 any space
mode 4 var name
mode 5 any space
mode 6 to
mode 7 any space
mode 8 the expression
*/
while (lineStr[i] != '\0') {
if (mode == 1) {
if (lineStr[i] == 's') {
mode = 2;
arg = 0;
continue;
}
if (lineStr[i] != ' ') {
break;
}
}
if (mode == 2) {
if (arg == 0 && lineStr[i] == 's') {
arg++;
i++;
continue;
}
if (arg == 1 && lineStr[i] == 'e') {
arg++;
i++;
continue;
}
if (arg == 2 && lineStr[i] == 't') {
mode = 3;
arg = 0;
i++;
continue;
}
break;
}
if (mode == 3) {
if (arg > 0 && is_char_accepted_in_var_name(lineStr[i])) {
mode = 4;
arg = 0;
res->name_start = i;
continue;
}
if (lineStr[i] != ' ') {
break;
}
arg++;
}
if (mode == 4) {
if (lineStr[i] == ' ') {
mode = 5;
arg = 0;
res->name_stop = i;
continue;
}
if (!is_char_accepted_in_var_name(lineStr[i])) {
break;
}
}
if (mode == 5) {
if (arg > 0 && lineStr[i] == 't') {
mode = 6;
arg = 0;
continue;
}
if (lineStr[i] != ' ') {
break;
}
arg++;
}
if (mode == 6) {
if (arg == 0 && lineStr[i] == 't') {
arg++;
i++;
continue;
}
if (arg == 1 && lineStr[i] == 'o') {
mode = 7;
arg = 0;
i++;
continue;
}
break;
}
if (mode == 7) {
if (arg == 0 && lineStr[i] != ' ') {
break;
}
if (arg > 0 && lineStr[i] != ' ') {
// success
mode = 8;
res->expression_start = i;
break;
}
arg++;
}
i++;
}
// printf("End of set statement parsing \n");
// printf("index %d \n", i);
// printf("mode %d \n", mode);
// printf("arg %d \n", arg);
if (mode != 8) {
// we've failed to recognize the pattern
return 0;
}
// return a struct with anchors to the groups
return 1;
}
int process_line(struct StateContainer* state, char* str)
{
printf("\n ======= PROCESSING LINE '%s' =======\n", str);
// process
int len = strlen(str);
// int startPos = 0;
// int stopPos = len-1;
// // modifiy the start and stop pos to trim spaces
// int startTrimOffset = 0;
// int stopTrimOffset = 0;
// for (int z = 0; z < len; z++) {
// if (inputStr[startPos+z] != ' ') {
// break;
// }
// startTrimOffset++;
// }
// for (int z = 1; z < len; z++) {
// if (inputStr[stopPos-z] != ' ') {
// break;
// }
// stopTrimOffset++;
// }
// startPos += startTrimOffset;
// stopPos -= stopTrimOffset;
// check for comment
// if (str[startPos] == '#') {
// return;
// }
//int stat = 0;
if (recognize_comment_statement(str)) {
printf("Comment recognized \n");
return 1;
}
struct SetStatement setStatementParsing;
if (recognize_set_statement(str, &setStatementParsing)) {
printf("Set statement recognized \n");
// handle the set statement (set a variable)
int nameLen = setStatementParsing.name_stop-setStatementParsing.name_start;
char* name = (char*) malloc(sizeof(char) * nameLen);
for (int z = 0; z < nameLen; z++) {
name[z] = str[setStatementParsing.name_start + z];
}
name[len] = '\0';
int res;
byte resType;
int evalStat = evaluate(state, str + setStatementParsing.expression_start, &res, &resType);
if (evalStat != 0) {
printf("Syntax error for line \"%s\"\n", str);
}
printf("==> Set '%s' to %s \n", name, get_repr(resType, &res));
var_store_set(state->varStore, name, resType, &res);
return 1;
}
// we evaluate but we dont care about the result
int res;
byte resType;
int evalStat = evaluate(state, str, &res, &resType);
if (evalStat != 0) {
printf("Syntax error for line \"%s\"\n", str);
return 0;
}
return 1;
}

7
src/line_processing.h Normal file
View file

@ -0,0 +1,7 @@
#include "./state.h"
#ifndef LINE_PROCESSING_H_
#define LINE_PROCESSING_H_
int process_line(struct StateContainer* state, char* str);
#endif

View file

@ -13,37 +13,6 @@ struct List {
};
*/
// get size in byte of a particular type
int get_size_of_type(unsigned char type)
{
int t = (int) type;
// underlying type is int (4 bytes)
if (t == TYPE_INT || t == TYPE_FLOAT) {
return 4;
}
// underlying type is short (1 byte)
if (t == TYPE_FUNC_NAME) {
return 2;
}
// underlying type is char (1 byte)
if (t == TYPE_OPERATOR) {
return 1;
}
if (
t == TYPE_OPEN_PARENTHESIS ||
t == TYPE_CLOSE_PARENTHESIS ||
t == TYPE_COMMA
) {
return 0;
}
return -1;
}
int is_type_number(unsigned char type)
{
return type == TYPE_INT || type == TYPE_FLOAT;
}
unsigned char list_get_type(struct List* list, int index) {
if (index >= list->num_elements) {
return 0;
@ -84,7 +53,7 @@ int list_get(struct List* list, int index, void* resultPtr)
if (type == TYPE_OPERATOR) {
*((char*) resultPtr) = *((char*) valuePtr);
}
if (type == TYPE_FUNC_NAME) {
if (type == TYPE_FUNC_NAME || type == TYPE_VAR_NAME) {
*((short*) resultPtr) = *((short*) valuePtr);
}
@ -245,6 +214,12 @@ void list_print(struct List* list)
printf("type: FUNC_NAME, val: %d", d);
}
if (type == TYPE_VAR_NAME) {
short d = 0;
list_get(list, i, &d);
printf("type: VAR_NAME, val: %d", d);
}
if (type == TYPE_OPEN_PARENTHESIS) {
printf("type: OPEN_PARENTHESIS");
}

View file

@ -44,13 +44,9 @@ struct List {
int data_ptr;
int ptrArray[LIST_SIZE];
unsigned char typeArray[LIST_SIZE];
unsigned char data[LIST_SIZE];
unsigned char data[LIST_SIZE]; // FIXME: remove this bc we want to use malloc
};
int is_type_number(unsigned char type);
int get_size_of_type(unsigned char type);
unsigned char list_get_type(struct List* list, int index);
int list_get(struct List* list, int index, void* valuePtr);

25
src/state.c Normal file
View file

@ -0,0 +1,25 @@
#include "./utils.h"
#include "./var_store.h"
#include "./state.h"
#include <stdlib.h>
// #define STATE_LEN 255
// #define VARIABLES_LEN 255
// struct ProcessingState {
// int linePtr;
// int variableStore[VARIABLES_LEN];
// int functionStore[255];
// //int stringStore[255]
// int data[STACK_LEN];
// };
struct StateContainer* state_init()
{
struct StateContainer* ptr = (struct StateContainer*) malloc(sizeof(struct StateContainer));
ptr->varStore = var_store_init();
return ptr;
}

26
src/state.h Normal file
View file

@ -0,0 +1,26 @@
/**
This is where we store the state of our program
we store:
- the variables names and their values (for now only int)
- the functions names and their references
*/
#include "./utils.h"
#include "./var_store.h"
#ifndef STATE_H_
#define STATE_H_
struct StateContainer {
// the line we are currently processing
int linePtr;
// usefull when we are in SKIP_BLOCK mode, we'will count the nb of block (begin/end)
int blocStack;
// FULL, SKIP_BLOC, etc
byte mode;
struct VariableStore* varStore;
// struct FunctionStore* funcStore;
// struct StringStore* strStore ??
};
struct StateContainer* state_init();
#endif

55
src/types.c Normal file
View file

@ -0,0 +1,55 @@
#include "./utils.h"
#include "./types.h"
#include <stdio.h>
#include <stdlib.h>
int is_type_number(byte type)
{
return type == TYPE_INT || type == TYPE_FLOAT;
}
// get size in byte of a particular type
int get_size_of_type(byte type)
{
int t = (int) type;
// underlying type is int (4 bytes)
if (t == TYPE_INT || t == TYPE_FLOAT) {
return 4;
}
// underlying type is short (2 bytes)
if (t == TYPE_FUNC_NAME || t == TYPE_VAR_NAME) {
return 2;
}
// underlying type is char (1 byte)
if (t == TYPE_OPERATOR) {
return 1;
}
if (
t == TYPE_OPEN_PARENTHESIS ||
t == TYPE_CLOSE_PARENTHESIS ||
t == TYPE_COMMA
) {
return 0;
}
return -1;
}
char* get_repr(byte type, void* valPtr)
{
char* res= (char*) malloc(sizeof(char)*32);
if (type == 0) {
sprintf(res, "NULL");
return res;
}
if (type == TYPE_INT) {
sprintf(res, "INT(%d)", *((int*) valPtr));
return res;
}
if (type == TYPE_FLOAT) {
sprintf(res, "FLOAT(%f)", *((float*) valPtr));
return res;
}
sprintf(res, "UNKNOWN(%d)", type);
return res;
}

View file

@ -1,8 +1,20 @@
#include "./utils.h"
#ifndef TYPES_H_
#define TYPES_H_
#define TYPE_INT 2
#define TYPE_FLOAT 3
#define TYPE_OPERATOR 32
#define TYPE_COMMA 33
#define TYPE_FUNC_NAME 34
#define TYPE_VAR_NAME 35
#define TYPE_OPEN_PARENTHESIS 64
#define TYPE_CLOSE_PARENTHESIS 65
int is_type_number(byte type);
int get_size_of_type(byte type);
char* get_repr(byte type, void* data);
#endif

View file

@ -3,6 +3,9 @@
#define CST_PI 3.1415926535
// define custom type (unsigned char)
typedef unsigned char byte;
int get_int_rep_from_float(float ft);
float get_float_from_int_rep(int representation);
@ -25,6 +28,8 @@ float m_exp(float x);
float m_ln(float x);
float m_log(float base, float x);
float m_sin(float x);
float m_cos(float x);

184
src/var_store.c Normal file
View file

@ -0,0 +1,184 @@
#include "./types.h"
#include "./var_store.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
struct VariableStore* var_store_init()
{
struct VariableStore* store = (struct VariableStore*) malloc(sizeof(struct VariableStore));
if (store == NULL) {
printf("[ERR] VARSTORE: malloc failed for variable store \n");
return NULL;
}
store->allocatedLength = VAR_STORE_INITIAL_ALLOC_LENGTH;
store->length = 0;
store->container = (struct VariableContainer*) malloc(sizeof(struct VariableContainer) * store->allocatedLength);
if (store->container == NULL) {
printf("[ERR] VARSTORE: malloc failed for first variable container \n");
return NULL;
}
for (int i = 0; i < store->allocatedLength; i++) {
store->container[i].type = 0;
}
return store;
}
#define MAX_INTEGER 47797852
int var_store_hash_name(struct VariableStore* store, char* varName)
{
int hash = 0;
int i = 0;
while (varName[i] != '\0') {
hash += (get_int_rep_from_char(varName[i])*integer_pow(9, i)) % MAX_INTEGER;
i++;
}
return hash % store->allocatedLength;
}
byte var_store_set(struct VariableStore* store, char* varName, byte type, void* valuePtr)
{
//printf("set variable at var name: '%s' \n", varName);
if (!(type == TYPE_FLOAT || type == TYPE_INT)) {
printf("[ERR] VARSTORE: unsupported type, cannot store type %d\n", type);
return 0;
}
void* dataPtr;
if (type == TYPE_FLOAT || type == TYPE_INT) {
dataPtr = malloc(sizeof(int));
if (dataPtr == NULL) {
printf("[ERR] VARSTORE: malloc failed for data\n");
return 1;
}
// copy the value to the place to store
// copy from stack to heap
memcpy(dataPtr, valuePtr, sizeof(int));
}
char* namePtr = (char*) malloc(strlen(varName));
if (namePtr == NULL) {
printf("[ERR] VARSTORE: malloc failed for var name\n");
return 1;
}
strcpy(namePtr, varName);
int originalKey = var_store_hash_name(store, varName);
int key = originalKey;
// handle collision, walk along the array
while (1)
{
if (store->container[key].type == 0) {
break;
}
if (strcmp(store->container[key].namePtr, varName) == 0) {
// we found a variable with the same exact key, so we overwrite it
break;
}
key = (key+1) % store->allocatedLength;
if (key == originalKey) {
// end the search to avoid endless loop
printf("[ERR] VARSTORE: cannot set variable, not enough containers \n");
return 1;
}
}
//printf("set variable at key: %d \n", key);
store->container[key].type = type;
store->container[key].namePtr = namePtr;
store->container[key].dataPtr = dataPtr;
store->length++;
if (2*store->length >= store->allocatedLength) {
// do smth to double the store->allocatedLength
// e.g reallocate the store->container
store->allocatedLength = 2*store->allocatedLength;
store->container = (struct VariableContainer*) realloc(store->container, sizeof(struct VariableContainer) * store->allocatedLength);
if (store->container == NULL) {
printf("[ERR] VARSTORE: relloc failed for container \n");
return 1;
}
}
return 0;
}
// get the real position of a variable (in order to handle collisions)
// return -1 if no pos are found
int var_store_get_key(struct VariableStore* store, char* varName)
{
//printf("get key for %s \n", varName);
int originalKey = var_store_hash_name(store, varName);
int key = originalKey;
// handle collision, walk along the array
while (1)
{
//printf("inter key: %d %d \n", key, store->container[key].type);
if (store->container[key].type == 0) {
return -1;
}
if (strcmp(store->container[key].namePtr, varName) == 0) {
// we found the position
return key;
}
key = (key+1) % store->allocatedLength;
if (key == originalKey) {
return -1;
}
}
}
byte var_store_exists(struct VariableStore* store, char* varName)
{
return var_store_get_key(store, varName) != -1;
}
byte var_store_get_type_from_key(struct VariableStore* store, int key)
{
return store->container[key].type;
}
byte var_store_get_type(struct VariableStore* store, char* varName)
{
int key = var_store_get_key(store, varName);
if (key < 0) {
return 0;
}
return var_store_get_type_from_key(store, key);
}
byte var_store_copy_from_key(struct VariableStore* store, int key, void* dst)
{
if (key < 0) {
return 1;
}
memcpy(dst, store->container[key].dataPtr, (size_t) get_size_of_type(store->container[key].type));
return 0;
}
byte var_store_copy(struct VariableStore* store, char* varName, void* dst)
{
return var_store_copy_from_key(store, var_store_get_key(store, varName), dst);
}
int var_store_get_int(struct VariableStore* store, char* varName)
{
if (var_store_get_type(store, varName) != TYPE_INT) {
return 0;
}
int val;
var_store_copy(store, varName, &val);
return val;
}
float var_store_get_float(struct VariableStore* store, char* varName)
{
if (var_store_get_type(store, varName) != TYPE_FLOAT) {
return 0;
}
float val;
var_store_copy(store, varName, &val);
return val;
}

64
src/var_store.h Normal file
View file

@ -0,0 +1,64 @@
#include "./types.h"
#include "./utils.h"
#ifndef VAR_STORE_H_
#define VAR_STORE_H_
#define VAR_STORE_INITIAL_ALLOC_LENGTH 32
/**
Variable store
With an Hash Table
This is a store in the heap
Features:
- resizable, when we have too much variable we can reallocate more memory to store
*/
struct VariableContainer {
byte type;
char* namePtr;
void* dataPtr;
};
struct VariableStore {
int allocatedLength;
int length;
struct VariableContainer* container; // with (storeAllocatedLength) items
};
struct VariableStore* var_store_init();
int var_store_hash_name(struct VariableStore* store, char* varName);
// get a pointer to the area of memory where is store the variable
//void* var_store_get_ptr(struct VariableStore* store, char* varName);
int var_store_get_key(struct VariableStore* store, char* varName);
// return 1 if var exists 0 else
byte var_store_exists(struct VariableStore* store, char* varName);
// get type of the variable
// return NULL if the var doesn't exists
byte var_store_get_type_from_key(struct VariableStore* store, int key);
byte var_store_get_type(struct VariableStore* store, char* varName);
byte var_store_copy_from_key(struct VariableStore* store, int key, void* dest);
byte var_store_copy(struct VariableStore* store, char* varName, void* dest);
// for debug purpose
int var_store_get_int(struct VariableStore* store, char* varName);
float var_store_get_float(struct VariableStore* store, char* varName);
// OR
//byte var_store_get_ptr(char* varName, void** ptrPtr);
// store a variable
byte var_store_set(struct VariableStore* store, char* varName, byte type, void* valuePtr);
byte var_store_delete(struct VariableStore* store, char* varName);
#endif