| 
					
				 | 
			
			
				@@ -198,9 +198,40 @@ static const char* cReadString() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static DataType cExpression(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void cLoadRef(DataType type) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(dtIsPointer(type)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        cAddOperation(OP_REFERENCE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    switch(type.type) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DT_OPERATION(LOAD); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case DT_STRUCT: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Struct* st = dtGetStruct(&structs, type); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if(st == NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    cError("compiler struct error"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                cAddIntOperation(OP_LOAD, dtGetSize(type, &structs)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        default: cError("cannot load type %s", cGetName(type)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static DataType cUnpack(DataType dt) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(dtRemoveVariable(&dt)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        cLoadRef(dt); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return dt; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static DataType cUnpackedExpression() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return cUnpack(cExpression()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void cCallFunctionArguments(Function* f) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     while(!cConsumeTokenIf(T_CLOSE_BRACKET)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        DataType dt = cExpression(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DataType dt = cUnpackedExpression(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if(fAddArgument(f, dt, &structs)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             cTooMuchArguments(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -239,7 +270,7 @@ static void cWalkStruct(Variable* v) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 cError("[] need a pointer"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             cAddOperation(OP_REFERENCE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            DataType index = cExpression(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            DataType index = cUnpackedExpression(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if(!dtCompare(index, dtInt())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 cError("array index must be an int"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -290,26 +321,6 @@ static void cReference(Variable* v, int dimension) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     cWalkStruct(v); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-static void cLoadRef(Variable* v) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if(dtIsPointer(v->type)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        cAddOperation(OP_LOAD_POINTER); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    switch(v->type.type) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        DT_OPERATION(LOAD); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        case DT_STRUCT: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                Struct* st = dtGetStruct(&structs, v->type); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if(st == NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    cError("compiler struct error"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                cAddIntOperation(OP_LOAD, dtGetSize(v->type, &structs)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        default: cError("cannot load type %s", cGetName(v->type)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void cStore(Variable* v, DataType dt, const char* name) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if(!dtCompare(v->type, dt)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         cInvalidOperation(v->type, dt, name); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -324,14 +335,6 @@ static void cStore(Variable* v, DataType dt, const char* name) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-static DataType cPostChange(Variable* v, int change, const char* name) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if(!dtCompare(v->type, dtInt())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        cError("%s needs an int", name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    cAddByteOperation(OP_PUSH_POST_INT_CHANGE, change); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return dtInt(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static DataType cLiteral() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     const char* literal = cReadString(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if(cConsumeTokenIf(T_OPEN_BRACKET)) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -345,14 +348,15 @@ static DataType cLiteral() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if(vsSearch(&vars, &v, literal)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         cNotDeclared(literal); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    cReference(&v, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    cAddIntOperation(OP_DEREFERENCE_VAR, v.address); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /*cWalkStruct(&v); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if(cConsumeTokenIf(T_INCREMENT)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return cPostChange(&v, 1, "++"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } else if(cConsumeTokenIf(T_DECREMENT)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return cPostChange(&v, -1, "--"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    cLoadRef(&v); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return v.type; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return dtToVariable(v.type); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static DataType cBracketPrimary() { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -361,20 +365,49 @@ static DataType cBracketPrimary() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return result; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static DataType cExtendType(DataType dt) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    while(cConsumeTokenIf(T_MUL)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        dt = dtDereference(dt); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return dt; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static DataType cReadType() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    DataType dt = dtVoid(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Token t = cReadTokenAndLine(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    switch(t) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case T_INT: dt = dtInt(); break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case T_BOOL: dt = dtBool(); break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case T_FLOAT: dt = dtFloat(); break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case T_LITERAL: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                const char* name = cReadString(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Struct* st = stsSearch(&structs, name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if(st == NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    cError("struct %s does not exist"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                dt = dtStruct(st); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        default: cUnexpectedToken(t); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return cExtendType(dt); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static DataType cAllocArray() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    cConsumeToken(T_INT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    DataType dt = cReadType(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     cConsumeToken(T_OPEN_SQUARE_BRACKET); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    DataType index = cExpression(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    DataType index = cUnpackedExpression(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if(!dtCompare(index, dtInt())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         cError("array size must be an int"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     cConsumeToken(T_CLOSE_SQUARE_BRACKET); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    cAddIntOperation(OP_NEW, dtGetSize(dtInt(), &structs)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return dtToArray(dtInt(), 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    cAddIntOperation(OP_NEW, dtGetSize(dt, &structs)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return dtDereference(dt); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static DataType cLength() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    DataType pointer = cExpression(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    DataType pointer = cUnpackedExpression(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if(!dtIsPointer(pointer)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         cError("length expects a pointer"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -397,83 +430,117 @@ static DataType cPrimary() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-static DataType cPreChange(int change, const char* name) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void cPostChange(DataType* dt, int change, const char* name) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(!dtRemoveVariable(dt) || !dtCompare(*dt, dtInt())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        cError("%s needs an int reference", name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    cAddByteOperation(OP_PUSH_POST_INT_CHANGE, change); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static DataType cStructAccess(DataType dt, int pointers) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Struct* st = dtGetStruct(&structs, dt); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(st == NULL || dt.pointers != pointers) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        cError(pointers == 0 ? ". expects a struct" : "-> expects a struct*"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     cConsumeToken(T_LITERAL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const char* literal = cReadString(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    Variable v; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if(vsSearch(&vars, &v, literal)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        cNotDeclared(literal); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const char* name = cReadString(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Variable inner; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(vSearchStruct(&inner, &structs, st, name)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        cError("%s has no member %s", st->name, name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    cReference(&v, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if(!dtCompare(v.type, dtInt())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        cError("%s needs an int", name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(inner.address > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        cAddIntOperation(OP_PUSH_INT, inner.address); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        cAddOperation(OP_ADD_REFERENCE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return dtToVariable(inner.type); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static DataType cAccess() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    DataType dt = cPrimary(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    while(true) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(cConsumeTokenIf(T_INCREMENT)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cPostChange(&dt, 1, "++"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else if(cConsumeTokenIf(T_DECREMENT)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cPostChange(&dt, -1, "--"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else if(cConsumeTokenIf(T_POINT)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if(!dtRemoveVariable(&dt)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                cError(". expects a reference"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            dt = cStructAccess(dt, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else if(cConsumeTokenIf(T_ARROW)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            dt = cStructAccess(cUnpack(dt), 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else if(cConsumeTokenIf(T_OPEN_SQUARE_BRACKET)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            dt = cUnpack(dt); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if(!dtIsPointer(dt)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                cError("[] needs a pointer"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            DataType index = cUnpackedExpression(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if(!dtCompare(index, dtInt())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                cError("array index must be an int"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cConsumeToken(T_CLOSE_SQUARE_BRACKET); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cAddOperation(OP_ADD_REFERENCE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            dt = dtToVariable(dtReference(dt)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return dt; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static DataType cPreChange(DataType dt, int change, const char* name) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(!dtRemoveVariable(&dt) || !dtCompare(dt, dtInt())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        cError("%s needs an int reference", name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     cAddByteOperation(OP_PUSH_PRE_INT_CHANGE, change); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return dtInt(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return dt; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static DataType cPreUnary() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if(cConsumeTokenIf(T_SUB)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        DataType result = cPrimary(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if(dtCompare(result, dtInt())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(cConsumeTokenIf(T_INCREMENT)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return cPreChange(cPreUnary(), 1, "++"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else if(cConsumeTokenIf(T_DECREMENT)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return cPreChange(cPreUnary(), -1, "--"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else if(cConsumeTokenIf(T_SUB)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DataType dt = cUnpack(cPreUnary()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(dtCompare(dt, dtInt())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             cAddOperation(OP_INVERT_SIGN_INT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } else if(dtCompare(result, dtFloat())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else if(dtCompare(dt, dtFloat())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             cAddOperation(OP_INVERT_SIGN_FLOAT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            cError("cannot invert sign of %s", cGetName(result)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cError("cannot invert sign of %s", cGetName(dt)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return result; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } else if(cConsumeTokenIf(T_INCREMENT)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return cPreChange(1, "++"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } else if(cConsumeTokenIf(T_DECREMENT)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return cPreChange(-1, "--"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return dt; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } else if(cConsumeTokenIf(T_NOT)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        int counter = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        while(cConsumeTokenIf(T_NOT)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            counter++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        DataType result = cPrimary(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if(!dtCompare(result, dtBool())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            cError("! needs a bool not %s", cGetName(result)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DataType dt = cPreUnary(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(!dtCompare(dt, dtBool())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cError("! needs a bool not %s", cGetName(dt)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         cAddOperation(OP_NOT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if((counter & 1) == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            cAddOperation(OP_NOT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return dtBool(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return dt; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } else if(cConsumeTokenIf(T_BIT_NOT)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        DataType result = cPrimary(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if(dtCompare(result, dtInt())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            cAddOperation(OP_BIT_NOT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            cError("~ needs an int not %s", cGetName(result)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DataType dt = cPreUnary(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(!dtCompare(dt, dtInt())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cError("~ needs an int not %s", cGetName(dt)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return result; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        cAddOperation(OP_BIT_NOT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return dt; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } else if(cConsumeTokenIf(T_BIT_AND)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        cConsumeToken(T_LITERAL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        const char* literal = cReadString(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        Variable v; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if(vsSearch(&vars, &v, literal)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            cNotDeclared(literal); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DataType dt = cPreUnary(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(!dtRemoveVariable(&dt)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cError("& needs a reference"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        cReference(&v, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return dtDereference(v.type); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return dtDereference(dt); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } else if(cConsumeTokenIf(T_MUL)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        int c = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        while(cConsumeTokenIf(T_MUL)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            c++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        cConsumeToken(T_LITERAL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        const char* literal = cReadString(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        Variable v; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if(vsSearch(&vars, &v, literal)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            cNotDeclared(literal); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DataType dt = cPreUnary(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(!dtIsPointer(dt)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cError("* expects a pointer"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        cReference(&v, c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        cLoadRef(&v); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return v.type; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        dt = dtReference(dt); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        cAddOperation(OP_REFERENCE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return dt; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return cPrimary(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return cAccess(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void cAddTypeOperation(DataType a, DataType b, const TypedOp* op) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -498,11 +565,14 @@ static DataType cMul() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     DataType a = cPreUnary(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     while(true) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if(cConsumeTokenIf(T_MUL)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            cAddTypeOperation(a, cPreUnary(), &TYPED_MUL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            a = cUnpack(a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cAddTypeOperation(a, cUnpack(cPreUnary()), &TYPED_MUL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } else if(cConsumeTokenIf(T_DIV)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            cAddTypeOperation(a, cPreUnary(), &TYPED_DIV); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            a = cUnpack(a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cAddTypeOperation(a, cUnpack(cPreUnary()), &TYPED_DIV); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } else if(cConsumeTokenIf(T_MOD)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            cAddTypeOperation(a, cPreUnary(), &TYPED_MOD); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            a = cUnpack(a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cAddTypeOperation(a, cUnpack(cPreUnary()), &TYPED_MOD); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -514,9 +584,11 @@ static DataType cAdd() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     DataType a = cMul(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     while(true) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if(cConsumeTokenIf(T_ADD)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            cAddTypeOperation(a, cMul(), &TYPED_ADD); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            a = cUnpack(a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cAddTypeOperation(a, cUnpack(cMul()), &TYPED_ADD); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } else if(cConsumeTokenIf(T_SUB)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            cAddTypeOperation(a, cMul(), &TYPED_SUB); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            a = cUnpack(a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cAddTypeOperation(a, cUnpack(cMul()), &TYPED_SUB); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -528,9 +600,11 @@ static DataType cShift() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     DataType a = cAdd(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     while(true) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if(cConsumeTokenIf(T_LEFT_SHIFT)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            cAddTypeOperation(a, cAdd(), &TYPED_LEFT_SHIFT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            a = cUnpack(a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cAddTypeOperation(a, cUnpack(cAdd()), &TYPED_LEFT_SHIFT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } else if(cConsumeTokenIf(T_RIGHT_SHIFT)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            cAddTypeOperation(a, cAdd(), &TYPED_RIGHT_SHIFT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            a = cUnpack(a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cAddTypeOperation(a, cUnpack(cAdd()), &TYPED_RIGHT_SHIFT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -542,17 +616,21 @@ static DataType cComparison() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     DataType a = cShift(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     while(true) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if(cConsumeTokenIf(T_LESS)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            cAddTypeOperation(a, cShift(), &TYPED_LESS); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            a = cUnpack(a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cAddTypeOperation(a, cUnpack(cShift()), &TYPED_LESS); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             a = dtBool(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } else if(cConsumeTokenIf(T_LESS_EQUAL)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            cAddTypeOperation(a, cShift(), &TYPED_LESS_EQUAL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            a = cUnpack(a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cAddTypeOperation(a, cUnpack(cShift()), &TYPED_LESS_EQUAL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             cAddOperation(OP_NOT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             a = dtBool(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } else if(cConsumeTokenIf(T_GREATER)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            cAddTypeOperation(a, cShift(), &TYPED_GREATER); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            a = cUnpack(a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cAddTypeOperation(a, cUnpack(cShift()), &TYPED_GREATER); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             a = dtBool(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } else if(cConsumeTokenIf(T_GREATER_EQUAL)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            cAddTypeOperation(a, cShift(), &TYPED_GREATER_EQUAL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            a = cUnpack(a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cAddTypeOperation(a, cUnpack(cShift()), &TYPED_GREATER_EQUAL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             cAddOperation(OP_NOT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             a = dtBool(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } else { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -566,10 +644,12 @@ static DataType cEqual() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     DataType a = cComparison(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     while(true) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if(cConsumeTokenIf(T_EQUAL)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            cAddTypeOperation(a, cComparison(), &TYPED_EQUAL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            a = cUnpack(a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cAddTypeOperation(a, cUnpack(cComparison()), &TYPED_EQUAL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             a = dtBool(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } else if(cConsumeTokenIf(T_NOT_EQUAL)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            cAddTypeOperation(a, cComparison(), &TYPED_NOT_EQUAL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            a = cUnpack(a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cAddTypeOperation(a, cUnpack(cComparison()), &TYPED_NOT_EQUAL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             cAddOperation(OP_NOT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             a = dtBool(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } else { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -582,8 +662,8 @@ static DataType cEqual() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static DataType cBitAnd() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     DataType a = cEqual(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     while(cConsumeTokenIf(T_BIT_AND)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        DataType b = cEqual(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        cAddTypeOperation(a, b, &TYPED_BIT_AND); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        a = cUnpack(a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        cAddTypeOperation(a, cUnpack(cEqual()), &TYPED_BIT_AND); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return a; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -591,8 +671,8 @@ static DataType cBitAnd() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static DataType cBitXor() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     DataType a = cBitAnd(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     while(cConsumeTokenIf(T_BIT_XOR)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        DataType b = cBitAnd(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        cAddTypeOperation(a, b, &TYPED_BIT_XOR); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        a = cUnpack(a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        cAddTypeOperation(a, cUnpack(cBitAnd()), &TYPED_BIT_XOR); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return a; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -600,8 +680,8 @@ static DataType cBitXor() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static DataType cBitOr() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     DataType a = cBitXor(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     while(cConsumeTokenIf(T_BIT_OR)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        DataType b = cBitXor(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        cAddTypeOperation(a, b, &TYPED_BIT_OR); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        a = cUnpack(a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        cAddTypeOperation(a, cUnpack(cBitXor()), &TYPED_BIT_OR); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return a; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -609,9 +689,10 @@ static DataType cBitOr() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static DataType cAnd() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     DataType a = cBitOr(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     while(cConsumeTokenIf(T_AND)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        a = cUnpack(a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         cAddOperation(OP_PEEK_FALSE_GOTO); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         int p = cReserveInt(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        DataType b = cBitOr(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DataType b = cUnpack(cBitOr()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if(!dtCompare(a, dtBool()) || !dtCompare(b, dtBool())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             cInvalidOperation(a, b, "&&"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -624,9 +705,10 @@ static DataType cAnd() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static DataType cOr() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     DataType a = cAnd(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     while(cConsumeTokenIf(T_OR)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        a = cUnpack(a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         cAddOperation(OP_PEEK_TRUE_GOTO); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         int p = cReserveInt(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        DataType b = cAnd(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DataType b = cUnpack(cAnd()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if(!dtCompare(a, dtBool()) || !dtCompare(b, dtBool())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             cInvalidOperation(a, b, "||"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -642,8 +724,8 @@ static DataType cExpression() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void cOperationSet(Variable* v, const TypedOp* op) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     cAddOperation(OP_DUPLICATE_REFERENCE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    cLoadRef(v); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    DataType dt = cExpression(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    cLoadRef(v->type); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    DataType dt = cUnpackedExpression(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     cAddTypeOperation(v->type, dt, op); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     cStore(v, dt, "="); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -655,13 +737,6 @@ static void cAddPostLineChange(Variable* v, int change, const char* name) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     cAddByteOperation(OP_INT_CHANGE, change); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-static DataType cExtendType(DataType dt) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    while(cConsumeTokenIf(T_MUL)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        dt = dtDereference(dt); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return dt; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void cDeclareStruct(Struct* st) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     DataType dt = cExtendType(dtStruct(st)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     cConsumeToken(T_LITERAL); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -673,7 +748,7 @@ static void cDeclareStruct(Struct* st) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if(dtIsPointer(dt)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         cConsumeToken(T_SET); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         cReference(vp, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        cStore(vp, cExpression(), "="); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        cStore(vp, cUnpackedExpression(), "="); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -685,7 +760,7 @@ static void cLineVariable(const char* name, int dimension) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     cReference(&v, dimension); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     Token t = cReadTokenAndLine(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     switch(t) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        case T_SET: cStore(&v, cExpression(), "="); break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case T_SET: cStore(&v, cUnpackedExpression(), "="); break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         case T_ADD_SET: cOperationSet(&v, &TYPED_ADD); break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         case T_SUB_SET: cOperationSet(&v, &TYPED_SUB); break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         case T_MUL_SET: cOperationSet(&v, &TYPED_MUL); break; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -755,7 +830,7 @@ static void cReturn() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         cAddReturn(OP_RETURN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    DataType dt = cExpression(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    DataType dt = cUnpackedExpression(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if(!dtCompare(dt, returnType)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         cError("wrong return type, should be %s", cGetName(returnType)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -772,7 +847,7 @@ static void cReturn() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void cPrint() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    DataType dt = cExpression(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    DataType dt = cUnpackedExpression(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if(dtIsPointer(dt)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         cAddOperation(OP_PRINT_POINTER); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         cConsumeToken(T_SEMICOLON); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -787,7 +862,7 @@ static void cPrint() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void cIf() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     cConsumeToken(T_OPEN_BRACKET); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    DataType dt = cExpression(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    DataType dt = cUnpackedExpression(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if(!dtCompare(dt, dtBool())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         cError("if expects a bool not %s", cGetName(dt)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -822,7 +897,7 @@ static void cConsumeBreaks(int start, int address) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void cWhile() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     int start = code->length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     cConsumeToken(T_OPEN_BRACKET); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    DataType dt = cExpression(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    DataType dt = cUnpackedExpression(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if(!dtCompare(dt, dtBool())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         cError("while expects a bool not %s", cGetName(dt)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -852,7 +927,7 @@ static void cDeclare(DataType dt) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     Variable* vp = vsAdd(&vars, var, dt, &structs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     cConsumeToken(T_SET); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     cReference(vp, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    cStore(vp, cExpression(), "="); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    cStore(vp, cUnpackedExpression(), "="); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void cAddPreLineChange(int change, const char* name) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -867,7 +942,7 @@ static void cAddPreLineChange(int change, const char* name) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void cDelete() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    DataType pointer = cExpression(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    DataType pointer = cUnpackedExpression(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if(!dtIsPointer(pointer)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         cError("delete expects a pointer"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -905,7 +980,7 @@ static void cFor() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     cLineExpression(cReadTokenAndLine()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     cConsumeToken(T_SEMICOLON); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     int startCheck = code->length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    DataType dt = cExpression(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    DataType dt = cUnpackedExpression(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if(!dtCompare(dt, dtBool())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         cError("for expects a bool not %s", cGetName(dt)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1108,25 +1183,7 @@ static void cStruct() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     DataType self = dtStruct(st); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     cConsumeToken(T_OPEN_CURVED_BRACKET); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     while(!cConsumeTokenIf(T_CLOSE_CURVED_BRACKET)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        Token t = cReadTokenAndLine(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        DataType dt = dtVoid(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        switch(t) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            case T_INT: dt = dtInt(); break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            case T_BOOL: dt = dtBool(); break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            case T_FLOAT: dt = dtFloat(); break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            case T_LITERAL: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    const char* name = cReadString(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    Struct* st = stsSearch(&structs, name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    if(st == NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        cError("struct %s does not exist"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    dt = dtStruct(st); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            default: cUnexpectedToken(t); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        dt = cExtendType(dt); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DataType dt = cReadType(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if(dtCompare(dt, self)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             cError("struct %s contains itself", name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 |