1 module zua.vm.std.math; 2 import zua.vm.engine; 3 import zua.vm.reflection; 4 import std.typecons; 5 import std.random; 6 import std.math; 7 8 private double lmath_abs(double x) { 9 if (x < 0) return -x; 10 else return x; 11 } 12 13 private double lmath_acos(double x) { 14 return acos(x); 15 } 16 17 private double lmath_asin(double x) { 18 return asin(x); 19 } 20 21 private double lmath_atan(double x) { 22 return atan(x); 23 } 24 25 private double lmath_atan2(double y, double x) { 26 return atan2(y, x); 27 } 28 29 private double lmath_ceil(double x) { 30 return ceil(x); 31 } 32 33 private double lmath_cos(double x) { 34 return cos(x); 35 } 36 37 private double lmath_cosh(double x) { 38 return cosh(x); 39 } 40 41 private double lmath_deg(double x) { 42 return x * 180 / PI; 43 } 44 45 private double lmath_exp(double x) { 46 return exp(x); 47 } 48 49 private double lmath_floor(double x) { 50 return floor(x); 51 } 52 53 private double lmath_fmod(double x, double y) { 54 return fmod(x, y); 55 } 56 57 private double lmath_mod(double x, double y) { 58 return fmod(x, y); 59 } 60 61 private Tuple!(double, int) lmath_frexp(double x) { 62 int exp; 63 double res = frexp(x, exp); 64 return tuple(res, exp); 65 } 66 67 private double lmath_ldexp(double m, int e) { 68 return m * pow(2.0, e); 69 } 70 71 private double lmath_log(double x) { 72 return log(x); 73 } 74 75 private double lmath_log10(double x) { 76 return log10(x); 77 } 78 79 private double lmath_max(double x, double y) { 80 if (x > y) return x; 81 else return y; 82 } 83 84 private double lmath_min(double x, double y) { 85 if (x < y) return x; 86 else return y; 87 } 88 89 private Tuple!(double, double) lmath_modf(double x) { 90 if (isNaN(x)) return tuple(x, x); 91 long i = cast(long)x; 92 return tuple(cast(double)i, x - i); 93 } 94 95 private double lmath_pow(double x, double y) { 96 return pow(x, y); 97 } 98 99 private double lmath_rad(double x) { 100 return x * PI / 180; 101 } 102 103 private Random rand; 104 105 static this() { 106 rand = Random(unpredictableSeed); 107 } 108 109 private double lmath_random(Nullable!long m, Nullable!long n) { 110 if (m.isNull && n.isNull) { 111 return uniform!"[)"(0.0, 1.0, rand); 112 } 113 else if (m.isNull && !n.isNull) { 114 throw new Exception("bad argument #1 to 'random' (number expected, got nil)"); 115 } 116 else if (!m.isNull && n.isNull) { 117 return uniform!"[]"(1L, m.get, rand); 118 } 119 else if (!m.isNull && !n.isNull) { 120 return uniform!"[]"(m.get, n.get, rand); 121 } 122 else assert(0); 123 } 124 125 private void lmath_randomseed(long x) { 126 rand.seed(cast(uint)x); 127 } 128 129 private double lmath_sin(double x) { 130 return sin(x); 131 } 132 133 private double lmath_sinh(double x) { 134 return sinh(x); 135 } 136 137 private double lmath_sqrt(double x) { 138 return sqrt(x); 139 } 140 141 private double lmath_tan(double x) { 142 return tan(x); 143 } 144 145 private double lmath_tanh(double x) { 146 return tanh(x); 147 } 148 149 /** Get math library */ 150 Value mathlib() { 151 TableValue res = new TableValue; 152 res.set(Value("abs"), exposeFunction!(lmath_abs, "abs")); 153 res.set(Value("acos"), exposeFunction!(lmath_acos, "acos")); 154 res.set(Value("asin"), exposeFunction!(lmath_asin, "asin")); 155 res.set(Value("atan"), exposeFunction!(lmath_atan, "atan")); 156 res.set(Value("atan2"), exposeFunction!(lmath_atan2, "atan2")); 157 res.set(Value("ceil"), exposeFunction!(lmath_ceil, "ceil")); 158 res.set(Value("cos"), exposeFunction!(lmath_cos, "cos")); 159 res.set(Value("cosh"), exposeFunction!(lmath_cosh, "cosh")); 160 res.set(Value("deg"), exposeFunction!(lmath_deg, "deg")); 161 res.set(Value("exp"), exposeFunction!(lmath_exp, "exp")); 162 res.set(Value("floor"), exposeFunction!(lmath_floor, "floor")); 163 res.set(Value("fmod"), exposeFunction!(lmath_fmod, "fmod")); 164 res.set(Value("mod"), exposeFunction!(lmath_mod, "mod")); 165 res.set(Value("frexp"), exposeFunction!(lmath_frexp, "frexp")); 166 res.set(Value("huge"), Value(double.infinity)); 167 res.set(Value("ldexp"), exposeFunction!(lmath_ldexp, "ldexp")); 168 res.set(Value("log"), exposeFunction!(lmath_log, "log")); 169 res.set(Value("log10"), exposeFunction!(lmath_log10, "log10")); 170 res.set(Value("max"), exposeFunction!(lmath_max, "max")); 171 res.set(Value("min"), exposeFunction!(lmath_min, "min")); 172 res.set(Value("modf"), exposeFunction!(lmath_modf, "modf")); 173 res.set(Value("pi"), Value(PI)); 174 res.set(Value("pow"), exposeFunction!(lmath_pow, "pow")); 175 res.set(Value("rad"), exposeFunction!(lmath_rad, "rad")); 176 res.set(Value("random"), exposeFunction!(lmath_random, "random")); 177 res.set(Value("randomseed"), exposeFunction!(lmath_randomseed, "randomseed")); 178 res.set(Value("sin"), exposeFunction!(lmath_sin, "sin")); 179 res.set(Value("sinh"), exposeFunction!(lmath_sinh, "sinh")); 180 res.set(Value("sqrt"), exposeFunction!(lmath_sqrt, "sqrt")); 181 res.set(Value("tan"), exposeFunction!(lmath_tan, "tan")); 182 res.set(Value("tanh"), exposeFunction!(lmath_tanh, "tanh")); 183 return Value(res); 184 }