X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FLibraries%2Flibspiderscript.so_src%2Fvalues.c;h=f72e2903d9f65e90346c4e4ebca47349649fe0a2;hb=edf4c879ac931092da63389e186f06f08e324680;hp=12e1bf0d92351803924bd067915b52c0abad4afd;hpb=a18890d3ecb360989383d727017a21c103fee865;p=tpg%2Facess2.git diff --git a/Usermode/Libraries/libspiderscript.so_src/values.c b/Usermode/Libraries/libspiderscript.so_src/values.c index 12e1bf0d..f72e2903 100644 --- a/Usermode/Libraries/libspiderscript.so_src/values.c +++ b/Usermode/Libraries/libspiderscript.so_src/values.c @@ -23,6 +23,12 @@ tSpiderValue *SpiderScript_CastValueTo(int Type, tSpiderValue *Source); int SpiderScript_IsValueTrue(tSpiderValue *Value); void SpiderScript_FreeValue(tSpiderValue *Value); char *SpiderScript_DumpValue(tSpiderValue *Value); +// --- Operations +tSpiderValue *SpiderScript_DoOp(tSpiderValue *Left, int Operation, int bCanCast, tSpiderValue *Right); +tSpiderValue *SpiderScript_int_DoOpInt(tSpiderValue *Left, int Operation, int bCanCast, tSpiderValue *Right); +tSpiderValue *SpiderScript_int_DoOpReal(tSpiderValue *Left, int Operation, int bCanCast, tSpiderValue *Right); +tSpiderValue *SpiderScript_int_DoOpString(tSpiderValue *Left, int Operation, int bCanCast, tSpiderValue *Right); + // === CODE === /** @@ -398,4 +404,58 @@ char *SpiderScript_DumpValue(tSpiderValue *Value) } +// --- +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); + } +}