]> git.mxchange.org Git - simgear.git/blob - simgear/nasal/mathlib.c
Removal of PLIB/SG from SimGear
[simgear.git] / simgear / nasal / mathlib.c
1 #include <math.h>
2 #include <string.h>
3
4 #include "nasal.h"
5
6 // Toss a runtime error for any NaN or Inf values produced.  Note that
7 // this assumes an IEEE 754 format.
8 #define VALIDATE(r) (valid(r.num) ? (r) : die(c, __FUNCTION__+2))
9
10 static int valid(double d)
11 {
12     union { double d; unsigned long long ull; } u;
13     u.d = d;
14     return ((u.ull >> 52) & 0x7ff) != 0x7ff;
15 }
16
17 static naRef die(naContext c, const char* fn)
18 {
19     naRuntimeError(c, "floating point error in math.%s()", fn);
20     return naNil();
21 }
22
23 static naRef f_sin(naContext c, naRef me, int argc, naRef* args)
24 {
25     naRef a = naNumValue(argc > 0 ? args[0] : naNil());
26     if(naIsNil(a))
27         naRuntimeError(c, "non numeric argument to sin()");
28     a.num = sin(a.num);
29     return VALIDATE(a);
30 }
31
32 static naRef f_cos(naContext c, naRef me, int argc, naRef* args)
33 {
34     naRef a = naNumValue(argc > 0 ? args[0] : naNil());
35     if(naIsNil(a))
36         naRuntimeError(c, "non numeric argument to cos()");
37     a.num = cos(a.num);
38     return VALIDATE(a);
39 }
40
41 static naRef f_exp(naContext c, naRef me, int argc, naRef* args)
42 {
43     naRef a = naNumValue(argc > 0 ? args[0] : naNil());
44     if(naIsNil(a))
45         naRuntimeError(c, "non numeric argument to exp()");
46     a.num = exp(a.num);
47     return VALIDATE(a);
48 }
49
50 static naRef f_ln(naContext c, naRef me, int argc, naRef* args)
51 {
52     naRef a = naNumValue(argc > 0 ? args[0] : naNil());
53     if(naIsNil(a))
54         naRuntimeError(c, "non numeric argument to ln()");
55     a.num = log(a.num);
56     return VALIDATE(a);
57 }
58
59 static naRef f_sqrt(naContext c, naRef me, int argc, naRef* args)
60 {
61     naRef a = naNumValue(argc > 0 ? args[0] : naNil());
62     if(naIsNil(a))
63         naRuntimeError(c, "non numeric argument to sqrt()");
64     a.num = sqrt(a.num);
65     return VALIDATE(a);
66 }
67
68 static naRef f_atan2(naContext c, naRef me, int argc, naRef* args)
69 {
70     naRef a = naNumValue(argc > 0 ? args[0] : naNil());
71     naRef b = naNumValue(argc > 1 ? args[1] : naNil());
72     if(naIsNil(a) || naIsNil(b))
73         naRuntimeError(c, "non numeric argument to atan2()");
74     a.num = atan2(a.num, b.num);
75     return VALIDATE(a);
76 }
77
78 static naCFuncItem funcs[] = {
79     { "sin", f_sin },
80     { "cos", f_cos },
81     { "exp", f_exp },
82     { "ln", f_ln },
83     { "sqrt", f_sqrt },
84     { "atan2", f_atan2 },
85     { 0 }
86 };
87
88 naRef naInit_math(naContext c)
89 {
90     naRef ns = naGenLib(c, funcs);
91     naAddSym(c, ns, "pi", naNum(3.14159265358979323846));
92     naAddSym(c, ns, "e", naNum(2.7182818284590452354));
93     return ns;
94 }