Mercurial > projects > dmdscript-tango
view dmdscript_tango/dmath.d @ 3:8363a4bf6a8f
rename package: dmdscript to dmdscript_tango
author | saaadel |
---|---|
date | Sun, 24 Jan 2010 18:33:05 +0200 |
parents | 55c2951c07be |
children |
line wrap: on
line source
/* Digital Mars DMDScript source code. * Copyright (c) 2000-2002 by Chromium Communications * D version Copyright (c) 2004-2005 by Digital Mars * All Rights Reserved * written by Walter Bright * www.digitalmars.com * Use at your own risk. There is no warranty, express or implied. * License for redistribution is by the GNU General Public License in gpl.txt. * * A binary, non-exclusive license for commercial use can be * purchased from www.digitalmars.com/dscript/buy.html. * * DMDScript is implemented in the D Programming Language, * www.digitalmars.com/d/ * * For a C++ implementation of DMDScript, including COM support, * see www.digitalmars.com/dscript/cppscript.html. */ module dmdscript_tango.dmath; import std.math; import std.random; import dmdscript_tango.script; import dmdscript_tango.value; import dmdscript_tango.dobject; import dmdscript_tango.dnative; import dmdscript_tango.threadcontext; import dmdscript_tango.text; import dmdscript_tango.property; d_number math_helper(Value[] arglist) { Value *v; v = arglist.length ? &arglist[0] : &vundefined; return v.toNumber(); } void* Dmath_abs(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) { // ECMA 15.8.2.1 d_number result; result = fabs(math_helper(arglist)); ret.putVnumber(result); return null; } void* Dmath_acos(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) { // ECMA 15.8.2.2 d_number result; result = acos(math_helper(arglist)); ret.putVnumber(result); return null; } void* Dmath_asin(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) { // ECMA 15.8.2.3 d_number result; result = asin(math_helper(arglist)); ret.putVnumber(result); return null; } void* Dmath_atan(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) { // ECMA 15.8.2.4 d_number result; result = atan(math_helper(arglist)); ret.putVnumber(result); return null; } void* Dmath_atan2(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) { // ECMA 15.8.2.5 d_number n1; Value *v2; d_number result; n1 = math_helper(arglist); v2 = (arglist.length >= 2) ? &arglist[1] : &vundefined; result = atan2(n1, v2.toNumber()); ret.putVnumber(result); return null; } void* Dmath_ceil(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) { // ECMA 15.8.2.6 d_number result; result = ceil(math_helper(arglist)); ret.putVnumber(result); return null; } void* Dmath_cos(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) { // ECMA 15.8.2.7 d_number result; result = cos(math_helper(arglist)); ret.putVnumber(result); return null; } void* Dmath_exp(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) { // ECMA 15.8.2.8 d_number result; result = std.math.exp(math_helper(arglist)); ret.putVnumber(result); return null; } void* Dmath_floor(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) { // ECMA 15.8.2.9 d_number result; result = std.math.floor(math_helper(arglist)); ret.putVnumber(result); return null; } void* Dmath_log(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) { // ECMA 15.8.2.10 d_number result; result = log(math_helper(arglist)); ret.putVnumber(result); return null; } void* Dmath_max(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) { // ECMA v3 15.8.2.11 d_number n; d_number result; uint a; result = -d_number.infinity; foreach (Value v; arglist) { n = v.toNumber(); if (isnan(n)) { result = d_number.nan; break; } if (result == n) { // if n is +0 and result is -0, pick n if (n == 0 && !signbit(n)) result = n; } else if (n > result) result = n; } ret.putVnumber(result); return null; } void* Dmath_min(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) { // ECMA v3 15.8.2.12 d_number n; d_number result; uint a; result = d_number.infinity; foreach (Value v; arglist) { n = v.toNumber(); if (isnan(n)) { result = d_number.nan; break; } if (result == n) { // if n is -0 and result is +0, pick n if (n == 0 && signbit(n)) result = n; } else if (n < result) result = n; } ret.putVnumber(result); return null; } void* Dmath_pow(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) { // ECMA 15.8.2.13 d_number n1; Value *v2; d_number result; n1 = math_helper(arglist); v2 = (arglist.length >= 2) ? &arglist[1] : &vundefined; result = pow(n1, v2.toNumber()); ret.putVnumber(result); return null; } void* Dmath_random(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) { // ECMA 15.8.2.14 // 0.0 <= result < 1.0 d_number result; ulong x; // Only want 53 bits of precision x = (cast(ulong)std.random.rand() << 32) + std.random.rand(); //PRINTF("x = x%016llx\n",x); x &= 0xFFFFFFFFFFFFF800L; result = x * (1 / (0x100000000L * cast(double)0x100000000L)) + (1 / (0x200000000L * cast(double)0x100000000L)); // Experiments on linux show that this will never be exactly // 1.0, so is the assert() worth it? assert(result >= 0 && result < 1.0); ret.putVnumber(result); return null; } void* Dmath_round(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) { // ECMA 15.8.2.15 d_number result; result = math_helper(arglist); if (!isnan(result)) result = copysign(std.math.floor(result + .5), result); ret.putVnumber(result); return null; } void* Dmath_sin(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) { // ECMA 15.8.2.16 d_number result; result = sin(math_helper(arglist)); ret.putVnumber(result); return null; } void* Dmath_sqrt(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) { // ECMA 15.8.2.17 d_number result; result = sqrt(math_helper(arglist)); ret.putVnumber(result); return null; } void* Dmath_tan(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) { // ECMA 15.8.2.18 d_number result; result = tan(math_helper(arglist)); ret.putVnumber(result); return null; } /* ===================== Dmath ==================== */ class Dmath : Dobject { this(ThreadContext *tc) { super(tc.Dobject_prototype); //writef("Dmath::Dmath(%x)\n", this); uint attributes = DontEnum | DontDelete | ReadOnly; struct MathConst { d_string *name; d_number value; } static MathConst table[] = [ { &TEXT_E, std.math.E }, { &TEXT_LN10, std.math.LN10 }, { &TEXT_LN2, std.math.LN2 }, { &TEXT_LOG2E, std.math.LOG2E }, { &TEXT_LOG10E, std.math.LOG10E }, { &TEXT_PI, std.math.PI }, { &TEXT_SQRT1_2, std.math.SQRT1_2 }, { &TEXT_SQRT2, std.math.SQRT2 }, ]; for (size_t u = 0; u < table.length; u++) { Value *v; v = Put(*table[u].name, table[u].value, attributes); //writef("Put(%s,%.5g) = %x\n", *table[u].name, table[u].value, v); } classname = TEXT_Math; static NativeFunctionData nfd[] = [ { &TEXT_abs, &Dmath_abs, 1 }, { &TEXT_acos, &Dmath_acos, 1 }, { &TEXT_asin, &Dmath_asin, 1 }, { &TEXT_atan, &Dmath_atan, 1 }, { &TEXT_atan2, &Dmath_atan2, 2 }, { &TEXT_ceil, &Dmath_ceil, 1 }, { &TEXT_cos, &Dmath_cos, 1 }, { &TEXT_exp, &Dmath_exp, 1 }, { &TEXT_floor, &Dmath_floor, 1 }, { &TEXT_log, &Dmath_log, 1 }, { &TEXT_max, &Dmath_max, 2 }, { &TEXT_min, &Dmath_min, 2 }, { &TEXT_pow, &Dmath_pow, 2 }, { &TEXT_random, &Dmath_random, 0 }, { &TEXT_round, &Dmath_round, 1 }, { &TEXT_sin, &Dmath_sin, 1 }, { &TEXT_sqrt, &Dmath_sqrt, 1 }, { &TEXT_tan, &Dmath_tan, 1 }, ]; DnativeFunction.init(this, nfd, attributes); } static void init(ThreadContext *tc) { tc.Dmath_object = new Dmath(tc); } }