0
|
1
|
|
2 /* Digital Mars DMDScript source code.
|
|
3 * Copyright (c) 2000-2002 by Chromium Communications
|
|
4 * D version Copyright (c) 2004-2006 by Digital Mars
|
|
5 * All Rights Reserved
|
|
6 * written by Walter Bright
|
|
7 * www.digitalmars.com
|
|
8 * Use at your own risk. There is no warranty, express or implied.
|
|
9 * License for redistribution is by the GNU General Public License in gpl.txt.
|
|
10 *
|
|
11 * A binary, non-exclusive license for commercial use can be
|
|
12 * purchased from www.digitalmars.com/dscript/buy.html.
|
|
13 *
|
|
14 * DMDScript is implemented in the D Programming Language,
|
|
15 * www.digitalmars.com/d/
|
|
16 *
|
|
17 * For a C++ implementation of DMDScript, including COM support,
|
|
18 * see www.digitalmars.com/dscript/cppscript.html.
|
|
19 */
|
|
20
|
|
21
|
|
22 module dmdscript.dnumber;
|
|
23
|
|
24 import std.math;
|
|
25 import std.c.stdlib;
|
|
26
|
|
27 import dmdscript.script;
|
|
28 import dmdscript.dobject;
|
|
29 import dmdscript.dfunction;
|
|
30 import dmdscript.value;
|
|
31 import dmdscript.threadcontext;
|
|
32 import dmdscript.text;
|
|
33 import dmdscript.property;
|
|
34 import dmdscript.errmsgs;
|
|
35 import dmdscript.dnative;
|
|
36
|
|
37 /* ===================== Dnumber_constructor ==================== */
|
|
38
|
|
39 class Dnumber_constructor : Dfunction
|
|
40 {
|
|
41 this(ThreadContext *tc)
|
|
42 {
|
|
43 super(1, tc.Dfunction_prototype);
|
|
44 uint attributes = DontEnum | DontDelete | ReadOnly;
|
|
45
|
|
46 name = TEXT_Number;
|
|
47 Put(TEXT_MAX_VALUE, d_number.max, attributes);
|
|
48 Put(TEXT_MIN_VALUE, d_number.min, attributes);
|
|
49 Put(TEXT_NaN, d_number.nan, attributes);
|
|
50 Put(TEXT_NEGATIVE_INFINITY, -d_number.infinity, attributes);
|
|
51 Put(TEXT_POSITIVE_INFINITY, d_number.infinity, attributes);
|
|
52 }
|
|
53
|
|
54 void* Construct(CallContext *cc, Value *ret, Value[] arglist)
|
|
55 {
|
|
56 // ECMA 15.7.2
|
|
57 d_number n;
|
|
58 Dobject o;
|
|
59
|
|
60 n = (arglist.length) ? arglist[0].toNumber() : 0;
|
|
61 o = new Dnumber(n);
|
|
62 ret.putVobject(o);
|
|
63 return null;
|
|
64 }
|
|
65
|
|
66 void* Call(CallContext *cc, Dobject othis, Value* ret, Value[] arglist)
|
|
67 {
|
|
68 // ECMA 15.7.1
|
|
69 d_number n;
|
|
70
|
|
71 n = (arglist.length) ? arglist[0].toNumber() : 0;
|
|
72 ret.putVnumber(n);
|
|
73 return null;
|
|
74 }
|
|
75 }
|
|
76
|
|
77
|
|
78 /* ===================== Dnumber_prototype_toString =============== */
|
|
79
|
|
80 void* Dnumber_prototype_toString(Dobject pthis, CallContext *cc, Dobject othis, Value *ret, Value[] arglist)
|
|
81 {
|
|
82 // ECMA v3 15.7.4.2
|
|
83 d_string s;
|
|
84
|
|
85 // othis must be a Number
|
|
86 if (!othis.isClass(TEXT_Number))
|
|
87 {
|
|
88 ret.putVundefined();
|
|
89 ErrInfo errinfo;
|
|
90 return Dobject.RuntimeError(&errinfo,
|
|
91 errmsgtbl[ERR_FUNCTION_WANTS_NUMBER],
|
|
92 TEXT_toString,
|
|
93 othis.classname);
|
|
94 }
|
|
95 else
|
|
96 { Value* v;
|
|
97
|
|
98 v = &(cast(Dnumber)othis).value;
|
|
99
|
|
100 if (arglist.length)
|
|
101 {
|
|
102 d_number radix;
|
|
103
|
|
104 radix = arglist[0].toNumber();
|
|
105 if (radix == 10.0 || arglist[0].isUndefined())
|
|
106 s = v.toString();
|
|
107 else
|
|
108 {
|
|
109 int r;
|
|
110
|
|
111 r = cast(int) radix;
|
|
112 // radix must be an integer 2..36
|
|
113 if (r == radix && r >= 2 && r <= 36)
|
|
114 s = v.toString(r);
|
|
115 else
|
|
116 s = v.toString();
|
|
117 }
|
|
118 }
|
|
119 else
|
|
120 s = v.toString();
|
|
121 ret.putVstring(s);
|
|
122 }
|
|
123 return null;
|
|
124 }
|
|
125
|
|
126 /* ===================== Dnumber_prototype_toLocaleString =============== */
|
|
127
|
|
128 void* Dnumber_prototype_toLocaleString(Dobject pthis, CallContext *cc, Dobject othis, Value *ret, Value[] arglist)
|
|
129 {
|
|
130 // ECMA v3 15.7.4.3
|
|
131 d_string s;
|
|
132
|
|
133 // othis must be a Number
|
|
134 if (!othis.isClass(TEXT_Number))
|
|
135 {
|
|
136 ret.putVundefined();
|
|
137 ErrInfo errinfo;
|
|
138 return Dobject.RuntimeError(&errinfo,
|
|
139 errmsgtbl[ERR_FUNCTION_WANTS_NUMBER],
|
|
140 TEXT_toLocaleString,
|
|
141 othis.classname);
|
|
142 }
|
|
143 else
|
|
144 { Value* v;
|
|
145
|
|
146 v = &(cast(Dnumber)othis).value;
|
|
147
|
|
148 s = v.toLocaleString();
|
|
149 ret.putVstring(s);
|
|
150 }
|
|
151 return null;
|
|
152 }
|
|
153
|
|
154 /* ===================== Dnumber_prototype_valueOf =============== */
|
|
155
|
|
156 void* Dnumber_prototype_valueOf(Dobject pthis, CallContext *cc, Dobject othis, Value *ret, Value[] arglist)
|
|
157 {
|
|
158 // othis must be a Number
|
|
159 if (!othis.isClass(TEXT_Number))
|
|
160 {
|
|
161 ret.putVundefined();
|
|
162 ErrInfo errinfo;
|
|
163 return Dobject.RuntimeError(&errinfo,
|
|
164 errmsgtbl[ERR_FUNCTION_WANTS_NUMBER],
|
|
165 TEXT_valueOf,
|
|
166 othis.classname);
|
|
167 }
|
|
168 else
|
|
169 {
|
|
170 Value* v;
|
|
171
|
|
172 v = &(cast(Dnumber)othis).value;
|
|
173 Value.copy(ret, v);
|
|
174 }
|
|
175 return null;
|
|
176 }
|
|
177
|
|
178 /* ===================== Formatting Support =============== */
|
|
179
|
|
180 const int FIXED_DIGITS = 20; // ECMA says >= 20
|
|
181
|
|
182
|
|
183 // power of tens array, indexed by power
|
|
184
|
|
185 static d_number tens[FIXED_DIGITS+1] =
|
|
186 [
|
|
187 1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
|
|
188 1e10,1e11,1e12,1e13,1e14,1e15,1e16,1e17,1e18,1e19,
|
|
189 1e20,
|
|
190 ];
|
|
191
|
|
192 /************************************************
|
|
193 * Let e and n be integers such that
|
|
194 * 10**f <= n < 10**(f+1) and for which the exact
|
|
195 * mathematical value of n * 10**(e-f) - x is as close
|
|
196 * to zero as possible. If there are two such sets of
|
|
197 * e and n, pick the e and n for which n * 10**(e-f)
|
|
198 * is larger.
|
|
199 */
|
|
200
|
|
201 number_t deconstruct_real(d_number x, int f, out int pe)
|
|
202 {
|
|
203 number_t n;
|
|
204 int e;
|
|
205 int i;
|
|
206
|
|
207 e = cast(int) log10(x);
|
|
208 i = e - f;
|
|
209 if (i >= 0 && i < tens.length)
|
|
210 // table lookup for speed & accuracy
|
|
211 n = cast(number_t)(x / tens[i] + 0.5);
|
|
212 else
|
|
213 n = cast(number_t)(x / std.math.pow(cast(real)10.0, i) + 0.5);
|
|
214
|
|
215 pe = e;
|
|
216 return n;
|
|
217 }
|
|
218
|
|
219 /* ===================== Dnumber_prototype_toFixed =============== */
|
|
220
|
|
221 void* Dnumber_prototype_toFixed(Dobject pthis, CallContext *cc, Dobject othis, Value *ret, Value[] arglist)
|
|
222 {
|
|
223 // ECMA v3 15.7.4.5
|
|
224 Value* v;
|
|
225 d_number x;
|
|
226 d_number fractionDigits;
|
|
227 d_string result;
|
|
228 int dup;
|
|
229
|
|
230 v = &arglist[0];
|
|
231 fractionDigits = (arglist.length) ? v.toInteger() : 0;
|
|
232 if (fractionDigits < 0 || fractionDigits > FIXED_DIGITS)
|
|
233 {
|
|
234 ErrInfo errinfo;
|
|
235
|
|
236 ret.putVundefined();
|
|
237 return Dobject.RangeError(&errinfo, ERR_VALUE_OUT_OF_RANGE,
|
|
238 TEXT_toFixed, "fractionDigits");
|
|
239 }
|
|
240 v = &othis.value;
|
|
241 x = v.toNumber();
|
|
242 if (isnan(x))
|
|
243 {
|
|
244 result = TEXT_NaN; // return "NaN"
|
|
245 }
|
|
246 else
|
|
247 { int sign;
|
|
248 tchar[] m;
|
|
249
|
|
250 sign = 0;
|
|
251 if (x < 0)
|
|
252 {
|
|
253 sign = 1;
|
|
254 x = -x;
|
|
255 }
|
|
256 if (x >= 10.0e+21) // exponent must be FIXED_DIGITS+1
|
|
257 {
|
|
258 Value vn;
|
|
259 vn.putVnumber(x);
|
|
260 m = vn.toString();
|
|
261 dup = 0;
|
|
262 }
|
|
263 else
|
|
264 {
|
|
265 number_t n;
|
|
266 tchar buffer[32 + 1];
|
|
267 d_number tenf;
|
|
268 int f;
|
|
269
|
|
270 f = cast(int) fractionDigits;
|
|
271 tenf = tens[f]; // tenf = 10**f
|
|
272
|
|
273 // Compute n which gives |(n / tenf) - x| is the smallest
|
|
274 // value. If there are two such n's, pick the larger.
|
|
275 n = cast(number_t)(x * tenf + 0.5); // round up & chop
|
|
276
|
|
277 if (n == 0)
|
|
278 { m = "0";
|
|
279 dup = 0;
|
|
280 }
|
|
281 else
|
|
282 {
|
|
283 // n still doesn't give 20 digits, only 19
|
|
284 m = std.string.sformat(buffer, cast(ulong)n);
|
|
285 dup = 1;
|
|
286 }
|
|
287 if (f != 0)
|
|
288 { int i;
|
|
289 int k;
|
|
290
|
|
291 k = m.length;
|
|
292 if (k <= f)
|
|
293 { tchar* s;
|
|
294 int nzeros;
|
|
295
|
|
296 s = cast(tchar*)alloca((f + 1) * tchar.sizeof);
|
|
297 assert(s);
|
|
298 nzeros = f + 1 - k;
|
|
299 s[0 .. nzeros] = '0';
|
|
300 s[nzeros .. f + 1] = m[0 .. k];
|
|
301
|
|
302 m = s[0 .. f + 1];
|
|
303 k = f + 1;
|
|
304 }
|
|
305
|
|
306 // result = "-" + m[0 .. k-f] + "." + m[k-f .. k];
|
|
307 result = new tchar[sign + k + 1];
|
|
308 if (sign)
|
|
309 result[0] = '-';
|
|
310 i = k - f;
|
|
311 result[sign .. sign + i] = m[0 .. i];
|
|
312 result[sign + i] = '.';
|
|
313 result[sign + i + 1 .. sign + k + 1] = m[i .. k];
|
|
314 goto Ldone;
|
|
315 }
|
|
316 }
|
|
317 if (sign)
|
|
318 result = TEXT_dash ~ m;
|
|
319 else if (dup)
|
|
320 result = m.dup;
|
|
321 else
|
|
322 result = m;
|
|
323 }
|
|
324
|
|
325 Ldone:
|
|
326 ret.putVstring(result);
|
|
327 return null;
|
|
328 }
|
|
329
|
|
330 /* ===================== Dnumber_prototype_toExponential =============== */
|
|
331
|
|
332 void* Dnumber_prototype_toExponential(Dobject pthis, CallContext *cc, Dobject othis, Value *ret, Value[] arglist)
|
|
333 {
|
|
334 // ECMA v3 15.7.4.6
|
|
335 Value* varg;
|
|
336 Value* v;
|
|
337 d_number x;
|
|
338 d_number fractionDigits;
|
|
339 d_string result;
|
|
340
|
|
341 varg = &arglist[0];
|
|
342 fractionDigits = (arglist.length) ? varg.toInteger() : 0;
|
|
343
|
|
344 v = &othis.value;
|
|
345 x = v.toNumber();
|
|
346 if (isnan(x))
|
|
347 {
|
|
348 result = TEXT_NaN; // return "NaN"
|
|
349 }
|
|
350 else
|
|
351 { int sign;
|
|
352
|
|
353 sign = 0;
|
|
354 if (x < 0)
|
|
355 {
|
|
356 sign = 1;
|
|
357 x = -x;
|
|
358 }
|
|
359 if (std.math.isinf(x))
|
|
360 {
|
|
361 result = sign ? TEXT_negInfinity : TEXT_Infinity;
|
|
362 }
|
|
363 else
|
|
364 { int f;
|
|
365 number_t n;
|
|
366 int e;
|
|
367 tchar[] m;
|
|
368 int i;
|
|
369 tchar buffer[32 + 1];
|
|
370
|
|
371 if (fractionDigits < 0 || fractionDigits > FIXED_DIGITS)
|
|
372 {
|
|
373 ErrInfo errinfo;
|
|
374
|
|
375 ret.putVundefined();
|
|
376 return Dobject.RangeError(&errinfo,
|
|
377 ERR_VALUE_OUT_OF_RANGE,
|
|
378 TEXT_toExponential,
|
|
379 "fractionDigits");
|
|
380 }
|
|
381
|
|
382 f = cast(int) fractionDigits;
|
|
383 if (x == 0)
|
|
384 { tchar* s;
|
|
385
|
|
386 s = cast(tchar*)alloca((f + 1) * tchar.sizeof);
|
|
387 assert(s);
|
|
388 m = s[0 .. f + 1];
|
|
389 m[0 .. f + 1] = '0';
|
|
390 e = 0;
|
|
391 }
|
|
392 else
|
|
393 {
|
|
394 if (arglist.length && !varg.isUndefined())
|
|
395 {
|
|
396 /* Step 12
|
|
397 * Let e and n be integers such that
|
|
398 * 10**f <= n < 10**(f+1) and for which the exact
|
|
399 * mathematical value of n * 10**(e-f) - x is as close
|
|
400 * to zero as possible. If there are two such sets of
|
|
401 * e and n, pick the e and n for which n * 10**(e-f)
|
|
402 * is larger.
|
|
403 * [Note: this is the same as Step 15 in toPrecision()
|
|
404 * with f = p - 1]
|
|
405 */
|
|
406 n = deconstruct_real(x, f, e);
|
|
407 }
|
|
408 else
|
|
409 {
|
|
410 /* Step 19
|
|
411 * Let e, n, and f be integers such that f >= 0,
|
|
412 * 10**f <= n < 10**(f+1), the number value for
|
|
413 * n * 10**(e-f) is x, and f is as small as possible.
|
|
414 * Note that the decimal representation of n has f+1
|
|
415 * digits, n is not divisible by 10, and the least
|
|
416 * significant digit of n is not necessarilly uniquely
|
|
417 * determined by these criteria.
|
|
418 */
|
|
419 /* Implement by trying maximum digits, and then
|
|
420 * lopping off trailing 0's.
|
|
421 */
|
|
422 f = 19; // should use FIXED_DIGITS
|
|
423 n = deconstruct_real(x, f, e);
|
|
424
|
|
425 // Lop off trailing 0's
|
|
426 assert(n);
|
|
427 while ((n % 10) == 0)
|
|
428 {
|
|
429 n /= 10;
|
|
430 f--;
|
|
431 assert(f >= 0);
|
|
432 }
|
|
433 }
|
|
434 // n still doesn't give 20 digits, only 19
|
|
435 m = std.string.sformat(buffer, cast(ulong)n);
|
|
436 }
|
|
437 if (f)
|
|
438 { tchar* s;
|
|
439
|
|
440 // m = m[0] + "." + m[1 .. f+1];
|
|
441 s = cast(tchar*)alloca((f + 2) * tchar.sizeof);
|
|
442 assert(s);
|
|
443 s[0] = m[0];
|
|
444 s[1] = '.';
|
|
445 s[2 .. f + 2] = m[1 .. f + 1];
|
|
446 m = s[0 .. f + 2];
|
|
447 }
|
|
448
|
|
449 // result = sign + m + "e" + c + e;
|
|
450 tchar[] c = (e >= 0) ? "+" : "";
|
|
451
|
|
452 result = std.string.format("%s%se%s%d", sign ? "-" : "", m, c, e);
|
|
453 }
|
|
454 }
|
|
455
|
|
456 ret.putVstring(result);
|
|
457 return null;
|
|
458 }
|
|
459
|
|
460 /* ===================== Dnumber_prototype_toPrecision =============== */
|
|
461
|
|
462 void* Dnumber_prototype_toPrecision(Dobject pthis, CallContext *cc, Dobject othis, Value *ret, Value[] arglist)
|
|
463 {
|
|
464 // ECMA v3 15.7.4.7
|
|
465 Value* varg;
|
|
466 Value* v;
|
|
467 d_number x;
|
|
468 d_number precision;
|
|
469 d_string result;
|
|
470
|
|
471 v = &othis.value;
|
|
472 x = v.toNumber();
|
|
473
|
|
474 varg = (arglist.length == 0) ? &vundefined : &arglist[0];
|
|
475
|
|
476 if (arglist.length == 0 || varg.isUndefined())
|
|
477 {
|
|
478 Value vn;
|
|
479
|
|
480 vn.putVnumber(x);
|
|
481 result = vn.toString();
|
|
482 }
|
|
483 else
|
|
484 {
|
|
485 if (isnan(x))
|
|
486 result = TEXT_NaN;
|
|
487 else
|
|
488 { int sign;
|
|
489 int e;
|
|
490 int p;
|
|
491 int i;
|
|
492 tchar[] m;
|
|
493 number_t n;
|
|
494 tchar buffer[32 + 1];
|
|
495
|
|
496 sign = 0;
|
|
497 if (x < 0)
|
|
498 {
|
|
499 sign = 1;
|
|
500 x = -x;
|
|
501 }
|
|
502
|
|
503 if (std.math.isinf(x))
|
|
504 {
|
|
505 result = sign ? TEXT_negInfinity : TEXT_Infinity;
|
|
506 goto Ldone;
|
|
507 }
|
|
508
|
|
509 precision = varg.toInteger();
|
|
510 if (precision < 1 || precision > 21)
|
|
511 {
|
|
512 ErrInfo errinfo;
|
|
513
|
|
514 ret.putVundefined();
|
|
515 return Dobject.RangeError(&errinfo,
|
|
516 ERR_VALUE_OUT_OF_RANGE,
|
|
517 TEXT_toPrecision,
|
|
518 "precision");
|
|
519 }
|
|
520
|
|
521 p = cast(int) precision;
|
|
522 if (x != 0)
|
|
523 {
|
|
524 /* Step 15
|
|
525 * Let e and n be integers such that 10**(p-1) <= n < 10**p
|
|
526 * and for which the exact mathematical value of n * 10**(e-p+1) - x
|
|
527 * is as close to zero as possible. If there are two such sets
|
|
528 * of e and n, pick the e and n for which n * 10**(e-p+1) is larger.
|
|
529 */
|
|
530 n = deconstruct_real(x, p - 1, e);
|
|
531
|
|
532 // n still doesn't give 20 digits, only 19
|
|
533 m = std.string.sformat(buffer, cast(ulong)n);
|
|
534
|
|
535 if (e < -6 || e >= p)
|
|
536 {
|
|
537 // result = sign + m[0] + "." + m[1 .. p] + "e" + c + e;
|
|
538 tchar[] c = (e >= 0) ? "+" : "";
|
|
539 result = std.string.format("%s%s.%se%s%d",
|
|
540 (sign ? "-" : ""), m[0], m[1 .. length], c, e);
|
|
541 goto Ldone;
|
|
542 }
|
|
543 }
|
|
544 else
|
|
545 {
|
|
546 // Step 12
|
|
547 // m = array[p] of '0'
|
|
548 tchar* s;
|
|
549 s = cast(tchar*)alloca(p * tchar.sizeof);
|
|
550 assert(s);
|
|
551 m = s[0 .. p];
|
|
552 m[] = '0';
|
|
553
|
|
554 e = 0;
|
|
555 }
|
|
556 if (e != p - 1)
|
|
557 { tchar* s;
|
|
558
|
|
559 if (e >= 0)
|
|
560 {
|
|
561 // m = m[0 .. e+1] + "." + m[e+1 .. p];
|
|
562
|
|
563 s = cast(tchar*)alloca((p + 1) * tchar.sizeof);
|
|
564 assert(s);
|
|
565 i = e + 1;
|
|
566 s[0 .. i] = m[0 .. i];
|
|
567 s[i] = '.';
|
|
568 s[i + 1 .. p + 1] = m[i .. p];
|
|
569 m = s[0 .. p + 1];
|
|
570 }
|
|
571 else
|
|
572 {
|
|
573 // m = "0." + (-(e+1) occurrences of the character '0') + m;
|
|
574 int imax = 2 + -(e + 1);
|
|
575
|
|
576 s = cast(tchar*)alloca((imax + p) * tchar.sizeof);
|
|
577 assert(s);
|
|
578 s[0] = '0';
|
|
579 s[1] = '.';
|
|
580 s[2 .. imax] = '0';
|
|
581 s[imax .. imax + p] = m[0 .. p];
|
|
582 m = s[0 .. imax + p];
|
|
583 }
|
|
584 }
|
|
585 if (sign)
|
|
586 result = TEXT_dash ~ m;
|
|
587 else
|
|
588 result = m.dup;
|
|
589 }
|
|
590 }
|
|
591
|
|
592 Ldone:
|
|
593 ret.putVstring(result);
|
|
594 return null;
|
|
595 }
|
|
596
|
|
597 /* ===================== Dnumber_prototype ==================== */
|
|
598
|
|
599 class Dnumber_prototype : Dnumber
|
|
600 {
|
|
601 this(ThreadContext *tc)
|
|
602 {
|
|
603 super(tc.Dobject_prototype);
|
|
604 uint attributes = DontEnum;
|
|
605
|
|
606 Dobject f = tc.Dfunction_prototype;
|
|
607
|
|
608 Put(TEXT_constructor, tc.Dnumber_constructor, attributes);
|
|
609
|
|
610 static NativeFunctionData nfd[] =
|
|
611 [
|
|
612 { &TEXT_toString, &Dnumber_prototype_toString, 1 },
|
|
613 // Permissible to use toString()
|
|
614 { &TEXT_toLocaleString, &Dnumber_prototype_toLocaleString, 1 },
|
|
615 { &TEXT_valueOf, &Dnumber_prototype_valueOf, 0 },
|
|
616 { &TEXT_toFixed, &Dnumber_prototype_toFixed, 1 },
|
|
617 { &TEXT_toExponential, &Dnumber_prototype_toExponential, 1 },
|
|
618 { &TEXT_toPrecision, &Dnumber_prototype_toPrecision, 1 },
|
|
619 ];
|
|
620
|
|
621 DnativeFunction.init(this, nfd, attributes);
|
|
622 }
|
|
623 }
|
|
624
|
|
625
|
|
626 /* ===================== Dnumber ==================== */
|
|
627
|
|
628 class Dnumber : Dobject
|
|
629 {
|
|
630 this(d_number n)
|
|
631 {
|
|
632 super(getPrototype());
|
|
633 classname = TEXT_Number;
|
|
634 value.putVnumber(n);
|
|
635 }
|
|
636
|
|
637 this(Dobject prototype)
|
|
638 {
|
|
639 super(prototype);
|
|
640 classname = TEXT_Number;
|
|
641 value.putVnumber(0);
|
|
642 }
|
|
643
|
|
644 static Dfunction getConstructor()
|
|
645 {
|
|
646 ThreadContext *tc = ThreadContext.getThreadContext();
|
|
647 assert(tc);
|
|
648 return tc.Dnumber_constructor;
|
|
649 }
|
|
650
|
|
651 static Dobject getPrototype()
|
|
652 {
|
|
653 ThreadContext *tc = ThreadContext.getThreadContext();
|
|
654 assert(tc);
|
|
655 return tc.Dnumber_prototype;
|
|
656 }
|
|
657
|
|
658 static void init(ThreadContext *tc)
|
|
659 {
|
|
660 tc.Dnumber_constructor = new Dnumber_constructor(tc);
|
|
661 tc.Dnumber_prototype = new Dnumber_prototype(tc);
|
|
662
|
|
663 tc.Dnumber_constructor.Put(TEXT_prototype, tc.Dnumber_prototype, DontEnum | DontDelete | ReadOnly);
|
|
664 }
|
|
665 }
|
|
666
|