#include #include #include "utils/Functions.h" static bool useGlobals = false; static Functions globalFunctions; void fInit(Function* f, const char* name, int16 line) { f->name = name; f->arguments = 0; f->returnType = dtVoid(); f->address = -1; f->size = 0; f->line = line; f->global = false; f->scriptFunction = NULL; } bool fAddArgument(Function* f, DataType type, Structs* sts) { if(f->arguments >= FUNCTION_ARGUMENTS) { return true; } int add; if(dtGetSize(type, sts, &add)) { return true; } f->size += add; f->argumentTypes[f->arguments++] = type; return false; } static bool fCompare(Function* a, Function* b) { if(a->arguments != b->arguments || strcmp(a->name, b->name) != 0) { return false; } for(int i = 0; i < a->arguments; i++) { if(!dtCompare(a->argumentTypes[i], b->argumentTypes[i])) { return false; } } return strcmp(a->name, b->name) == 0; } void fsInit(Functions* fs) { fs->capacity = 16; fs->entries = 0; fs->data = (Function*)malloc(sizeof(Function) * (size_t)fs->capacity); } void fsDelete(Functions* fs) { free(fs->data); } static Function* fsInternSearch(Functions* fs, Function* f) { for(int i = 0; i < fs->entries; i++) { if(fCompare(fs->data + i, f)) { return fs->data + i; } } return NULL; } Function* fsSearch(Functions* fs, Function* f) { if(useGlobals) { Function* gf = fsInternSearch(&globalFunctions, f); if(gf != NULL) { return gf; } } return fsInternSearch(fs, f); } void fsAdd(Functions* fs, Function* f) { if(fs->entries >= fs->capacity) { fs->capacity *= 2; fs->data = (Function*)realloc(fs->data, sizeof(Function) * (size_t)fs->capacity); } fs->data[fs->entries++] = *f; } void gfInit(Function* f, const char* name, DataType r, ScriptFunction sf) { fInit(f, name, -1); f->returnType = r; f->scriptFunction = sf; } bool gfAddArgument(Function* f, DataType type) { return fAddArgument(f, type, gstsGet()); } void gfsInit(void) { fsInit(&globalFunctions); useGlobals = true; } bool gfsAdd(Function* f) { if(fsSearch(&globalFunctions, f) != NULL) { return true; } int index = globalFunctions.entries; fsAdd(&globalFunctions, f); globalFunctions.data[index].line = (int16)index; globalFunctions.data[index].global = true; return false; } bool gfsCall(Script* sc, int id) { if(!useGlobals || id < 0 || id >= globalFunctions.entries) { return true; } globalFunctions.data[id].scriptFunction(sc); return false; } void gfsDelete(void) { fsDelete(&globalFunctions); useGlobals = false; }