aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Bennett <steveb@workware.net.au>2016-04-18 19:55:01 +1000
committerSteve Bennett <steveb@workware.net.au>2016-08-17 15:58:07 +1000
commita4f2aef246668e2d33f379093157d872d2db07f2 (patch)
tree2c11505b8270192ccab820a9ded82db648cdf3c7
parentba16ea3bdd9c8d22a99a9a354327f2b5593822c4 (diff)
downloadjimtcl-a4f2aef246668e2d33f379093157d872d2db07f2.zip
jimtcl-a4f2aef246668e2d33f379093157d872d2db07f2.tar.gz
jimtcl-a4f2aef246668e2d33f379093157d872d2db07f2.tar.bz2
expr: add support for atan2, hypot and fmod
And enable some more math tests Signed-off-by: Steve Bennett <steveb@workware.net.au>
-rw-r--r--jim.c121
-rw-r--r--tests/expr-old.test59
2 files changed, 96 insertions, 84 deletions
diff --git a/jim.c b/jim.c
index 4760caf..ca3bcec 100644
--- a/jim.c
+++ b/jim.c
@@ -7617,6 +7617,7 @@ enum
JIM_EXPROP_FUNC_ASIN,
JIM_EXPROP_FUNC_ACOS,
JIM_EXPROP_FUNC_ATAN,
+ JIM_EXPROP_FUNC_ATAN2,
JIM_EXPROP_FUNC_SINH,
JIM_EXPROP_FUNC_COSH,
JIM_EXPROP_FUNC_TANH,
@@ -7627,6 +7628,8 @@ enum
JIM_EXPROP_FUNC_LOG10,
JIM_EXPROP_FUNC_SQRT,
JIM_EXPROP_FUNC_POW,
+ JIM_EXPROP_FUNC_HYPOT,
+ JIM_EXPROP_FUNC_FMOD,
};
struct JimExprState
@@ -7938,7 +7941,6 @@ static int JimExprOpIntBin(Jim_Interp *interp, struct JimExprState *e)
/* A binary operation on two ints or two doubles (or two strings for some ops) */
static int JimExprOpBin(Jim_Interp *interp, struct JimExprState *e)
{
- int intresult = 1;
int rc = JIM_OK;
double dA, dB, dC = 0;
jim_wide wA, wB, wC = 0;
@@ -7956,20 +7958,21 @@ static int JimExprOpBin(Jim_Interp *interp, struct JimExprState *e)
case JIM_EXPROP_POW:
case JIM_EXPROP_FUNC_POW:
wC = JimPowWide(wA, wB);
- break;
+ goto intresult;
case JIM_EXPROP_ADD:
wC = wA + wB;
- break;
+ goto intresult;
case JIM_EXPROP_SUB:
wC = wA - wB;
- break;
+ goto intresult;
case JIM_EXPROP_MUL:
wC = wA * wB;
- break;
+ goto intresult;
case JIM_EXPROP_DIV:
if (wB == 0) {
Jim_SetResultString(interp, "Division by zero", -1);
rc = JIM_ERR;
+ goto done;
}
else {
/*
@@ -7988,51 +7991,63 @@ static int JimExprOpBin(Jim_Interp *interp, struct JimExprState *e)
if (wA % wB < 0) {
wC--;
}
+ goto intresult;
}
- break;
case JIM_EXPROP_LT:
wC = wA < wB;
- break;
+ goto intresult;
case JIM_EXPROP_GT:
wC = wA > wB;
- break;
+ goto intresult;
case JIM_EXPROP_LTE:
wC = wA <= wB;
- break;
+ goto intresult;
case JIM_EXPROP_GTE:
wC = wA >= wB;
- break;
+ goto intresult;
case JIM_EXPROP_NUMEQ:
wC = wA == wB;
- break;
+ goto intresult;
case JIM_EXPROP_NUMNE:
wC = wA != wB;
- break;
- default:
- abort();
+ goto intresult;
}
}
- else if (Jim_GetDouble(interp, A, &dA) == JIM_OK && Jim_GetDouble(interp, B, &dB) == JIM_OK) {
- intresult = 0;
+ if (Jim_GetDouble(interp, A, &dA) == JIM_OK && Jim_GetDouble(interp, B, &dB) == JIM_OK) {
switch (e->opcode) {
+#ifndef JIM_MATH_FUNCTIONS
case JIM_EXPROP_POW:
case JIM_EXPROP_FUNC_POW:
-#ifdef JIM_MATH_FUNCTIONS
- dC = pow(dA, dB);
-#else
+ case JIM_EXPROP_FUNC_ATAN2:
+ case JIM_EXPROP_FUNC_HYPOT:
+ case JIM_EXPROP_FUNC_FMOD:
Jim_SetResultString(interp, "unsupported", -1);
rc = JIM_ERR;
+ goto done;
+#else
+ case JIM_EXPROP_POW:
+ case JIM_EXPROP_FUNC_POW:
+ dC = pow(dA, dB);
+ goto doubleresult;
+ case JIM_EXPROP_FUNC_ATAN2:
+ dC = atan2(dA, dB);
+ goto doubleresult;
+ case JIM_EXPROP_FUNC_HYPOT:
+ dC = hypot(dA, dB);
+ goto doubleresult;
+ case JIM_EXPROP_FUNC_FMOD:
+ dC = fmod(dA, dB);
+ goto doubleresult;
#endif
- break;
case JIM_EXPROP_ADD:
dC = dA + dB;
- break;
+ goto doubleresult;
case JIM_EXPROP_SUB:
dC = dA - dB;
- break;
+ goto doubleresult;
case JIM_EXPROP_MUL:
dC = dA * dB;
- break;
+ goto doubleresult;
case JIM_EXPROP_DIV:
if (dB == 0) {
#ifdef INFINITY
@@ -8044,33 +8059,25 @@ static int JimExprOpBin(Jim_Interp *interp, struct JimExprState *e)
else {
dC = dA / dB;
}
- break;
+ goto doubleresult;
case JIM_EXPROP_LT:
wC = dA < dB;
- intresult = 1;
- break;
+ goto intresult;
case JIM_EXPROP_GT:
wC = dA > dB;
- intresult = 1;
- break;
+ goto intresult;
case JIM_EXPROP_LTE:
wC = dA <= dB;
- intresult = 1;
- break;
+ goto intresult;
case JIM_EXPROP_GTE:
wC = dA >= dB;
- intresult = 1;
- break;
+ goto intresult;
case JIM_EXPROP_NUMEQ:
wC = dA == dB;
- intresult = 1;
- break;
+ goto intresult;
case JIM_EXPROP_NUMNE:
wC = dA != dB;
- intresult = 1;
- break;
- default:
- abort();
+ goto intresult;
}
}
else {
@@ -8082,41 +8089,36 @@ static int JimExprOpBin(Jim_Interp *interp, struct JimExprState *e)
switch (e->opcode) {
case JIM_EXPROP_LT:
wC = i < 0;
- break;
+ goto intresult;
case JIM_EXPROP_GT:
wC = i > 0;
- break;
+ goto intresult;
case JIM_EXPROP_LTE:
wC = i <= 0;
- break;
+ goto intresult;
case JIM_EXPROP_GTE:
wC = i >= 0;
- break;
+ goto intresult;
case JIM_EXPROP_NUMEQ:
wC = i == 0;
- break;
+ goto intresult;
case JIM_EXPROP_NUMNE:
wC = i != 0;
- break;
- default:
- rc = JIM_ERR;
- break;
- }
- }
-
- if (rc == JIM_OK) {
- if (intresult) {
- ExprPush(e, Jim_NewIntObj(interp, wC));
- }
- else {
- ExprPush(e, Jim_NewDoubleObj(interp, dC));
+ goto intresult;
}
}
-
+ /* If we get here, it is an error */
+ rc = JIM_ERR;
+done:
Jim_DecrRefCount(interp, A);
Jim_DecrRefCount(interp, B);
-
return rc;
+intresult:
+ ExprPush(e, Jim_NewIntObj(interp, wC));
+ goto done;
+doubleresult:
+ ExprPush(e, Jim_NewDoubleObj(interp, dC));
+ goto done;
}
static int JimSearchList(Jim_Interp *interp, Jim_Obj *listObjPtr, Jim_Obj *valObj)
@@ -8408,6 +8410,7 @@ static const struct Jim_ExprOperator Jim_ExprOperators[] = {
OPRINIT("asin", 200, 1, JimExprOpDoubleUnary),
OPRINIT("acos", 200, 1, JimExprOpDoubleUnary),
OPRINIT("atan", 200, 1, JimExprOpDoubleUnary),
+ OPRINIT("atan2", 200, 2, JimExprOpBin),
OPRINIT("sinh", 200, 1, JimExprOpDoubleUnary),
OPRINIT("cosh", 200, 1, JimExprOpDoubleUnary),
OPRINIT("tanh", 200, 1, JimExprOpDoubleUnary),
@@ -8418,6 +8421,8 @@ static const struct Jim_ExprOperator Jim_ExprOperators[] = {
OPRINIT("log10", 200, 1, JimExprOpDoubleUnary),
OPRINIT("sqrt", 200, 1, JimExprOpDoubleUnary),
OPRINIT("pow", 200, 2, JimExprOpBin),
+ OPRINIT("hypot", 200, 2, JimExprOpBin),
+ OPRINIT("fmod", 200, 2, JimExprOpBin),
#endif
};
#undef OPRINIT
diff --git a/tests/expr-old.test b/tests/expr-old.test
index b1d722d..1021041 100644
--- a/tests/expr-old.test
+++ b/tests/expr-old.test
@@ -17,6 +17,15 @@
source [file dirname [info script]]/testing.tcl
+# Jim Tcl may have no math functions, and may not have specific math functions
+foreach {expr constraint} {sin(0) mathfunc fmod(0,1) expr_fmod hypot(0,1) expr_hypot} {
+ if {[catch {expr $expr} msg]} {
+ testConstraint $constraint 0
+ } else {
+ testConstraint $constraint 1
+ }
+}
+
# First, test all of the integer operators individually.
test expr-old-1.1 {integer operators} {expr -4} -4
@@ -556,72 +565,70 @@ test expr-old-31.4 {multiple arguments to expr command} {
# Math functions
-if {0} {
-test expr-old-32.1 {math functions in expressions} {
+test expr-old-32.1 {math functions in expressions} mathfunc {
format %.6g [expr acos(0.5)]
} {1.0472}
-test expr-old-32.2 {math functions in expressions} {
+test expr-old-32.2 {math functions in expressions} mathfunc {
format %.6g [expr asin(0.5)]
} {0.523599}
-test expr-old-32.3 {math functions in expressions} {
+test expr-old-32.3 {math functions in expressions} mathfunc {
format %.6g [expr atan(1.0)]
} {0.785398}
-test expr-old-32.4 {math functions in expressions} {
+test expr-old-32.4 {math functions in expressions} mathfunc {
format %.6g [expr atan2(2.0, 2.0)]
} {0.785398}
-test expr-old-32.5 {math functions in expressions} {
+test expr-old-32.5 {math functions in expressions} mathfunc {
format %.6g [expr ceil(1.999)]
} {2}
-test expr-old-32.6 {math functions in expressions} {
+test expr-old-32.6 {math functions in expressions} mathfunc {
format %.6g [expr cos(.1)]
} {0.995004}
-test expr-old-32.7 {math functions in expressions} {
+test expr-old-32.7 {math functions in expressions} mathfunc {
format %.6g [expr cosh(.1)]
} {1.005}
-test expr-old-32.8 {math functions in expressions} {
+test expr-old-32.8 {math functions in expressions} mathfunc {
format %.6g [expr exp(1.0)]
} {2.71828}
-test expr-old-32.9 {math functions in expressions} {
+test expr-old-32.9 {math functions in expressions} mathfunc {
format %.6g [expr floor(2.000)]
} {2}
-test expr-old-32.10 {math functions in expressions} {
+test expr-old-32.10 {math functions in expressions} mathfunc {
format %.6g [expr floor(2.001)]
} {2}
-test expr-old-32.11 {math functions in expressions} {
+test expr-old-32.11 {math functions in expressions} expr_fmod {
format %.6g [expr fmod(7.3, 3.2)]
} {0.9}
-test expr-old-32.12 {math functions in expressions} {
+test expr-old-32.12 {math functions in expressions} expr_hypot {
format %.6g [expr hypot(3.0, 4.0)]
} {5}
-test expr-old-32.13 {math functions in expressions} {
+test expr-old-32.13 {math functions in expressions} mathfunc {
format %.6g [expr log(2.8)]
} {1.02962}
-test expr-old-32.14 {math functions in expressions} {
+test expr-old-32.14 {math functions in expressions} mathfunc {
format %.6g [expr log10(2.8)]
} {0.447158}
-test expr-old-32.15 {math functions in expressions} {
+test expr-old-32.15 {math functions in expressions} mathfunc {
format %.6g [expr pow(2.1, 3.1)]
} {9.97424}
-test expr-old-32.16 {math functions in expressions} {
+test expr-old-32.16 {math functions in expressions} mathfunc {
format %.6g [expr sin(.1)]
} {0.0998334}
-test expr-old-32.17 {math functions in expressions} {
+test expr-old-32.17 {math functions in expressions} mathfunc {
format %.6g [expr sinh(.1)]
} {0.100167}
-test expr-old-32.18 {math functions in expressions} {
+test expr-old-32.18 {math functions in expressions} mathfunc {
format %.6g [expr sqrt(2.0)]
} {1.41421}
-test expr-old-32.19 {math functions in expressions} {
+test expr-old-32.19 {math functions in expressions} mathfunc {
format %.6g [expr tan(0.8)]
} {1.02964}
-test expr-old-32.20 {math functions in expressions} {
+test expr-old-32.20 {math functions in expressions} mathfunc {
format %.6g [expr tanh(0.8)]
} {0.664037}
-}
-test expr-old-32.21 {math functions in expressions} {
+test expr-old-32.21 {math functions in expressions} mathfunc {
format %.6g [expr abs(-1.8)]
} {1.8}
-test expr-old-32.22 {math functions in expressions} {
+test expr-old-32.22 {math functions in expressions} mathfunc {
expr abs(10.0)
} {10.0}
test expr-old-32.23 {math functions in expressions} {
@@ -808,10 +815,10 @@ test expr-old-36.8 {ExprLooksLikeInt procedure} {
test expr-old-36.9 {ExprLooksLikeInt procedure} {
list [catch {expr 24E1} msg] $msg
} {0 240.0}
+}
test expr-old-36.10 {ExprLooksLikeInt procedure} {
list [catch {expr 78e} msg] $msg
-} {1 {syntax error in expression "78e"}}
-}
+} {1 {syntax error in expression: "78e"}}
# test for [Bug #542588]
# XXX: Can't rely on overflow checking