+// ---
+tSpiderValue *SpiderScript_DoOp(tSpiderValue *Left, int Operation, int bCanCast, tSpiderValue *Right)
+{
+ switch(Left->Type)
+ {
+ case SS_DATATYPE_INTEGER:
+ return SpiderScript_int_DoOpInt(Left, Operation, bCanCast, Right);
+ }
+ return NULL;
+}
+
+tSpiderValue *SpiderScript_int_DoOpInt(tSpiderValue *Left, int Operation, int bCanCast, tSpiderValue *Right)
+{
+ tSpiderValue *oldright = Right;
+ tSpiderValue *ret = NULL;
+ int64_t rv;
+
+ // Casting
+ if(Right && Right->Type != SS_DATATYPE_INTEGER) {
+ if(!bCanCast) return ERRPTR;
+ Right = SpiderScript_CastValueTo(Right, SS_DATATYPE_INTEGER);
+ }
+
+ // Do the operation
+ switch(Operation)
+ {
+ case SS_VALUEOP_NEGATE:
+ if(Right) ret = ERRPTR;
+ else rv = -Left->Integer;
+ break;
+ case SS_VALUEOP_ADD:
+ if(!Right) ret = ERRPTR;
+ else rv = Left->Integer + Right->Integer;
+ break;
+ }
+
+ // Delete temporary value
+ if( Right != oldright )
+ SpiderScript_DereferenceValue(Right);
+
+ // Return error if signaled
+ if(ret == ERRPTR)
+ return ERRPTR;
+
+ // Reuse `Left` if possible, to reduce mallocs
+ if(Left->ReferenceCount == 1) {
+ SpiderScript_ReferenceValue(Left);
+ Left->Integer = rv;
+ return Left;
+ }
+ else {
+ return SpiderScript_CreateInteger(rv);
+ }
+}