#include #include #include #include "DataType.h" #define ARRAY_NAME 256 static int typeNameIndex = 0; static int typeNameSwap = 0; static char typeName[2][ARRAY_NAME]; static bool useGlobals = false; static Structs globalStructs; static void dtAppend(const char* s) { int index = 0; while(typeNameIndex < (ARRAY_NAME - 1) && s[index] != '\0') { typeName[typeNameSwap][typeNameIndex] = s[index]; index++; typeNameIndex++; } typeName[typeNameSwap][typeNameIndex] = '\0'; } const char* dtGetName(Structs* sts, DataType dt) { typeNameSwap = !typeNameSwap; typeNameIndex = 0; if(dt.constant) { dtAppend("const "); } switch(dt.type) { case DT_INT32: dtAppend("int"); break; case DT_INT64: dtAppend("long"); break; case DT_FLOAT: dtAppend("float"); break; case DT_BOOL: dtAppend("bool"); break; case DT_NULL: dtAppend("null"); break; case DT_STRUCT: dtAppend(sts->data[dt.structId].name); break; case DT_VOID: dtAppend("void"); break; default: dtAppend("unknown"); } for(unsigned int i = 0; i < dt.pointers; i++) { dtAppend("*"); } return typeName[typeNameSwap]; } int dtGetSize(DataType dt, Structs* sts) { if(dt.pointers > 0 || dtIsNull(dt)) { return sizeof(Pointer); } switch(dt.type) { case DT_INT32: return sizeof(int32); case DT_INT64: return sizeof(int64); case DT_FLOAT: return sizeof(float); case DT_BOOL: return sizeof(bool); case DT_STRUCT: { int size = 0; Struct* st = sts->data + dt.structId; for(int i = 0; i < st->amount; i++) { size += dtGetSize(st->vars[i].type, sts); } return size; } default: return 0; } } DataType dtInt32() { DataType dt = {DT_INT32, 0, 0, 0}; return dt; } DataType dtInt64() { DataType dt = {DT_INT64, 0, 0, 0}; return dt; } DataType dtFloat() { DataType dt = {DT_FLOAT, 0, 0, 0}; return dt; } DataType dtBool() { DataType dt = {DT_BOOL, 0, 0, 0}; return dt; } DataType dtNull() { DataType dt = {DT_NULL, 0, 0, 0}; return dt; } DataType dtText() { DataType dt = {DT_INT32, 1, 0, 0}; return dt; } DataType dtVoid() { DataType dt = {DT_VOID, 0, 0, 0}; return dt; } DataType dtStruct(Struct* st) { DataType dt = {DT_STRUCT, 0, 0, st->id}; return dt; } DataType dtReference(DataType dt) { dt.pointers--; return dt; } bool dtDereference(DataType* dt) { if(dt->pointers == 15) { return true; } dt->pointers++; return false; } static bool dtInternCompare(DataType a, DataType b) { return a.pointers == b.pointers && a.structId == b.structId && a.type == b.type && a.constant == b.constant; } bool dtCompare(DataType a, DataType b) { return dtInternCompare(a, b); } bool dtNullCompare(DataType a, DataType bOrNull) { return dtInternCompare(a, bOrNull) || (dtIsPointer(a) && dtIsNull(bOrNull) && a.constant == bOrNull.constant); } bool dtIsInt32(DataType dt) { return dtCompare(dt, dtInt32()); } bool dtIsInt64(DataType dt) { return dtCompare(dt, dtInt64()); } bool dtIsFloat(DataType dt) { return dtCompare(dt, dtFloat()); } bool dtIsBool(DataType dt) { return dtCompare(dt, dtBool()); } bool dtIsNull(DataType dt) { dt.constant = 0; return dtCompare(dt, dtNull()); } bool dtIsVoid(DataType dt) { return dtCompare(dt, dtVoid()); } bool dtIsPointer(DataType dt) { return dt.pointers > 0; } bool dtIsVariable(DataType dt) { return dt.type & 8; } Struct* dtGetStruct(Structs* sts, DataType dt) { if(dt.type != DT_STRUCT) { return NULL; } return sts->data + dt.structId; } DataType dtToVariable(DataType dt) { dt.type |= 8; return dt; } bool dtRemoveVariable(DataType* dt) { if(dtIsVariable(*dt)) { dt->type &= 7; return true; } return false; } DataType dtConst(DataType dt) { dt.constant = 1; return dt; } void stAddVariable(Struct* st, const char* name, DataType type) { int index = st->amount; st->amount++; st->vars = realloc(st->vars, sizeof(StructVariable) * st->amount); st->vars[index].name = name; st->vars[index].type = type; } void stsInit(Structs* sts) { sts->capacity = 4; sts->entries = 0; sts->data = malloc(sizeof(Struct) * sts->capacity); } void stsDelete(Structs* sts) { for(int i = 0; i < sts->entries; i++) { free(sts->data[i].vars); } free(sts->data); } static Struct* stsInternSearch(Structs* sts, const char* name) { for(int i = 0; i < sts->entries; i++) { if(strcmp(sts->data[i].name, name) == 0) { return sts->data + i; } } return NULL; } Struct* stsSearch(Structs* sts, const char* name) { if(useGlobals) { Struct* st = stsInternSearch(&globalStructs, name); if(st != NULL) { return st; } } return stsInternSearch(sts, name); } Struct* stsAdd(Structs* sts, const char* name) { if(sts->entries >= sts->capacity) { sts->capacity *= 2; sts->data = realloc(sts->data, sizeof(Struct) * sts->capacity); } int index = sts->entries++; sts->data[index].id = index; sts->data[index].amount = 0; sts->data[index].name = name; sts->data[index].vars = NULL; return sts->data + index; } void gstsInit() { stsInit(&globalStructs); useGlobals = true; } void gstsDelete() { stsDelete(&globalStructs); useGlobals = false; } Structs* gstsGet() { return &globalStructs; } Struct* gstsAdd(const char* name) { return stsAdd(&globalStructs, name); }