#include "value.h"
#include "object.h"
#include "types.h"
#include "interpreter.h"
#include "operations.h"
#include "number_object.h"
#include "error_object.h"
#include "number_object.lut.h"
using namespace KJS;
const ClassInfo NumberInstanceImp::info = {"Number", 0, 0, 0};
NumberInstanceImp::NumberInstanceImp(ObjectImp *proto)
: ObjectImp(proto)
{
}
NumberPrototypeImp::NumberPrototypeImp(ExecState *exec,
ObjectPrototypeImp *objProto,
FunctionPrototypeImp *funcProto)
: NumberInstanceImp(objProto)
{
Value protect(this);
setInternalValue(NumberImp::zero());
putDirect(toStringPropertyName, new NumberProtoFuncImp(exec,funcProto,NumberProtoFuncImp::ToString, 1), DontEnum);
putDirect(toLocaleStringPropertyName, new NumberProtoFuncImp(exec,funcProto,NumberProtoFuncImp::ToLocaleString, 0), DontEnum);
putDirect(valueOfPropertyName, new NumberProtoFuncImp(exec,funcProto,NumberProtoFuncImp::ValueOf, 0), DontEnum);
}
NumberProtoFuncImp::NumberProtoFuncImp(ExecState *exec,
FunctionPrototypeImp *funcProto, int i, int len)
: InternalFunctionImp(funcProto), id(i)
{
Value protect(this);
putDirect(lengthPropertyName, len, DontDelete|ReadOnly|DontEnum);
}
bool NumberProtoFuncImp::implementsCall() const
{
return true;
}
Value NumberProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &args)
{
Value result;
if (!thisObj.inherits(&NumberInstanceImp::info)) {
Object err = Error::create(exec,TypeError);
exec->setException(err);
return err;
}
Value v = thisObj.internalValue();
switch (id) {
case ToString: {
double dradix = 10;
if (!args.isEmpty() && args[0].type() != UndefinedType)
dradix = args[0].toInteger(exec);
if (dradix < 2 || dradix > 36 || dradix == 10)
result = String(v.toString(exec));
else {
int radix = static_cast<int>(radix);
unsigned i = v.toUInt32(exec);
char s[33];
char *p = s + sizeof(s);
*--p = '\0';
do {
*--p = "0123456789abcdefghijklmnopqrstuvwxyz"[i % radix];
i /= radix;
} while (i);
result = String(p);
}
break;
}
case ToLocaleString:
result = String(v.toString(exec));
break;
case ValueOf:
result = Number(v.toNumber(exec));
break;
}
return result;
}
const ClassInfo NumberObjectImp::info = {"Number", &InternalFunctionImp::info, &numberTable, 0};
NumberObjectImp::NumberObjectImp(ExecState *exec,
FunctionPrototypeImp *funcProto,
NumberPrototypeImp *numberProto)
: InternalFunctionImp(funcProto)
{
Value protect(this);
putDirect(prototypePropertyName, numberProto,DontEnum|DontDelete|ReadOnly);
putDirect(lengthPropertyName, NumberImp::one(), ReadOnly|DontDelete|DontEnum);
}
Value NumberObjectImp::get(ExecState *exec, const Identifier &propertyName) const
{
return lookupGetValue<NumberObjectImp, InternalFunctionImp>( exec, propertyName, &numberTable, this );
}
Value NumberObjectImp::getValueProperty(ExecState *, int token) const
{
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();
}
bool NumberObjectImp::implementsConstruct() const
{
return true;
}
Object NumberObjectImp::construct(ExecState *exec, const List &args)
{
ObjectImp *proto = exec->lexicalInterpreter()->builtinNumberPrototype().imp();
Object obj(new NumberInstanceImp(proto));
Number n;
if (args.isEmpty())
n = Number(0);
else
n = args[0].toNumber(exec);
obj.setInternalValue(n);
return obj;
}
bool NumberObjectImp::implementsCall() const
{
return true;
}
Value NumberObjectImp::call(ExecState *exec, Object &, const List &args)
{
if (args.isEmpty())
return Number(0);
else
return Number(args[0].toNumber(exec));
}