X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FLibraries%2Flibspiderscript.so_src%2Fvalues.c;h=f72e2903d9f65e90346c4e4ebca47349649fe0a2;hb=2f9415b7b804073b0365781ad4f05a7306b6c890;hp=f05360d4a2aa1443e2627ab3e7645c8481f0ceba;hpb=1e45480331132c75898cbdd761ddd1fa48739e54;p=tpg%2Facess2.git diff --git a/Usermode/Libraries/libspiderscript.so_src/values.c b/Usermode/Libraries/libspiderscript.so_src/values.c index f05360d4..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 === /** @@ -32,13 +38,20 @@ void SpiderScript_DereferenceValue(tSpiderValue *Object) { if(!Object || Object == ERRPTR) return ; Object->ReferenceCount --; + if(Object->Type == SS_DATATYPE_OBJECT) { + } if( Object->ReferenceCount == 0 ) { switch( (enum eSpiderScript_DataTypes) Object->Type ) { case SS_DATATYPE_OBJECT: - Object->Object->Type->Destructor( Object->Object ); + Object->Object->ReferenceCount --; + if(Object->Object->ReferenceCount == 0) { + Object->Object->Type->Destructor( Object->Object ); + } + Object->Object = NULL; break; + case SS_DATATYPE_OPAQUE: Object->Opaque.Destroy( Object->Opaque.Data ); break; @@ -169,7 +182,7 @@ tSpiderValue *SpiderScript_CastValueTo(int Type, tSpiderValue *Source) // Check if anything needs to be done if( Source->Type == Type ) { - SpiderScript_DereferenceValue(Source); + SpiderScript_ReferenceValue(Source); return Source; } @@ -391,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); + } +}