|  | @@ -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) {
 |