fix logic
[personal-kdelibs.git] / kjs / operations.cpp
blobd4c00662acdac3938bab61020d29ac92e115ac8c
1 // -*- c-basic-offset: 2 -*-
2 /*
3 * This file is part of the KDE libraries
4 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
23 #include "operations.h"
24 #include <config.h>
26 #include "object.h"
27 #include "internal.h"
28 #include <math.h>
29 #include <stdio.h>
30 #include <wtf/MathExtras.h>
32 #if HAVE(IEEEFP_H)
33 #if HAVE(FUNC_ISINF) || HAVE(FUNC_FINITE)
34 #include <ieeefp.h>
35 #endif
36 #endif
38 #if HAVE(FLOAT_H)
39 #include <float.h>
40 #endif
42 namespace KJS {
44 #if !PLATFORM(DARWIN)
46 // FIXME: Should probably be inlined on non-Darwin platforms too, and controlled exclusively
47 // by HAVE macros rather than PLATFORM.
49 // FIXME: Merge with isnan in MathExtras.h and remove this one entirely.
50 bool isNaN(double d)
52 #if HAVE(FUNC_ISNAN)
53 return isnan(d) != 0;
54 #elif HAVE(FLOAT_H)
55 return _isnan(d) != 0;
56 #else
57 return !(d == d);
58 #endif
61 // FIXME: Merge with isinf in MathExtras.h and remove this one entirely.
62 bool isInf(double d)
64 // FIXME: should be HAVE(_FPCLASS)
65 #if PLATFORM(WIN_OS)
66 int fpClass = _fpclass(d);
67 return _FPCLASS_PINF == fpClass || _FPCLASS_NINF == fpClass;
68 #elif HAVE(FUNC_ISINF) && !PLATFORM(SOLARIS_OS)
69 return isinf(d);
70 #elif HAVE(FUNC_FINITE)
71 return finite(d) == 0 && d == d;
72 #elif HAVE(FUNC__FINITE)
73 return _finite(d) == 0 && d == d;
74 #else
75 return false;
76 #endif
79 bool isPosInf(double d)
81 // FIXME: should be HAVE(_FPCLASS)
82 #if PLATFORM(WIN_OS)
83 return _FPCLASS_PINF == _fpclass(d);
84 #elif HAVE(FUNC_ISINF) && !PLATFORM(SOLARIS_OS)
85 return (isinf(d) == 1);
86 #elif HAVE(FUNC_FINITE)
87 return !finite(d) && d == d; // ### can we distinguish between + and - ?
88 #elif HAVE(FUNC__FINITE)
89 return !_finite(d) && d == d; // ###
90 #else
91 return false;
92 #endif
95 bool isNegInf(double d)
97 // FIXME: should be HAVE(_FPCLASS)
98 #if PLATFORM(WIN_OS)
99 return _FPCLASS_NINF == _fpclass(d);
100 #elif HAVE(FUNC_ISINF) && !PLATFORM(SOLARIS_OS)
101 return (isinf(d) == -1);
102 #elif HAVE(FUNC_FINITE)
103 return finite(d) == 0 && d == d; // ###
104 #elif HAVE(FUNC__FINITE)
105 return _finite(d) == 0 && d == d; // ###
106 #else
107 return false;
108 #endif
111 #endif
113 // ECMA 11.9.3
114 bool equal(ExecState *exec, JSValue *v1, JSValue *v2)
116 JSType t1 = v1->type();
117 JSType t2 = v2->type();
119 if (t1 != t2) {
120 if (t1 == UndefinedType)
121 t1 = NullType;
122 if (t2 == UndefinedType)
123 t2 = NullType;
125 if (t1 == BooleanType)
126 t1 = NumberType;
127 if (t2 == BooleanType)
128 t2 = NumberType;
130 if (t1 == NumberType && t2 == StringType) {
131 // use toNumber
132 } else if (t1 == StringType && t2 == NumberType)
133 t1 = NumberType;
134 // use toNumber
135 else {
136 if ((t1 == StringType || t1 == NumberType) && t2 >= ObjectType)
137 return equal(exec, v1, v2->toPrimitive(exec));
138 if (t1 == NullType && t2 == ObjectType)
139 return static_cast<JSObject *>(v2)->masqueradeAsUndefined();
140 if (t1 >= ObjectType && (t2 == StringType || t2 == NumberType))
141 return equal(exec, v1->toPrimitive(exec), v2);
142 if (t1 == ObjectType && t2 == NullType)
143 return static_cast<JSObject *>(v1)->masqueradeAsUndefined();
144 if (t1 != t2)
145 return false;
149 if (t1 == UndefinedType || t1 == NullType)
150 return true;
152 if (t1 == NumberType) {
153 double d1 = v1->toNumber(exec);
154 double d2 = v2->toNumber(exec);
155 return d1 == d2;
158 if (t1 == StringType)
159 return v1->toString(exec) == v2->toString(exec);
161 if (t1 == BooleanType)
162 return v1->toBoolean(exec) == v2->toBoolean(exec);
164 // types are Object
165 return v1 == v2;
168 bool strictEqual(ExecState *exec, JSValue *v1, JSValue *v2)
170 JSType t1 = v1->type();
171 JSType t2 = v2->type();
173 if (t1 != t2)
174 return false;
175 if (t1 == UndefinedType || t1 == NullType)
176 return true;
177 if (t1 == NumberType) {
178 double n1 = v1->toNumber(exec);
179 double n2 = v2->toNumber(exec);
180 if (n1 == n2)
181 return true;
182 return false;
183 } else if (t1 == StringType)
184 return v1->toString(exec) == v2->toString(exec);
185 else if (t2 == BooleanType)
186 return v1->toBoolean(exec) == v2->toBoolean(exec);
188 if (v1 == v2)
189 return true;
190 /* TODO: joined objects */
192 return false;
195 int relation(ExecState *exec, JSValue *v1, JSValue *v2)
197 double n1;
198 double n2;
199 JSValue* p1;
200 JSValue* p2;
201 bool wasNotString1 = v1->getPrimitiveNumber(exec, n1, p1);
202 if (exec->hadException())
203 return -1;
205 bool wasNotString2 = v2->getPrimitiveNumber(exec, n2, p2);
207 if (wasNotString1 || wasNotString2) {
208 if (n1 < n2)
209 return 1;
210 if (n1 >= n2)
211 return 0;
212 return -1; // must be NaN, so undefined
215 assert(p1->isString() && p2->isString());
216 return static_cast<const StringImp*>(p1)->value() < static_cast<const StringImp*>(p2)->value() ? 1 : 0;
219 int relation(ExecState *exec, JSValue *v1, double n2)
221 double n1;
222 JSValue* p1;
224 v1->getPrimitiveNumber(exec, n1, p1);
225 if (exec->hadException())
226 return -1;
228 if (n1 < n2)
229 return 1;
230 if (n1 >= n2)
231 return 0;
232 return -1; // must be NaN, so undefined
235 int maxInt(int d1, int d2)
237 return (d1 > d2) ? d1 : d2;
240 int minInt(int d1, int d2)
242 return (d1 < d2) ? d1 : d2;