Browse Source

datatype does not use bitfields any more

Kajetan Johannes Hammerle 1 year ago
parent
commit
f32f8de174
3 changed files with 112 additions and 55 deletions
  1. 11 11
      Compiler.c
  2. 75 36
      DataType.c
  3. 26 8
      DataType.h

+ 11 - 11
Compiler.c

@@ -23,8 +23,8 @@ static jmp_buf errorJump;
 #define BREAK_BUFFER 32
 
 #define DT_OPERATION(op)                                                       \
-    case DT_INT: cAddOperation(OP_##op##_INT); break;                          \
-    case DT_FLOAT: cAddOperation(OP_##op##_FLOAT); break;
+    case RDT_INT: cAddOperation(OP_##op##_INT); break;                         \
+    case RDT_FLOAT: cAddOperation(OP_##op##_FLOAT); break;
 
 typedef DataType (*Parser)(void);
 
@@ -247,14 +247,14 @@ static void cLoadRef(DataType type) {
         cAddOperation(OP_LOAD_ARRAY);
         return;
     }
-    switch(type.type) {
+    switch(dtGetType(type)) {
         DT_OPERATION(LOAD);
         default: cError("cannot load type %s", cGetName(type));
     }
 }
 
 static DataType cUnpack(DataType dt) {
-    if(dt.type != DT_STRUCT && dtRemovePointer(&dt)) {
+    if(!dtIsStruct(dt) && dtRemovePointer(&dt)) {
         cLoadRef(dt);
     }
     return dt;
@@ -319,7 +319,7 @@ static void cStore(DataType left, DataType right, const char* name) {
     if(!dtCompare(left, right)) {
         cInvalidOperation(left, right, name);
     }
-    switch(left.type) {
+    switch(dtGetType(left)) {
         DT_OPERATION(STORE);
         default: cError("cannot store type %s", cGetName(left));
     }
@@ -332,8 +332,8 @@ static DataType cLiteral(void) {
     }
     Variable v;
     if(!vsSearch(&vars, &v, literal)) {
-        if(v.type.pointer != 0) {
-            if(v.type.type != DT_STRUCT) {
+        if(dtIsPointer(v.type)) {
+            if(!dtIsStruct(v.type)) {
                 cError("non struct type %s should not be a pointer here",
                        cGetName(v.type));
             }
@@ -377,7 +377,7 @@ static void cArrayIndex(void) {
 
 static DataType cAllocArray(void) {
     DataType dt = cReadType(cReadTokenAndLine(), true);
-    if(dt.array != 0) {
+    if(dtIsArray(dt)) {
         cError("array type must not be an array");
     }
     cConsumeToken(T_OPEN_SQUARE_BRACKET);
@@ -830,7 +830,7 @@ static void cDeclareSet(Variables* vs, DataType dt, const char* var,
         cDeclared(var);
     }
     Variable* v = vsAdd(vs, var, dt, &structs);
-    if(dt.type != DT_STRUCT || dtIsArray(dt)) {
+    if(!dtIsStruct(dt) || dtIsArray(dt)) {
         cConsumeToken(T_SET);
         cAddInt32Operation(op, v->address);
         DataType right = cUnpackedExpression();
@@ -932,7 +932,7 @@ static void cLine(void) {
 }
 
 static void cBuildFunction(Function* f, DataType rType, const char* fName) {
-    if(rType.type == DT_STRUCT && rType.array == 0) {
+    if(dtIsStruct(rType) && !dtIsArray(rType)) {
         cError("structs cannot be returned");
     }
     fInit(f, fName, line);
@@ -949,7 +949,7 @@ static void cBuildFunction(Function* f, DataType rType, const char* fName) {
         if(vsInScope(&vars, name)) {
             cDeclared(name);
         }
-        if(dt.type == DT_STRUCT) {
+        if(dtIsStruct(dt)) {
             dt = dtToPointer(dt);
         }
         vsAdd(&vars, name, dt, &structs);

+ 75 - 36
DataType.c

@@ -71,10 +71,10 @@ static void dtAppend(const char* s) {
 const char* dtGetName(const Structs* sts, DataType dt) {
     typeNameSwap = !typeNameSwap;
     typeNameIndex = 0;
-    switch(dt.type) {
-        case DT_INT: dtAppend("int"); break;
-        case DT_FLOAT: dtAppend("float"); break;
-        case DT_STRUCT: {
+    switch(dtGetType(dt)) {
+        case RDT_INT: dtAppend("int"); break;
+        case RDT_FLOAT: dtAppend("float"); break;
+        case RDT_STRUCT: {
             Struct* s = dtGetStruct(sts, dt);
             if(s != NULL) {
                 dtAppend(s->name);
@@ -83,26 +83,27 @@ const char* dtGetName(const Structs* sts, DataType dt) {
             }
             break;
         }
-        case DT_VOID: dtAppend("void"); break;
-        default: dtAppend("unknown");
+        case RDT_VOID: dtAppend("void"); break;
+        case RDT_INVALID: dtAppend("invalid"); break;
+        default: dtAppend("?");
     }
-    if(dt.array != 0) {
+    if(dtIsArray(dt)) {
         dtAppend("[]");
     }
-    if(dt.pointer != 0) {
+    if(dtIsPointer(dt)) {
         dtAppend("*");
     }
     return typeName[typeNameSwap];
 }
 
 int dtGetSize(DataType dt, const Structs* sts) {
-    if(dt.pointer != 0) {
+    if(dtIsPointer(dt)) {
         return 1;
     }
-    switch(dt.type) {
-        case DT_INT: return 1;
-        case DT_FLOAT: return 1;
-        case DT_STRUCT: {
+    switch(dtGetType(dt)) {
+        case RDT_INT: return 1;
+        case RDT_FLOAT: return 1;
+        case RDT_STRUCT: {
             int size = 0;
             Struct* st = dtGetStruct(sts, dt);
             if(st == NULL) {
@@ -113,61 +114,79 @@ int dtGetSize(DataType dt, const Structs* sts) {
             }
             return size;
         }
-        default: return 0;
+        case RDT_LAST:
+        case RDT_VOID:
+        case RDT_INVALID: return 0;
     }
+    return 0;
+}
+
+static DataType dtBuild(RawDataType rdt, bool isPointer, bool isArray,
+                        int32 structId) {
+    if(rdt < 0 || rdt >= RDT_LAST || structId < 0 ||
+       structId > DT_MAX_STRUCT_ID) {
+        return (DataType){RDT_INVALID};
+    }
+    return (DataType){((uint32)rdt << DT_TYPE_OFFSET) |
+                      ((uint32)isPointer << DT_IS_POINTER_OFFSET) |
+                      ((uint32)isArray << DT_IS_ARRAY_OFFSET) |
+                      ((uint32)structId << DT_STRUCT_ID_OFFSET)};
 }
 
 DataType dtInt(void) {
-    DataType dt = {DT_INT, 0, 0, 0};
-    return dt;
+    return dtBuild(RDT_INT, false, false, 0);
 }
 
 DataType dtFloat(void) {
-    DataType dt = {DT_FLOAT, 0, 0, 0};
-    return dt;
+    return dtBuild(RDT_FLOAT, false, false, 0);
 }
 
 DataType dtVoid(void) {
-    DataType dt = {DT_VOID, 0, 0, 0};
-    return dt;
+    return dtBuild(RDT_VOID, false, false, 0);
 }
 
 DataType dtStruct(const Struct* st) {
-    DataType dt = {DT_STRUCT, 0, 0, st->id};
-    return dt;
+    return dtBuild(RDT_STRUCT, false, false, st->id);
 }
 
 DataType dtText(void) {
-    DataType dt = {DT_INT, 0, 1, 0};
-    return dt;
+    return dtBuild(RDT_INT, false, true, 0);
 }
 
 DataType dtToArray(DataType dt) {
-    dt.array = 1;
+    dt.data |= 1 << DT_IS_ARRAY_OFFSET;
     return dt;
 }
 
 DataType dtRemoveArray(DataType dt) {
-    dt.array = 0;
+    dt.data &= ~(((1u << DT_IS_ARRAY_BIT_SIZE) - 1u) << DT_IS_ARRAY_OFFSET);
     return dt;
 }
 
 DataType dtToPointer(DataType dt) {
-    dt.pointer = 1;
+    dt.data |= 1 << DT_IS_POINTER_OFFSET;
     return dt;
 }
 
 bool dtRemovePointer(DataType* dt) {
-    if(dt->pointer != 0) {
-        dt->pointer = 0;
+    if(dtIsPointer(*dt)) {
+        dt->data &=
+            ~(((1u << DT_IS_POINTER_BIT_SIZE) - 1u) << DT_IS_POINTER_OFFSET);
         return true;
     }
     return false;
 }
 
+RawDataType dtGetType(DataType dt) {
+    uint32 type = dt.data & (((1u << DT_TYPE_BIT_SIZE) - 1u) << DT_TYPE_OFFSET);
+    if(type >= RDT_LAST) {
+        return RDT_INVALID;
+    }
+    return (RawDataType)type;
+}
+
 bool dtCompare(DataType a, DataType b) {
-    return a.array == b.array && a.structId == b.structId && a.type == b.type &&
-           a.pointer == b.pointer;
+    return a.data == b.data;
 }
 
 bool dtIsInt(DataType dt) {
@@ -183,20 +202,40 @@ bool dtIsVoid(DataType dt) {
 }
 
 bool dtIsArray(DataType dt) {
-    return dt.array != 0;
+    return dt.data &
+           (((1u << DT_IS_ARRAY_BIT_SIZE) - 1u) << DT_IS_ARRAY_OFFSET);
+}
+
+bool dtIsStruct(DataType dt) {
+    return dtGetType(dt) == RDT_STRUCT;
+}
+
+bool dtIsPointer(DataType dt) {
+    return dt.data &
+           (((1u << DT_IS_POINTER_BIT_SIZE) - 1u) << DT_IS_POINTER_OFFSET);
 }
 
 Struct* dtGetStruct(const Structs* sts, DataType dt) {
-    if(dt.type != DT_STRUCT) {
+    if(!dtIsStruct(dt)) {
         return NULL;
     }
-    if(dt.structId & 1) {
+    int32 structId = (int32)((dt.data >> DT_STRUCT_ID_OFFSET) &
+                             ((1u << DT_STRUCT_ID_BIT_SIZE) - 1u));
+    if(structId & 1) {
         if(!useGlobals) {
             return NULL;
         }
-        return globalStructs.data + (dt.structId >> 1);
+        structId >>= 1;
+        if(structId < 0 || structId >= globalStructs.entries) {
+            return NULL;
+        }
+        return globalStructs.data + structId;
+    }
+    structId >>= 1;
+    if(structId < 0 || structId >= sts->entries) {
+        return NULL;
     }
-    return sts->data + (dt.structId >> 1);
+    return sts->data + structId;
 }
 
 void stAddVariable(Struct* st, const char* name, DataType type) {

+ 26 - 8
DataType.h

@@ -32,18 +32,33 @@ typedef struct {
     } data;
 } Value;
 
-#define DT_INT 0
-#define DT_FLOAT 1
-#define DT_VOID 2
-#define DT_STRUCT 3
+typedef enum {
+    RDT_INVALID = 0,
+    RDT_INT,
+    RDT_FLOAT,
+    RDT_VOID,
+    RDT_STRUCT,
+    RDT_LAST
+} RawDataType;
 
 typedef struct {
-    uint8 type : 7;
-    uint8 pointer : 1;
-    uint8 array;
-    uint16 structId;
+    uint32 data;
 } DataType;
 
+#define DT_TYPE_BIT_SIZE 4
+#define DT_IS_POINTER_BIT_SIZE 1
+#define DT_IS_ARRAY_BIT_SIZE 1
+#define DT_STRUCT_ID_BIT_SIZE                                                  \
+    (32 - DT_TYPE_BIT_SIZE - DT_IS_POINTER_BIT_SIZE - DT_IS_ARRAY_BIT_SIZE)
+static_assert(RDT_LAST < (1 << DT_TYPE_BIT_SIZE));
+
+#define DT_MAX_STRUCT_ID ((1 << DT_STRUCT_ID_BIT_SIZE) - 1)
+
+#define DT_TYPE_OFFSET 0
+#define DT_IS_POINTER_OFFSET (DT_TYPE_OFFSET + DT_TYPE_BIT_SIZE)
+#define DT_IS_ARRAY_OFFSET (DT_IS_POINTER_OFFSET + DT_IS_POINTER_BIT_SIZE)
+#define DT_STRUCT_ID_OFFSET (DT_IS_ARRAY_OFFSET + DT_IS_ARRAY_BIT_SIZE)
+
 typedef struct {
     const char* name;
     DataType type;
@@ -85,11 +100,14 @@ Struct* dtGetStruct(const Structs* sts, DataType dt);
 DataType dtToPointer(DataType dt);
 bool dtRemovePointer(DataType* dt);
 
+RawDataType dtGetType(DataType dt);
 bool dtCompare(DataType a, DataType b);
 bool dtIsInt(DataType dt);
 bool dtIsFloat(DataType dt);
 bool dtIsVoid(DataType dt);
 bool dtIsArray(DataType dt);
+bool dtIsStruct(DataType dt);
+bool dtIsPointer(DataType dt);
 
 const char* dtGetName(const Structs* sts, DataType dt);