number_object.cpp 5.38 KB
Newer Older
1
// -*- c-basic-offset: 2 -*-
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*
 *  This file is part of the KDE libraries
 *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 20
 *
 *  $Id$
21 22
 */

23 24 25 26
#include "value.h"
#include "object.h"
#include "types.h"
#include "interpreter.h"
27 28
#include "operations.h"
#include "number_object.h"
29 30 31
#include "error_object.h"

#include "number_object.lut.h"
32 33 34

using namespace KJS;

35 36 37 38 39 40 41

// ------------------------------ NumberInstanceImp ----------------------------

const ClassInfo NumberInstanceImp::info = {"Number", 0, 0, 0};

NumberInstanceImp::NumberInstanceImp(const Object &proto)
  : ObjectImp(proto)
42 43
{
}
44 45 46
// ------------------------------ NumberPrototypeImp ---------------------------

// ECMA 15.7.4
47

48 49 50 51
NumberPrototypeImp::NumberPrototypeImp(ExecState *exec,
                                       ObjectPrototypeImp *objProto,
                                       FunctionPrototypeImp *funcProto)
  : NumberInstanceImp(Object(objProto))
52
{
53 54
  Value protect(this);
  setInternalValue(Number(0));
55

56 57 58 59 60
  // The constructor will be added later, after NumberObjectImp has been constructed

  put(exec,"toString",       Object(new NumberProtoFuncImp(exec,funcProto,NumberProtoFuncImp::ToString,       1)), DontEnum);
  put(exec,"toLocaleString", Object(new NumberProtoFuncImp(exec,funcProto,NumberProtoFuncImp::ToLocaleString, 0)), DontEnum);
  put(exec,"valueOf",        Object(new NumberProtoFuncImp(exec,funcProto,NumberProtoFuncImp::ValueOf,        0)), DontEnum);
61 62 63
}


64
// ------------------------------ NumberProtoFuncImp ---------------------------
65

66 67 68
NumberProtoFuncImp::NumberProtoFuncImp(ExecState *exec,
                                       FunctionPrototypeImp *funcProto, int i, int len)
  : InternalFunctionImp(funcProto), id(i)
69
{
70 71
  Value protect(this);
  put(exec,"length",Number(len),DontDelete|ReadOnly|DontEnum);
72 73 74
}


75
bool NumberProtoFuncImp::implementsCall() const
76
{
77 78
  return true;
}
79

80 81 82 83
// ECMA 15.7.4.2 - 15.7.4.7
Value NumberProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &/*args*/)
{
  Value result;
84 85

  // no generic function. "this" has to be a Number object
86 87 88 89
  if (!thisObj.inherits(&NumberInstanceImp::info)) {
    Object err = Error::create(exec,TypeError);
    exec->setException(err);
    return err;
90 91 92
  }

  // execute "toString()" or "valueOf()", respectively
93
  Value v = thisObj.internalValue();
94 95 96
  switch (id) {
  case ToString:
  case ToLocaleString: /* TODO */
97
    result = String(v.toString(exec));
98 99
    break;
  case ValueOf:
100
    result = Number(v.toNumber(exec));
101 102 103
    break;
  }

104
  return result;
105 106
}

107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
// ------------------------------ NumberObjectImp ------------------------------

const ClassInfo NumberObjectImp::info = {"Number", &InternalFunctionImp::info, &numberTable, 0};
//const ClassInfo NumberObjectImp::info = {"Number", 0, &numberTable, 0};

/* Source for number_object.lut.h
@begin numberTable 5
  NaN			NumberObjectImp::NaNValue	DontEnum
  NEGATIVE_INFINITY	NumberObjectImp::NegInfinity	DontEnum
  POSITIVE_INFINITY	NumberObjectImp::PosInfinity	DontEnum
  MAX_VALUE		NumberObjectImp::MaxValue	DontEnum
  MIN_VALUE		NumberObjectImp::MinValue	DontEnum
@end
*/
NumberObjectImp::NumberObjectImp(ExecState *exec,
                                 FunctionPrototypeImp *funcProto,
                                 NumberPrototypeImp *numberProto)
  : InternalFunctionImp(funcProto)
125
{
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
  Value protect(this);
  // Number.Prototype
  put(exec,"prototype", Value(numberProto),DontEnum|DontDelete|ReadOnly);

  // no. of arguments for constructor
  put(exec,"length", Number(1), ReadOnly|DontDelete|DontEnum);
}

Value NumberObjectImp::get(ExecState *exec, const UString &propertyName) const
{
  return lookupGetValue<NumberObjectImp, InternalFunctionImp>( exec, propertyName, &numberTable, this );
}

Value NumberObjectImp::getValueProperty(ExecState *, int token) const
{
  // ECMA 15.7.3
  switch(token) {
  case NaNValue:
    return Number(NaN);
  case NegInfinity:
    return Number(-Inf);
  case PosInfinity:
    return Number(Inf);
  case MaxValue:
    return Number(1.7976931348623157E+308);
  case MinValue:
    return Number(5E-324);
  }
  return Null();
155 156
}

157 158 159 160 161 162 163 164
bool NumberObjectImp::implementsConstruct() const
{
  return true;
}


// ECMA 15.7.1
Object NumberObjectImp::construct(ExecState *exec, const List &args)
165
{
166 167 168 169 170 171
  Object proto = exec->interpreter()->builtinNumberPrototype();
  Object obj(new NumberInstanceImp(proto));

  Number n;
  if (args.isEmpty())
    n = Number(0);
172
  else
173 174 175 176 177 178
    n = args[0].toNumber(exec);

  obj.setInternalValue(n);

  return obj;
}
179

180 181 182 183 184 185 186 187 188 189 190 191
bool NumberObjectImp::implementsCall() const
{
  return true;
}

// ECMA 15.7.2
Value NumberObjectImp::call(ExecState *exec, Object &/*thisObj*/, const List &args)
{
  if (args.isEmpty())
    return Number(0);
  else
    return Number(args[0].toNumber(exec));
192
}