2
0
Эх сурвалжийг харах

Refactored the code, added method "set".

mingodad 13 жил өмнө
parent
commit
0b05002e76

+ 79 - 56
SquiLu-ext/sq_decimal.cpp

@@ -173,60 +173,6 @@ static mpd_context_t * sq_get_global_ctx(HSQUIRRELVM v, SQInteger idx)
     sq_getinstanceup(v, -1, (void**)&ctx, (void*)sq_decimal_ctx_TAG);
     sq_poptop(v);
 	return ctx;
-}
-
-static SQRESULT sq_Decimal_release_hook(SQUserPointer p, SQInteger size, HSQUIRRELVM v) {
-    mpd_t *dec = (mpd_t *)p;
-    if(dec) mpd_del(dec);
-    return 0;
-}
-
-/*
-** Creates a new Decimal.
-*/
-static SQRESULT sq_Decimal_constructor (HSQUIRRELVM v) {
-    SQ_FUNC_VARS(v);
-    GET_Decimal_INSTANCE(v, 1);
-    uint32_t status;
-    mpd_context_t *ctx = sq_get_global_ctx(v, 1);
-    if(_top_ > 1){
-        switch(sq_gettype(v, 2)){
-/*
-            case OT_INSTANCE:{
-                GET_DecimalCtx_INSTANCE(v, 2);
-                dec = mpd_new(ctx);
-                mpd_qset_i32(dec, 0, ctx, &status);
-            }
-*/
-            case OT_INTEGER:{
-                SQ_GET_INTEGER(v, 2, iparam);
-                dec = mpd_new(ctx);
-                mpd_qset_i32(dec, iparam, ctx, &status);
-            }
-            break;
-            case OT_STRING:{
-                SQ_GET_STRING(v, 2, str);
-                dec = mpd_new(ctx);
-                mpd_qset_string(dec, str, ctx, &status);
-            }
-            break;
-            case OT_FLOAT:{
-                SQ_GET_FLOAT(v, 2, fparam);
-                dec = mpd_new(ctx);
-                char buf[32];
-                snprintf(buf, sizeof(buf), "%f", fparam);
-                mpd_qset_string(dec, buf, ctx, &status);
-            }
-            break;
-        }
-    }
-    else {
-        dec = mpd_new(ctx);
-        mpd_qset_i32(dec, 0, ctx, &status);
-    }
-    sq_setinstanceup(v, 1, dec);
-    sq_setreleasehook(v, 1, sq_Decimal_release_hook);
-    return 1;
 }
 
 static SQRESULT sq_Decimal_error(HSQUIRRELVM v, uint32_t status) {
@@ -253,6 +199,83 @@ static SQRESULT sq_Decimal_error(HSQUIRRELVM v, uint32_t status) {
     return sq_throwerror(v, error);
 }
 
+static SQRESULT sq_Decimal_set_from(HSQUIRRELVM v, SQInteger idx, mpd_context_t *ctx, mpd_t *dec, uint32_t *status){
+    SQInteger _rc_;
+    switch(sq_gettype(v, idx)){
+
+        case OT_INSTANCE:{
+            GET_Decimal_INSTANCE2(v, idx);
+            mpd_qcopy(dec, dec2, status);
+        }
+
+        case OT_INTEGER:{
+            SQ_GET_INTEGER(v, idx, iparam);
+            mpd_qset_i32(dec, iparam, ctx, status);
+        }
+        break;
+        case OT_STRING:{
+            SQ_GET_STRING(v, idx, str);
+            mpd_qset_string(dec, str, ctx, status);
+        }
+        break;
+        case OT_FLOAT:{
+            SQ_GET_FLOAT(v, idx, fparam);
+            char buf[32];
+            snprintf(buf, sizeof(buf), "%f", fparam);
+            mpd_qset_string(dec, buf, ctx, status);
+        }
+        break;
+
+        default:
+            return sq_throwerror(v, _SC("invalid type (%s) to convert to decimal"), sq_gettypename(v, idx));
+    }
+    return SQ_OK;
+}
+
+static SQRESULT sq_Decimal_release_hook(SQUserPointer p, SQInteger size, HSQUIRRELVM v) {
+    mpd_t *dec = (mpd_t *)p;
+    if(dec) mpd_del(dec);
+    return 0;
+}
+
+/*
+** Creates a new Decimal.
+*/
+static SQRESULT sq_Decimal_constructor (HSQUIRRELVM v) {
+    uint32_t status = 0;
+    mpd_context_t *ctx = sq_get_global_ctx(v, 1);
+    mpd_t *dec = mpd_new(ctx);
+    if(sq_gettop(v) > 1){
+        if(sq_Decimal_set_from(v, 2, ctx, dec, &status) != SQ_OK) return SQ_ERROR;
+    }
+    else mpd_qset_i32(dec, 0, ctx, &status);
+
+	ctx->status |= status;
+	if (status&ctx->traps) {
+	    mpd_del(dec);
+	    return sq_Decimal_error(v, status);
+	}
+
+    sq_setinstanceup(v, 1, dec);
+    sq_setreleasehook(v, 1, sq_Decimal_release_hook);
+    return 1;
+}
+
+static SQRESULT sq_Decimal_set(HSQUIRRELVM v)
+{
+    SQ_FUNC_VARS_NO_TOP(v);
+    GET_Decimal_INSTANCE(v, 1);
+    uint32_t status = 0;
+    mpd_context_t *ctx = sq_get_global_ctx(v, 1);
+    if(sq_Decimal_set_from(v, 2, ctx, dec, &status) != SQ_OK) return SQ_ERROR;
+	ctx->status |= status;
+	if (status&ctx->traps) {
+	    return sq_Decimal_error(v, status);
+	}
+	sq_settop(v, 1); //returns itself
+	return 1;
+}
+
 static SQRESULT sq_Decimal_new_for_dec (HSQUIRRELVM v, mpd_t *dec, mpd_context_t *ctx, uint32_t status) {
     //mpd_addstatus_raise(ctx, status);
 	ctx->status |= status;
@@ -451,12 +474,12 @@ DECIMAL_IS(iszero);
 DECIMAL_IS(isinteger);
 DECIMAL_IS(isodd);
 DECIMAL_IS(iseven);
-
 
 #define _DECL_FUNC(name,nparams,tycheck) {_SC(#name),sq_Decimal_##name,nparams,tycheck}
 static SQRegFunction Decimal_methods[] =
 {
-    _DECL_FUNC(constructor,-1,_SC("x x|n|s")),
+    _DECL_FUNC(constructor,-1,_SC("x n|s|x")),
+    _DECL_FUNC(set, 2,_SC("x n|s|x")),
     {_SC("_tostring"),sq_Decimal_tostring, 1,_SC("x")},
     _DECL_FUNC(tostring,1,_SC("x")),
     _DECL_FUNC(_add, 2,_SC("xx")),

+ 11 - 1
SquiLu/samples/test-decimal.nut

@@ -11,7 +11,17 @@ print(d.isnan(), d.iszero(), d.isodd(), d.iseven());
 
 local dec1 = Decimal("1.1");
 local dec2 = Decimal("2.2");
-print(dec1 + dec2)
+print(dec1, dec2, dec1 + dec2)
+
+local dec44 = Decimal();
+print("dec44", dec44);
+dec44.set("44.4");
+print("dec44", dec44);
+dec44.set(48);
+print("dec44", dec44);
+dec44.set(49.8);
+print("dec44", dec44);
+print("dec44", dec1 + dec44.set(22));
 
 
 dec1 = Decimal("0.1");