number_object.cpp 5.43 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 21
 */

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

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

using namespace KJS;

34 35 36 37 38 39 40

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

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

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

// ECMA 15.7.4
46

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

55 56
  // The constructor will be added later, after NumberObjectImp has been constructed

darin's avatar
darin committed
57
  put(exec,toStringPropertyName,       Object(new NumberProtoFuncImp(exec,funcProto,NumberProtoFuncImp::ToString,       1)), DontEnum);
58
  put(exec,toLocaleStringPropertyName, Object(new NumberProtoFuncImp(exec,funcProto,NumberProtoFuncImp::ToLocaleString, 0)), DontEnum);
darin's avatar
darin committed
59
  put(exec,valueOfPropertyName,        Object(new NumberProtoFuncImp(exec,funcProto,NumberProtoFuncImp::ValueOf,        0)), DontEnum);
60 61 62
}


63
// ------------------------------ NumberProtoFuncImp ---------------------------
64

65 66 67
NumberProtoFuncImp::NumberProtoFuncImp(ExecState *exec,
                                       FunctionPrototypeImp *funcProto, int i, int len)
  : InternalFunctionImp(funcProto), id(i)
68
{
69
  Value protect(this);
darin's avatar
darin committed
70
  put(exec,lengthPropertyName,Number(len),DontDelete|ReadOnly|DontEnum);
71 72 73
}


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

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

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

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

103
  return result;
104 105
}

106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
// ------------------------------ 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)
124
{
125 126
  Value protect(this);
  // Number.Prototype
darin's avatar
darin committed
127
  put(exec,prototypePropertyName, Value(numberProto),DontEnum|DontDelete|ReadOnly);
128 129

  // no. of arguments for constructor
darin's avatar
darin committed
130
  put(exec,lengthPropertyName, Number(1), ReadOnly|DontDelete|DontEnum);
131 132
}

darin's avatar
darin committed
133
Value NumberObjectImp::get(ExecState *exec, const Identifier &propertyName) const
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
{
  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();
154 155
}

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


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

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

  obj.setInternalValue(n);

  return obj;
}
178

179 180 181 182 183 184 185 186 187 188 189 190
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));
191
}