operations.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef HAVE_CONFIG_H
00024 #include "config.h"
00025 #endif
00026 #ifndef HAVE_FLOAT_H
00027 #define HAVE_FLOAT_H 0
00028 #define HAVE_FUNC__FINITE 0
00029 #endif
00030
00031 #include <stdio.h>
00032 #include <assert.h>
00033 #include <math.h>
00034 #include <stdlib.h>
00035
00036
00037 #ifdef __SUNPRO_CC
00038 #include <sunmath.h>
00039 #endif
00040
00041 #ifndef HAVE_FUNC_ISINF
00042 #ifdef HAVE_IEEEFP_H
00043 #include <ieeefp.h>
00044 #endif
00045 #endif
00046
00047 #if HAVE_FLOAT_H
00048 #include <float.h>
00049 #endif
00050
00051 #include "operations.h"
00052 #include "object.h"
00053
00054 using namespace KJS;
00055
00056 bool KJS::isNaN(double d)
00057 {
00058 #ifdef HAVE_FUNC_ISNAN
00059 return isnan(d);
00060 #elif defined HAVE_FLOAT_H
00061 return _isnan(d) != 0;
00062 #else
00063 return !(d == d);
00064 #endif
00065 }
00066
00067 bool KJS::isInf(double d)
00068 {
00069 #if defined(HAVE_FUNC_ISINF)
00070 return isinf(d);
00071 #elif HAVE_FUNC_FINITE
00072 return finite(d) == 0 && d == d;
00073 #elif HAVE_FUNC__FINITE
00074 return _finite(d) == 0 && d == d;
00075 #else
00076 return false;
00077 #endif
00078 }
00079
00080 bool KJS::isPosInf(double d)
00081 {
00082 #if defined(HAVE_FUNC_ISINF)
00083 return (isinf(d) == 1);
00084 #elif HAVE_FUNC_FINITE
00085 return finite(d) == 0 && d == d;
00086 #elif HAVE_FUNC__FINITE
00087 return _finite(d) == 0 && d == d;
00088 #else
00089 return false;
00090 #endif
00091 }
00092
00093 bool KJS::isNegInf(double d)
00094 {
00095 #if defined(HAVE_FUNC_ISINF)
00096 return (isinf(d) == -1);
00097 #elif HAVE_FUNC_FINITE
00098 return finite(d) == 0 && d == d;
00099 #elif HAVE_FUNC__FINITE
00100 return _finite(d) == 0 && d == d;
00101 #else
00102 return false;
00103 #endif
00104 }
00105
00106
00107 bool KJS::equal(ExecState *exec, const Value& v1, const Value& v2)
00108 {
00109 Type t1 = v1.type();
00110 Type t2 = v2.type();
00111
00112 if (t1 == t2) {
00113 if (t1 == UndefinedType || t1 == NullType)
00114 return true;
00115 if (t1 == NumberType)
00116 {
00117 double d1 = v1.toNumber(exec);
00118 double d2 = v2.toNumber(exec);
00119 if ( isNaN( d1 ) || isNaN( d2 ) )
00120 return false;
00121 return ( d1 == d2 );
00122 }
00123 if (t1 == StringType)
00124 return (v1.toString(exec) == v2.toString(exec));
00125 if (t1 == BooleanType)
00126 return (v1.toBoolean(exec) == v2.toBoolean(exec));
00127
00128
00129 return (v1.imp() == v2.imp());
00130 }
00131
00132
00133 if ((t1 == NullType && t2 == UndefinedType) || (t1 == UndefinedType && t2 == NullType))
00134 return true;
00135 if (t1 == NumberType && t2 == StringType) {
00136 Number n2 = v2.toNumber(exec);
00137 return equal(exec,v1, n2);
00138 }
00139 if ((t1 == StringType && t2 == NumberType) || t1 == BooleanType) {
00140 Number n1 = v1.toNumber(exec);
00141 return equal(exec,n1, v2);
00142 }
00143 if (t2 == BooleanType) {
00144 Number n2 = v2.toNumber(exec);
00145 return equal(exec,v1, n2);
00146 }
00147 if ((t1 == StringType || t1 == NumberType) && t2 >= ObjectType) {
00148 Value p2 = v2.toPrimitive(exec);
00149 return equal(exec,v1, p2);
00150 }
00151 if (t1 >= ObjectType && (t2 == StringType || t2 == NumberType)) {
00152 Value p1 = v1.toPrimitive(exec);
00153 return equal(exec,p1, v2);
00154 }
00155
00156 return false;
00157 }
00158
00159 bool KJS::strictEqual(ExecState *exec, const Value &v1, const Value &v2)
00160 {
00161 Type t1 = v1.type();
00162 Type t2 = v2.type();
00163
00164 if (t1 != t2)
00165 return false;
00166 if (t1 == UndefinedType || t1 == NullType)
00167 return true;
00168 if (t1 == NumberType) {
00169 double n1 = v1.toNumber(exec);
00170 double n2 = v2.toNumber(exec);
00171 if (isNaN(n1) || isNaN(n2))
00172 return false;
00173 if (n1 == n2)
00174 return true;
00175
00176 return false;
00177 } else if (t1 == StringType) {
00178 return v1.toString(exec) == v2.toString(exec);
00179 } else if (t2 == BooleanType) {
00180 return v1.toBoolean(exec) == v2.toBoolean(exec);
00181 }
00182 if (v1.imp() == v2.imp())
00183 return true;
00184
00185
00186 return false;
00187 }
00188
00189 int KJS::relation(ExecState *exec, const Value& v1, const Value& v2)
00190 {
00191 Value p1 = v1.toPrimitive(exec,NumberType);
00192 Value p2 = v2.toPrimitive(exec,NumberType);
00193
00194 if (p1.type() == StringType && p2.type() == StringType)
00195 return p1.toString(exec) < p2.toString(exec) ? 1 : 0;
00196
00197 double n1 = p1.toNumber(exec);
00198 double n2 = p2.toNumber(exec);
00199 if ( isNaN( n1 ) || isNaN( n2 ) )
00200 return -1;
00201 if (n1 == n2)
00202 return 0;
00203
00204 if ( isPosInf( n1 ) )
00205 return 0;
00206 if ( isPosInf( n2 ) )
00207 return 1;
00208 if ( isNegInf( n2 ) )
00209 return 0;
00210 if ( isNegInf( n1 ) )
00211 return 1;
00212 return (n1 < n2) ? 1 : 0;
00213 }
00214
00215 int KJS::maxInt(int d1, int d2)
00216 {
00217 return (d1 > d2) ? d1 : d2;
00218 }
00219
00220 int KJS::minInt(int d1, int d2)
00221 {
00222 return (d1 < d2) ? d1 : d2;
00223 }
00224
00225
00226 Value KJS::add(ExecState *exec, const Value &v1, const Value &v2, char oper)
00227 {
00228
00229 Type preferred = oper == '+' ? UnspecifiedType : NumberType;
00230 Value p1 = v1.toPrimitive(exec, preferred);
00231 Value p2 = v2.toPrimitive(exec, preferred);
00232
00233 if ((p1.type() == StringType || p2.type() == StringType) && oper == '+') {
00234 UString s1 = p1.toString(exec);
00235 UString s2 = p2.toString(exec);
00236
00237 return String(s1 + s2);
00238 }
00239
00240 double n1 = p1.toNumber(exec);
00241 double n2 = p2.toNumber(exec);
00242
00243 if (oper == '+')
00244 return Number(n1 + n2);
00245 else
00246 return Number(n1 - n2);
00247 }
00248
00249
00250 Value KJS::mult(ExecState *exec, const Value &v1, const Value &v2, char oper)
00251 {
00252 double n1 = v1.toNumber(exec);
00253 double n2 = v2.toNumber(exec);
00254
00255 double result;
00256
00257 if (oper == '*')
00258 result = n1 * n2;
00259 else if (oper == '/')
00260 result = n1 / n2;
00261 else
00262 result = fmod(n1, n2);
00263
00264 return Number(result);
00265 }
This file is part of the documentation for kdelibs Version 3.1.5.