-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathbmath.c
116 lines (94 loc) · 4.42 KB
/
bmath.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include <math.h>
#include <time.h>
#include "bstring.h"
#include "berror.h"
#include "bparser.h"
#include "bmath.h"
#ifndef M_PI
define M_PI 3.14159265358979323846
#endif
#define single(action, arg) do { \
assert_with_message(argc >= 1 && ttisnumber(&args[0]), "Please provide a number operand."); \
TValue * ret = TV_MALLOC; \
double val = nvalue(arg); \
setnvalue(ret, action(val)); \
return ret; \
} while(0);
#define binary(action, args) do { \
assert_with_message(argc >= 2 && ttisnumber(&args[0]) && ttisnumber(&args[1]), "Please provide two number operand."); \
TValue * ret = TV_MALLOC; \
double val1 = nvalue(&args[0]); \
double val2 = nvalue(&args[1]); \
setnvalue(ret, action(val1, val2)); \
return ret; \
} while(0);
static TValue * primitive_Math_ceil(bean_State * B, TValue * thisVal UNUSED, TValue * args, int argc) {
single(ceil, &args[0]);
}
static TValue * primitive_Math_floor(bean_State * B, TValue * thisVal UNUSED, TValue * args, int argc) {
single(floor, &args[0]);
}
static TValue * primitive_Math_round(bean_State * B, TValue * thisVal UNUSED, TValue * args, int argc) {
single(round, &args[0]);
}
static TValue * primitive_Math_sin(bean_State * B, TValue * thisVal UNUSED, TValue * args, int argc) {
single(sin, &args[0]);
}
static TValue * primitive_Math_cos(bean_State * B, TValue * thisVal UNUSED, TValue * args, int argc) {
single(cos, &args[0]);
}
static TValue * primitive_Math_abs(bean_State * B, TValue * thisVal UNUSED, TValue * args, int argc) {
single(fabs, &args[0]);
}
static TValue * primitive_Math_sqrt(bean_State * B, TValue * thisVal UNUSED, TValue * args, int argc) {
single(sqrt, &args[0]);
}
static TValue * primitive_Math_log(bean_State * B, TValue * thisVal UNUSED, TValue * args, int argc) {
single(log, &args[0]);
}
static TValue * primitive_Math_exp(bean_State * B, TValue * thisVal UNUSED, TValue * args, int argc) {
single(exp, &args[0]);
}
static TValue * primitive_Math_random(bean_State * B, TValue * thisVal UNUSED, TValue * args UNUSED, int argc UNUSED) {
TValue * ret = TV_MALLOC;
setnvalue(ret, (double)rand() / 0x7fffffff);
return ret;
}
static TValue * primitive_Math_max(bean_State * B, TValue * thisVal UNUSED, TValue * args, int argc UNUSED) {
binary(fmax, args);
}
static TValue * primitive_Math_min(bean_State * B, TValue * thisVal UNUSED, TValue * args, int argc UNUSED) {
binary(fmin, args);
}
static TValue * primitive_Math_pow(bean_State * B, TValue * thisVal UNUSED, TValue * args, int argc UNUSED) {
binary(pow, args);
}
TValue * init_Math(bean_State * B) {
srand(time(0));
global_State * G = B->l_G;
TValue * proto = TV_MALLOC;
Hash * h = init_hash(B);
sethashvalue(proto, h);
set_prototype_function(B, "ceil", 4, primitive_Math_ceil, hhvalue(proto));
set_prototype_function(B, "floor", 5, primitive_Math_floor, hhvalue(proto));
set_prototype_function(B, "round", 5, primitive_Math_round, hhvalue(proto));
set_prototype_function(B, "sin", 3, primitive_Math_sin, hhvalue(proto));
set_prototype_function(B, "cos", 3, primitive_Math_cos, hhvalue(proto));
set_prototype_function(B, "abs", 3, primitive_Math_abs, hhvalue(proto));
set_prototype_function(B, "sqrt", 4, primitive_Math_sqrt, hhvalue(proto));
set_prototype_function(B, "log", 3, primitive_Math_log, hhvalue(proto));
set_prototype_function(B, "exp", 3, primitive_Math_exp, hhvalue(proto));
set_prototype_function(B, "random", 6, primitive_Math_random, hhvalue(proto));
set_prototype_function(B, "min", 3, primitive_Math_min, hhvalue(proto));
set_prototype_function(B, "max", 3, primitive_Math_max, hhvalue(proto));
set_prototype_function(B, "pow", 3, primitive_Math_pow, hhvalue(proto));
TValue * pi = TV_MALLOC;
setsvalue(pi, beanS_newlstr(B, "PI", 2));
TValue * pi_v = TV_MALLOC;
setnvalue(pi_v, M_PI);
hash_set(B, hhvalue(proto), pi, pi_v);
TValue * math = TV_MALLOC;
setsvalue(math, beanS_newlstr(B, "Math", 4));
hash_set(B, G->globalScope->variables, math, proto);
return proto;
}