1
21
22# include "luametatex.h"
23
24# include <complex.h>
25
26# define COMPLEX_METATABLE "complex number"
27
28# if (_MSC_VER)
29
30
34
35 # define Complex _Dcomplex
36
37 inline static Complex xcomplexlib_get(lua_State *L, int i)
38 {
39 switch (lua_type(L, i)) {
40 case LUA_TUSERDATA:
41 return *((Complex*) luaL_checkudata(L, i, COMPLEX_METATABLE));
42 case LUA_TNUMBER:
43 case LUA_TSTRING:
44 return _Cbuild(luaL_checknumber(L, i), 0);
45 default:
46 return _Cbuild(0, 0);
47 }
48 }
49
50# else
51
52
55
56 # define Complex double complex
57
58 inline static Complex xcomplexlib_get(lua_State *L, int i)
59 {
60 switch (lua_type(L, i)) {
61 case LUA_TUSERDATA:
62 return *((Complex*)luaL_checkudata(L, i, COMPLEX_METATABLE));
63 case LUA_TNUMBER:
64 case LUA_TSTRING:
65 return luaL_checknumber(L, i);
66 default:
67 return 0;
68 }
69 }
70
71# endif
72
73inline static int xcomplexlib_push(lua_State *L, Complex z)
74{
75 Complex *p = lua_newuserdatauv(L, sizeof(Complex), 0);
76 luaL_setmetatable(L, COMPLEX_METATABLE);
77 *p = z;
78 return 1;
79}
80
81# if (_MSC_VER)
82
83 static int xcomplexlib_new(lua_State *L)
84 {
85 xcomplexlib_push(L, _Cbuild(0, 0));
86 return 1;
87 }
88
89 static int xcomplexlib_inew(lua_State *L)
90 {
91 xcomplexlib_push(L, _Cbuild(0, 1));
92 return 1;
93 }
94
95 static int xcomplexlib_eq(lua_State *L)
96 {
97 Complex a = xcomplexlib_get(L, 1);
98 Complex b = xcomplexlib_get(L, 2);
99 lua_pushboolean(L, creal(a) == creal(b) && cimag(a) == cimag(b));
100 return 1;
101 }
102
103 static int xcomplexlib_add(lua_State *L) {
104 Complex a = xcomplexlib_get(L, 1);
105 Complex b = xcomplexlib_get(L, 2);
106 return xcomplexlib_push(L, _Cbuild(creal(a) + creal(b), cimag(a) + cimag(b)));
107 }
108
109 static int xcomplexlib_sub(lua_State *L) {
110 Complex a = xcomplexlib_get(L, 1);
111 Complex b = xcomplexlib_get(L, 2);
112 return xcomplexlib_push(L, _Cbuild(creal(a) - creal(b), cimag(a) - cimag(b)));
113 }
114
115 static int xcomplexlib_neg(lua_State *L) {
116 Complex a = xcomplexlib_get(L, 1);
117 return xcomplexlib_push(L, _Cbuild(-creal(a), -cimag(a)));
118 }
119
120 static int xcomplexlib_div(lua_State *L) {
121 Complex b = xcomplexlib_get(L, 2);
122 if (creal(b) == 0.0 || cimag(b) == 0.0) {
123 return 0;
124 } else {
125 Complex a = xcomplexlib_get(L, 1);
126 Complex t = { 1 / creal(b), 1 / cimag(b) };
127 return xcomplexlib_push(L, _Cmulcc(a, t));
128 }
129 }
130
131 static int xcomplexlib_mul(lua_State *L) {
132 Complex a = xcomplexlib_get(L, 1);
133 Complex b = xcomplexlib_get(L, 2);
134 return xcomplexlib_push(L, _Cmulcc(a, b));
135 }
136
137# else
138
139 static int xcomplexlib_new(lua_State *L)
140 {
141 return xcomplexlib_push(L, luaL_optnumber(L, 1, 0) + luaL_optnumber(L, 2, 0) * I);
142 }
143
144 static int xcomplexlib_inew(lua_State *L)
145 {
146 return xcomplexlib_push(L, I);
147 }
148
149 static int xcomplexlib_eq(lua_State *L)
150 {
151 lua_pushboolean(L, xcomplexlib_get(L, 1) == xcomplexlib_get(L, 2));
152 return 1;
153 }
154
155 static int xcomplexlib_add(lua_State *L)
156 {
157 return xcomplexlib_push(L, xcomplexlib_get(L, 1) + xcomplexlib_get(L, 2));
158 }
159
160 static int xcomplexlib_sub(lua_State *L)
161 {
162 return xcomplexlib_push(L, xcomplexlib_get(L, 1) - xcomplexlib_get(L, 2));
163 }
164
165 static int xcomplexlib_neg(lua_State *L)
166 {
167 return xcomplexlib_push(L, - xcomplexlib_get(L, 1));
168 }
169
170 static int xcomplexlib_div(lua_State *L)
171 {
172 return xcomplexlib_push(L, xcomplexlib_get(L, 1) / xcomplexlib_get(L, 2));
173 }
174
175 static int xcomplexlib_mul(lua_State *L)
176 {
177 return xcomplexlib_push(L, xcomplexlib_get(L, 1) * xcomplexlib_get(L, 2));
178 }
179
180# endif
181
182static int xcomplexlib_abs(lua_State *L)
183{
184 lua_pushnumber(L, (lua_Number) cabs(xcomplexlib_get(L, 1)));
185 return 1;
186}
187
188static int xcomplexlib_acos(lua_State *L)
189{
190 return xcomplexlib_push(L, cacos(xcomplexlib_get(L, 1)));
191}
192
193static int xcomplexlib_acosh(lua_State *L)
194{
195 return xcomplexlib_push(L, cacosh(xcomplexlib_get(L, 1)));
196}
197
198static int xcomplexlib_arg(lua_State *L)
199{
200 lua_pushnumber(L, (lua_Number) carg(xcomplexlib_get(L, 1)));
201 return 1;
202}
203
204static int xcomplexlib_asin(lua_State *L)
205{
206 return xcomplexlib_push(L, casin(xcomplexlib_get(L, 1)));
207}
208
209static int xcomplexlib_asinh(lua_State *L)
210{
211 return xcomplexlib_push(L, casinh(xcomplexlib_get(L, 1)));
212}
213
214static int xcomplexlib_atan(lua_State *L)
215{
216 return xcomplexlib_push(L, catan(xcomplexlib_get(L, 1)));
217}
218
219static int xcomplexlib_atanh(lua_State *L)
220{
221 return xcomplexlib_push(L, catanh(xcomplexlib_get(L, 1)));
222}
223
224static int xcomplexlib_cos(lua_State *L)
225{
226 return xcomplexlib_push(L, ccos(xcomplexlib_get(L, 1)));
227}
228
229static int xcomplexlib_cosh(lua_State *L)
230{
231 return xcomplexlib_push(L, ccosh(xcomplexlib_get(L, 1)));
232}
233
234static int xcomplexlib_exp(lua_State *L)
235{
236 xcomplexlib_push(L, cexp(xcomplexlib_get(L, 1)));
237 return 1;
238}
239
240static int xcomplexlib_imag(lua_State *L) {
241 lua_pushnumber(L, (lua_Number) (cimag)(xcomplexlib_get(L, 1)));
242 return 1;
243}
244
245static int xcomplexlib_log(lua_State *L)
246{
247 return xcomplexlib_push(L, clog(xcomplexlib_get(L, 1)));
248}
249
250static int xcomplexlib_pow(lua_State *L)
251{
252 return xcomplexlib_push(L, cpow(xcomplexlib_get(L, 1), xcomplexlib_get(L, 2)));
253}
254
255static int xcomplexlib_proj(lua_State *L)
256{
257 return xcomplexlib_push(L, cproj(xcomplexlib_get(L, 1)));
258}
259
260static int xcomplexlib_real(lua_State *L)
261{
262 lua_pushnumber(L, (lua_Number) creal(xcomplexlib_get(L, 1)));
263 return 1;
264}
265
266static int xcomplexlib_sin(lua_State *L)
267{
268 return xcomplexlib_push(L, csin(xcomplexlib_get(L, 1)));
269}
270
271static int xcomplexlib_sinh(lua_State *L)
272{
273 return xcomplexlib_push(L, csinh(xcomplexlib_get(L, 1)));
274}
275
276static int xcomplexlib_sqrt(lua_State *L)
277{
278 return xcomplexlib_push(L, csqrt(xcomplexlib_get(L, 1)));
279}
280
281static int xcomplexlib_tan(lua_State *L)
282{
283 return xcomplexlib_push(L, ctan(xcomplexlib_get(L, 1)));
284}
285
286static int xcomplexlib_tanh(lua_State *L)
287{
288 return xcomplexlib_push(L, ctanh(xcomplexlib_get(L, 1)));
289}
290
291
292
293static int xcomplexlib_tostring(lua_State *L)
294{
295 Complex z = xcomplexlib_get(L, 1);
296 lua_Number x = creal(z);
297 lua_Number y = cimag(z);
298 lua_settop(L, 0);
299 if (x != 0.0 || y == 0.0) {
300 lua_pushnumber(L, x);
301 }
302 if (y != 0.0) {
303 if (y == 1.0) {
304 if (x != 0.0) {
305 lua_pushliteral(L, "+");
306 }
307 } else if (y == -1.0) {
308 lua_pushliteral(L, "-");
309 } else {
310 if (y > 0.0 && x != 0.0) {
311 lua_pushliteral(L, "+");
312 }
313 lua_pushnumber(L, y);
314 }
315 lua_pushliteral(L, "i");
316 }
317 lua_concat(L, lua_gettop(L));
318 return 1;
319}
320
321static int xcomplexlib_topair(lua_State *L)
322{
323 Complex z = xcomplexlib_get(L, 1);
324 lua_pushnumber(L, (lua_Number) creal(z));
325 lua_pushnumber(L, (lua_Number) cimag(z));
326 return 2;
327}
328
329static int xcomplexlib_totable(lua_State *L)
330{
331 Complex z = xcomplexlib_get(L, 1);
332 lua_createtable(L, 2, 0);
333 lua_pushnumber(L, (lua_Number) creal(z));
334 lua_pushnumber(L, (lua_Number) cimag(z));
335 lua_rawseti(L, -3, 1);
336 lua_rawseti(L, -3, 2);
337 return 1;
338}
339
340
341
342static const struct luaL_Reg xcomplexlib_function_list[] = {
343
344 { "new", xcomplexlib_new },
345 { "tostring", xcomplexlib_tostring },
346 { "topair", xcomplexlib_topair },
347 { "totable", xcomplexlib_totable },
348 { "i", xcomplexlib_inew },
349
350 { "__add", xcomplexlib_add },
351 { "__div", xcomplexlib_div },
352 { "__eq", xcomplexlib_eq },
353 { "__mul", xcomplexlib_mul },
354 { "__sub", xcomplexlib_sub },
355 { "__unm", xcomplexlib_neg },
356 { "__pow", xcomplexlib_pow },
357
358 { "abs", xcomplexlib_abs },
359 { "acos", xcomplexlib_acos },
360 { "acosh", xcomplexlib_acosh },
361 { "arg", xcomplexlib_arg },
362 { "asin", xcomplexlib_asin },
363 { "asinh", xcomplexlib_asinh },
364 { "atan", xcomplexlib_atan },
365 { "atanh", xcomplexlib_atanh },
366 { "conj", xcomplexlib_neg },
367 { "cos", xcomplexlib_cos },
368 { "cosh", xcomplexlib_cosh },
369 { "exp", xcomplexlib_exp },
370 { "imag", xcomplexlib_imag },
371 { "log", xcomplexlib_log },
372 { "pow", xcomplexlib_pow },
373 { "proj", xcomplexlib_proj },
374 { "real", xcomplexlib_real },
375 { "sin", xcomplexlib_sin },
376 { "sinh", xcomplexlib_sinh },
377 { "sqrt", xcomplexlib_sqrt },
378 { "tan", xcomplexlib_tan },
379 { "tanh", xcomplexlib_tanh },
380
381 { NULL, NULL },
382};
383
384int luaopen_xcomplex(lua_State *L)
385{
386 luaL_newmetatable(L, COMPLEX_METATABLE);
387 luaL_setfuncs(L, xcomplexlib_function_list, 0);
388 lua_pushliteral(L, "__index");
389 lua_pushvalue(L, -2);
390 lua_settable(L, -3);
391 lua_pushliteral(L, "__tostring");
392 lua_pushliteral(L, "tostring");
393 lua_gettable(L, -3);
394 lua_settable(L, -3);
395 lua_pushliteral(L, "I");
396 lua_pushliteral(L, "i");
397 lua_gettable(L, -3);
398 lua_settable(L, -3);
399 lua_pushliteral(L, "__name");
400 lua_pushliteral(L, "complex");
401 lua_settable(L, -3);
402 return 1;
403}
404 |