kjs Library API Documentation

math_object.cpp

00001 // -*- c-basic-offset: 2 -*-
00002 /*
00003  *  This file is part of the KDE libraries
00004  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
00005  *
00006  *  This library is free software; you can redistribute it and/or
00007  *  modify it under the terms of the GNU Lesser General Public
00008  *  License as published by the Free Software Foundation; either
00009  *  version 2 of the License, or (at your option) any later version.
00010  *
00011  *  This library is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  *  Lesser General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU Lesser General Public
00017  *  License along with this library; if not, write to the Free Software
00018  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  *  $Id: math_object.cpp,v 1.29 2002/06/19 08:21:00 domi Exp $
00021  */
00022 
00023 #include <math.h>
00024 #include <stdlib.h>
00025 #include <stdio.h>
00026 #include <assert.h>
00027 
00028 #include "value.h"
00029 #include "object.h"
00030 #include "types.h"
00031 #include "interpreter.h"
00032 #include "operations.h"
00033 #include "math_object.h"
00034 
00035 #include "math_object.lut.h"
00036 
00037 #ifndef M_PI
00038 #define M_PI 3.14159265358979323846
00039 #endif  /*  M_PI  */
00040 
00041 using namespace KJS;
00042 
00043 // ------------------------------ MathObjectImp --------------------------------
00044 
00045 const ClassInfo MathObjectImp::info = { "Math", 0, &mathTable, 0 };
00046 
00047 /* Source for math_object.lut.h
00048 @begin mathTable 21
00049   E             MathObjectImp::Euler    DontEnum|DontDelete|ReadOnly
00050   LN2           MathObjectImp::Ln2      DontEnum|DontDelete|ReadOnly
00051   LN10          MathObjectImp::Ln10     DontEnum|DontDelete|ReadOnly
00052   LOG2E         MathObjectImp::Log2E    DontEnum|DontDelete|ReadOnly
00053   LOG10E        MathObjectImp::Log10E   DontEnum|DontDelete|ReadOnly
00054   PI            MathObjectImp::Pi       DontEnum|DontDelete|ReadOnly
00055   SQRT1_2       MathObjectImp::Sqrt1_2  DontEnum|DontDelete|ReadOnly
00056   SQRT2         MathObjectImp::Sqrt2    DontEnum|DontDelete|ReadOnly
00057   abs           MathObjectImp::Abs      DontEnum|Function 1
00058   acos          MathObjectImp::ACos     DontEnum|Function 1
00059   asin          MathObjectImp::ASin     DontEnum|Function 1
00060   atan          MathObjectImp::ATan     DontEnum|Function 1
00061   atan2         MathObjectImp::ATan2    DontEnum|Function 2
00062   ceil          MathObjectImp::Ceil     DontEnum|Function 1
00063   cos           MathObjectImp::Cos      DontEnum|Function 1
00064   exp           MathObjectImp::Exp      DontEnum|Function 1
00065   floor         MathObjectImp::Floor    DontEnum|Function 1
00066   log           MathObjectImp::Log      DontEnum|Function 1
00067   max           MathObjectImp::Max      DontEnum|Function 2
00068   min           MathObjectImp::Min      DontEnum|Function 2
00069   pow           MathObjectImp::Pow      DontEnum|Function 2
00070   random        MathObjectImp::Random   DontEnum|Function 0
00071   round         MathObjectImp::Round    DontEnum|Function 1
00072   sin           MathObjectImp::Sin      DontEnum|Function 1
00073   sqrt          MathObjectImp::Sqrt     DontEnum|Function 1
00074   tan           MathObjectImp::Tan      DontEnum|Function 1
00075 @end
00076 */
00077 
00078 MathObjectImp::MathObjectImp(ExecState * /*exec*/,
00079                              ObjectPrototypeImp *objProto)
00080   : ObjectImp(Object(objProto))
00081 {
00082 }
00083 
00084 // ECMA 15.8
00085 Value MathObjectImp::get(ExecState *exec, const UString &propertyName) const
00086 {
00087   return lookupGet<MathFuncImp, MathObjectImp, ObjectImp>( exec, propertyName, &mathTable, this );
00088 }
00089 
00090 Value MathObjectImp::getValueProperty(ExecState *, int token) const
00091 {
00092   double d = -42; // ;)
00093   switch (token) {
00094   case Euler:
00095     d = exp(1.0);
00096     break;
00097   case Ln2:
00098     d = log(2.0);
00099     break;
00100   case Ln10:
00101     d = log(10.0);
00102     break;
00103   case Log2E:
00104     d = 1.0/log(2.0);
00105     break;
00106   case Log10E:
00107     d = 1.0/log(10.0);
00108     break;
00109   case Pi:
00110     d = M_PI;
00111     break;
00112   case Sqrt1_2:
00113     d = sqrt(0.5);
00114     break;
00115   case Sqrt2:
00116     d = sqrt(2.0);
00117     break;
00118   default:
00119     fprintf( stderr, "Internal error in MathObjectImp: unhandled token %d\n", token );
00120     break;
00121   }
00122 
00123   return Number(d);
00124 }
00125 
00126 // ------------------------------ MathObjectImp --------------------------------
00127 
00128 MathFuncImp::MathFuncImp(ExecState *exec, int i, int l)
00129   : InternalFunctionImp(
00130     static_cast<FunctionPrototypeImp*>(exec->interpreter()->builtinFunctionPrototype().imp())
00131     ), id(i)
00132 {
00133   Value protect(this);
00134   put(exec,"length",Number(l),DontDelete|ReadOnly|DontEnum);
00135 }
00136 
00137 bool MathFuncImp::implementsCall() const
00138 {
00139   return true;
00140 }
00141 
00142 Value MathFuncImp::call(ExecState *exec, Object &/*thisObj*/, const List &args)
00143 {
00144   double arg = args[0].toNumber(exec);
00145   double arg2 = args[1].toNumber(exec);
00146   double result;
00147 
00148   switch (id) {
00149   case MathObjectImp::Abs:
00150     result = ( arg < 0 || arg == -0) ? (-arg) : arg;
00151     break;
00152   case MathObjectImp::ACos:
00153     result = ::acos(arg);
00154     break;
00155   case MathObjectImp::ASin:
00156     result = ::asin(arg);
00157     break;
00158   case MathObjectImp::ATan:
00159     result = ::atan(arg);
00160     break;
00161   case MathObjectImp::ATan2:
00162     result = ::atan2(arg, arg2);
00163     break;
00164   case MathObjectImp::Ceil:
00165     result = ::ceil(arg);
00166     break;
00167   case MathObjectImp::Cos:
00168     result = ::cos(arg);
00169     break;
00170   case MathObjectImp::Exp:
00171     result = ::exp(arg);
00172     break;
00173   case MathObjectImp::Floor:
00174     result = ::floor(arg);
00175     break;
00176   case MathObjectImp::Log:
00177     result = ::log(arg);
00178     break;
00179   case MathObjectImp::Max: {
00180     unsigned int argsCount = args.size();
00181     result = -Inf;
00182     for ( unsigned int k = 0 ; k < argsCount ; ++k ) {
00183       double val = args[k].toNumber(exec);
00184       if ( isNaN( val ) )
00185       {
00186         result = NaN;
00187         break;
00188       }
00189       if ( val > result )
00190         result = val;
00191     }
00192     break;
00193   }
00194   case MathObjectImp::Min: {
00195     unsigned int argsCount = args.size();
00196     result = +Inf;
00197     for ( unsigned int k = 0 ; k < argsCount ; ++k ) {
00198       double val = args[k].toNumber(exec);
00199       if ( isNaN( val ) )
00200       {
00201         result = NaN;
00202         break;
00203       }
00204       if ( val < result )
00205         result = val;
00206     }
00207     break;
00208   }
00209   case MathObjectImp::Pow:
00210     // ECMA 15.8.2.1.13 (::pow takes care of most of the critera)
00211     if (KJS::isNaN(arg2))
00212       result = NaN;
00213     else if (arg2 == 0)
00214       result = 1;
00215     else if (KJS::isNaN(arg) && arg2 != 0)
00216       result = NaN;
00217     else if (::fabs(arg) > 1 && KJS::isPosInf(arg2))
00218       result = Inf;
00219     else if (::fabs(arg) > 1 && KJS::isNegInf(arg2))
00220       result = +0;
00221     else if (::fabs(arg) == 1 && KJS::isPosInf(arg2))
00222       result = NaN;
00223     else if (::fabs(arg) == 1 && KJS::isNegInf(arg2))
00224       result = NaN;
00225     else if (::fabs(arg) < 1 && KJS::isPosInf(arg2))
00226       result = +0;
00227     else if (::fabs(arg) < 1 && KJS::isNegInf(arg2))
00228       result = Inf;
00229     else
00230       result = ::pow(arg, arg2);
00231     break;
00232   case MathObjectImp::Random:
00233     result = ::rand();
00234     result = result / RAND_MAX;
00235     break;
00236   case MathObjectImp::Round:
00237     if (isNaN(arg))
00238       result = arg;
00239     else if (isInf(arg) || isInf(-arg))
00240       result = arg;
00241     else if (arg == -0.5)
00242       result = 0;
00243     else
00244       result = (double)(arg >= 0.0 ? int(arg + 0.5) : int(arg - 0.5));
00245     break;
00246   case MathObjectImp::Sin:
00247     result = ::sin(arg);
00248     break;
00249   case MathObjectImp::Sqrt:
00250     result = ::sqrt(arg);
00251     break;
00252   case MathObjectImp::Tan:
00253     result = ::tan(arg);
00254     break;
00255 
00256   default:
00257     result = 0.0;
00258     assert(0);
00259   }
00260 
00261   return Number(result);
00262 }
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.4.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Sun Feb 27 22:15:17 2005 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001