[gimp] R5RS compliance fix. Return proper type for remainder and modulo.



commit 73e5ef394febbe6f492e947520f1093d4144eb4c
Author: Kevin Cozens <kevin ve3syb ca>
Date:   Thu Aug 6 11:35:39 2020 -0400

    R5RS compliance fix. Return proper type for remainder and modulo.
    
    Also fixed quotient to only take two arguments. Applied minor
    optimization in execution of quotient, remainder, and modulo.
    From revision 122 of the TinyScheme repository in SourceForge.

 plug-ins/script-fu/tinyscheme/opdefines.h |  2 +-
 plug-ins/script-fu/tinyscheme/scheme.c    | 47 ++++++++++++++++---------------
 2 files changed, 26 insertions(+), 23 deletions(-)
---
diff --git a/plug-ins/script-fu/tinyscheme/opdefines.h b/plug-ins/script-fu/tinyscheme/opdefines.h
index ceb4d0e393..4f59fec155 100644
--- a/plug-ins/script-fu/tinyscheme/opdefines.h
+++ b/plug-ins/script-fu/tinyscheme/opdefines.h
@@ -75,7 +75,7 @@
     _OP_DEF(opexe_2, "-",                              1,  INF_ARG, TST_NUMBER,                      OP_SUB  
            )
     _OP_DEF(opexe_2, "*",                              0,  INF_ARG, TST_NUMBER,                      OP_MUL  
            )
     _OP_DEF(opexe_2, "/",                              1,  INF_ARG, TST_NUMBER,                      OP_DIV  
            )
-    _OP_DEF(opexe_2, "quotient",                       1,  INF_ARG, TST_INTEGER,                     
OP_INTDIV           )
+    _OP_DEF(opexe_2, "quotient",                       2,  2,       TST_INTEGER,                     
OP_INTDIV           )
     _OP_DEF(opexe_2, "remainder",                      2,  2,       TST_INTEGER,                     OP_REM  
            )
     _OP_DEF(opexe_2, "modulo",                         2,  2,       TST_INTEGER,                     OP_MOD  
            )
     _OP_DEF(opexe_2, "car",                            1,  1,       TST_PAIR,                        OP_CAR  
            )
diff --git a/plug-ins/script-fu/tinyscheme/scheme.c b/plug-ins/script-fu/tinyscheme/scheme.c
index a5b1b02c22..eee98da566 100644
--- a/plug-ins/script-fu/tinyscheme/scheme.c
+++ b/plug-ins/script-fu/tinyscheme/scheme.c
@@ -500,10 +500,14 @@ static num num_rem(num a, num b) {
      }
  } else if (res < 0) {
      if (e1 > 0) {
-        res += labs(e2);
+         res += labs(e2);
      }
  }
- ret.value.ivalue=res;
+ if (ret.is_fixnum) {
+     ret.value.ivalue = res;
+ } else {
+     ret.value.rvalue = res;
+ }
  return ret;
 }
 
@@ -515,10 +519,14 @@ static num num_mod(num a, num b) {
  e2=num_ivalue(b);
  res=e1%e2;
  /* modulo should have same sign as second operand */
- if ((res < 0) != (e2 < 0) && res) { /* if their sign is different... */
-   res+=e2;
+ if (res * e2 < 0) {
+    res += e2;
+ }
+ if (ret.is_fixnum) {
+     ret.value.ivalue = res;
+ } else {
+     ret.value.rvalue = res;
  }
- ret.value.ivalue=res;
  return ret;
 }
 
@@ -3464,26 +3472,20 @@ static pointer opexe_2(scheme *sc, enum scheme_opcodes op) {
        s_return(sc,mk_number(sc, v));
 
      case OP_INTDIV:        /* quotient */
-          if(cdr(sc->args)==sc->NIL) {
-               x=sc->args;
-               v=num_one;
-          } else {
-               x = cdr(sc->args);
-               v = nvalue(car(sc->args));
-          }
-          for (; x != sc->NIL; x = cdr(x)) {
-               if (ivalue(car(x)) != 0)
-                    v=num_intdiv(v,nvalue(car(x)));
-               else {
-                    Error_0(sc,"quotient: division by zero");
-               }
+          v = nvalue(car(sc->args));
+          x = cadr(sc->args);
+          if (ivalue(x) != 0)
+               v=num_intdiv(v,nvalue(x));
+          else {
+               Error_0(sc,"quotient: division by zero");
           }
           s_return(sc,mk_number(sc, v));
 
      case OP_REM:        /* remainder */
           v = nvalue(car(sc->args));
-          if (ivalue(cadr(sc->args)) != 0)
-               v=num_rem(v,nvalue(cadr(sc->args)));
+          x = cadr(sc->args);
+          if (ivalue(x) != 0)
+               v=num_rem(v,nvalue(x));
           else {
                Error_0(sc,"remainder: division by zero");
           }
@@ -3491,8 +3493,9 @@ static pointer opexe_2(scheme *sc, enum scheme_opcodes op) {
 
      case OP_MOD:        /* modulo */
           v = nvalue(car(sc->args));
-          if (ivalue(cadr(sc->args)) != 0)
-               v=num_mod(v,nvalue(cadr(sc->args)));
+          x = cadr(sc->args);
+          if (ivalue(x) != 0)
+               v=num_mod(v,nvalue(x));
           else {
                Error_0(sc,"modulo: division by zero");
           }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]