1
4
5
28
29# include <luametatex.h>
30
31# define POSIT_METATABLE "posit number"
32
33inline static posit_t *positlib_push(lua_State *L)
34{
35 posit p = lua_newuserdatauv(L, sizeof(posit_t), 0);
36 luaL_setmetatable(L, POSIT_METATABLE);
37 return p;
38}
39
40inline static int positlib_new(lua_State *L)
41{
42 posit p = positlib_push(L);
43 switch (lua_type(L, 1)) {
44 case LUA_TSTRING:
45 *p = double_to_posit(lua_tonumber(L, 1));
46 break;
47 case LUA_TNUMBER:
48 if (lua_isinteger(L, 1)) {
49 *p = i64_to_posit(lua_tointeger(L, 1));
50 } else {
51 *p = double_to_posit(lua_tonumber(L, 1));
52 }
53 break;
54 default:
55 p->v = 0;
56 break;
57 }
58 return 1;
59}
60
61inline static int positlib_toposit(lua_State *L)
62{
63 if (lua_type(L, 1) == LUA_TNUMBER) {
64 posit_t p = double_to_posit(lua_tonumber(L, 1));
65 lua_pushinteger(L, p.v);
66 } else {
67 lua_pushinteger(L, 0);
68 }
69 return 1;
70}
71
72inline static int positlib_fromposit(lua_State *L)
73{
74 if (lua_type(L, 1) == LUA_TNUMBER) {
75 posit_t p = { .v = lmt_roundnumber(L, 1) };
76 lua_pushnumber(L, posit_to_double(p));
77 } else {
78 lua_pushinteger(L, 0);
79 }
80 return 1;
81}
82
83
87
88static posit_t *positlib_get(lua_State *L, int i)
89{
90 switch (lua_type(L, i)) {
91 case LUA_TUSERDATA:
92 return (posit) luaL_checkudata(L, i, POSIT_METATABLE);
93 case LUA_TSTRING:
94 {
95 posit p = positlib_push(L);
96 *p = double_to_posit(lua_tonumber(L, i));
97 lua_replace(L, i);
98 return p;
99 }
100 case LUA_TNUMBER:
101 {
102 posit p = positlib_push(L);
103 *p = lua_isinteger(L, i) ? integer_to_posit(lua_tointeger(L, i)) : double_to_posit(lua_tonumber(L, i));
104 lua_replace(L, i);
105 return p;
106 }
107 default:
108 {
109 posit p = positlib_push(L);
110 lua_replace(L, i);
111 return p;
112 }
113 }
114}
115
116static int positlib_tostring(lua_State *L)
117{
118 posit p = positlib_get(L, 1);
119 double d = posit_to_double(*p);
120 lua_pushnumber(L, d);
121 lua_tostring(L, -1);
122 return 1;
123}
124
125
126static int positlib_tonumber(lua_State *L)
127{
128 posit p = positlib_get(L, 1);
129 double d = posit_to_double(*p);
130 lua_pushnumber(L, d);
131 return 1;
132}
133
134static int positlib_copy(lua_State *L)
135{
136 posit a = positlib_get(L, 1);
137 posit p = positlib_push(L);
138 *p = *a;
139 return 1;
140}
141
142static int positlib_eq(lua_State *L)
143{
144 posit a = positlib_get(L, 1);
145 posit b = positlib_get(L, 2);
146 lua_pushboolean(L, posit_eq(*a, *b));
147 return 1;
148}
149
150static int positlib_le(lua_State *L)
151{
152 posit a = positlib_get(L, 1);
153 posit b = positlib_get(L, 2);
154 lua_pushboolean(L, posit_le(*a, *b));
155 return 1;
156}
157
158static int positlib_lt(lua_State *L)
159{
160 posit a = positlib_get(L, 1);
161 posit b = positlib_get(L, 2);
162 lua_pushboolean(L, posit_lt(*a, *b));
163 return 1;
164}
165
166static int positlib_add(lua_State *L)
167{
168 posit a = positlib_get(L, 1);
169 posit b = positlib_get(L, 2);
170 posit p = positlib_push(L);
171 *p = posit_add(*a, *b);
172 return 1;
173}
174
175static int positlib_sub(lua_State *L)
176{
177 posit a = positlib_get(L, 1);
178 posit b = positlib_get(L, 2);
179 posit p = positlib_push(L);
180 *p = posit_sub(*a, *b);
181 return 1;
182}
183
184static int positlib_mul(lua_State *L)
185{
186 posit a = positlib_get(L, 1);
187 posit b = positlib_get(L, 2);
188 posit p = positlib_push(L);
189 *p = posit_mul(*a, *b);
190 return 1;
191}
192
193static int positlib_div(lua_State *L) {
194 posit a = positlib_get(L, 1);
195 posit b = positlib_get(L, 2);
196 posit p = positlib_push(L);
197 *p = posit_div(*a, *b);
198 return 1;
199}
200
201static int positlib_round(lua_State *L)
202{
203 posit a = positlib_get(L, 1);
204 posit p = positlib_push(L);
205 *p = posit_round_to_integer(*a);
206 return 1;
207}
208
209static int positlib_rounded(lua_State *L)
210{
211 posit a = positlib_get(L, 1);
212 lua_pushinteger(L, posit_to_integer(*a));
213 return 1;
214}
215
216static int positlib_integer(lua_State *L)
217{
218 posit p = positlib_get(L, 1);
219 lua_pushinteger(L, (lua_Integer) posit_to_i64(*p));
220 return 1;
221}
222
223static int positlib_NaN(lua_State *L)
224{
225 posit p = positlib_get(L, 1);
226 lua_pushboolean(L, p->v == (uint32_t) 0x80000000);
227 return 1;
228}
229
230static int positlib_NaR(lua_State *L)
231{
232 posit p = positlib_get(L, 1);
233 lua_pushboolean(L, posit_is_NaR(p->v));
234 return 1;
235}
236
237
238
239
240
241
242
243
244
245static int positlib_neg(lua_State* L)
246{
247 posit a = positlib_get(L, 1);
248 posit p = positlib_push(L);
249 *p = posit_neg(*a);
250 return 1;
251}
252
253static int positlib_min(lua_State *L)
254{
255 posit a = positlib_get(L, 1);
256 posit b = positlib_get(L, 2);
257 posit p = positlib_push(L);
258 *p = posit_lt(*a, *b) ? *a : *b;
259 return 1;
260}
261
262static int positlib_max(lua_State *L)
263{
264 posit a = positlib_get(L, 1);
265 posit b = positlib_get(L, 2);
266 posit p = positlib_push(L);
267 *p = posit_lt(*a, *b) ? *b : *a;
268 return 1;
269}
270
271static int positlib_pow(lua_State *L)
272{
273 posit a = positlib_get(L, 1);
274 posit b = positlib_get(L, 1);
275 posit p = positlib_push(L);
276 *p = double_to_posit(pow(posit_to_double(*a),posit_to_double(*b)));
277 return 1;
278}
279
280static int positlib_abs(lua_State *L)
281{
282 posit a = positlib_get(L, 1);
283 posit p = positlib_push(L);
284 *p = posit_abs(*a);
285 return 1;
286}
287
288static int positlib_sqrt(lua_State *L)
289{
290 posit a = positlib_get(L, 1);
291 posit p = positlib_push(L);
292 *p = posit_sqrt(*a);
293 return 1;
294}
295
296
297
298
299
300
301
302
303
304static int positlib_log10(lua_State *L)
305{
306 posit a = positlib_get(L, 1);
307 posit p = positlib_push(L);
308 *p = double_to_posit(log10(posit_to_double(*a)));
309 return 1;
310}
311
312static int positlib_log1p(lua_State *L)
313{
314 posit a = positlib_get(L, 1);
315 posit p = positlib_push(L);
316 *p = double_to_posit(log1p(posit_to_double(*a)));
317 return 1;
318}
319
320static int positlib_log2(lua_State *L)
321{
322 posit a = positlib_get(L, 1);
323 posit p = positlib_push(L);
324 *p = double_to_posit(log2(posit_to_double(*a)));
325 return 1;
326}
327
328static int positlib_logb(lua_State *L)
329{
330 posit a = positlib_get(L, 1);
331 posit p = positlib_push(L);
332 *p = double_to_posit(logb(posit_to_double(*a)));
333 return 1;
334}
335
336static int positlib_log(lua_State *L)
337{
338 if (lua_gettop(L) == 1) {
339 posit a = positlib_get(L, 1);
340 posit p = positlib_push(L);
341 *p = double_to_posit(log(posit_to_double(*a)));
342 } else {
343 posit a = positlib_get(L, 1);
344 posit b = positlib_get(L, 2);
345 posit p = positlib_push(L);
346 double d = posit_to_double(*a);
347 double n = posit_to_double(*b);
348 if (n == 10.0) {
349 n = (lua_Number) log10(d);
350 } else if (n == 2.0) {
351 n = (lua_Number) log2(d);
352 } else {
353 n = (lua_Number) log(d) / (lua_Number) log(n);
354 }
355 *p = double_to_posit(n);
356 }
357 return 1;
358}
359
360static int positlib_exp(lua_State *L)
361{
362 posit a = positlib_get(L, 1);
363 posit p = positlib_push(L);
364 *p = double_to_posit(exp(posit_to_double(*a)));
365 return 1;
366}
367
368static int positlib_exp2(lua_State *L)
369{
370 posit a = positlib_get(L, 1);
371 posit p = positlib_push(L);
372 *p = double_to_posit(exp2(posit_to_double(*a)));
373 return 1;
374}
375
376static int positlib_ceil(lua_State *L)
377{
378 posit a = positlib_get(L, 1);
379 posit p = positlib_push(L);
380 *p = double_to_posit(ceil(posit_to_double(*a)));
381 return 1;
382}
383
384static int positlib_floor(lua_State *L)
385{
386 posit a = positlib_get(L, 1);
387 posit p = positlib_push(L);
388 *p = double_to_posit(floor(posit_to_double(*a)));
389 return 1;
390}
391
392static int positlib_modf(lua_State *L)
393{
394 posit a = positlib_get(L, 1);
395 posit p = positlib_push(L);
396 posit q = positlib_push(L);
397 double d;
398 *q = double_to_posit(modf(posit_to_double(*a),&d));
399 *p = double_to_posit(d);
400 return 2;
401}
402
403static int positlib_sin(lua_State *L)
404{
405 posit a = positlib_get(L, 1);
406 posit p = positlib_push(L);
407 *p = double_to_posit(sin(posit_to_double(*a)));
408 return 1;
409}
410
411static int positlib_cos(lua_State *L)
412{
413 posit a = positlib_get(L, 1);
414 posit p = positlib_push(L);
415 *p = double_to_posit(cos(posit_to_double(*a)));
416 return 1;
417}
418
419static int positlib_tan(lua_State *L)
420{
421 posit a = positlib_get(L, 1);
422 posit p = positlib_push(L);
423 *p = double_to_posit(tan(posit_to_double(*a)));
424 return 1;
425}
426
427static int positlib_asin(lua_State *L)
428{
429 posit a = positlib_get(L, 1);
430 posit p = positlib_push(L);
431 *p = double_to_posit(asin(posit_to_double(*a)));
432 return 1;
433}
434
435static int positlib_acos(lua_State *L)
436{
437 posit a = positlib_get(L, 1);
438 posit p = positlib_push(L);
439 *p = double_to_posit(acos(posit_to_double(*a)));
440 return 1;
441}
442
443static int positlib_atan(lua_State *L)
444{
445 posit a = positlib_get(L, 1);
446 posit p = positlib_push(L);
447 *p = double_to_posit(atan(posit_to_double(*a)));
448 return 1;
449}
450
451static int positlib_rotate(lua_State *L)
452{
453 posit a = positlib_get(L, 1);
454 lua_Integer n = luaL_optinteger(L, 2, 1);
455 posit p = positlib_push(L);
456 if (n > 0) {
457 p->v = (a->v >> n) | (a->v << (posit_bits - n));
458 } else if (n < 0) {
459 p->v = (a->v << n) | (a->v >> (posit_bits - n));
460 } else {
461 p->v = a->v;
462 }
463 return 1;
464}
465
466static int positlib_shift(lua_State *L)
467{
468 posit a = positlib_get(L, 1);
469 lua_Integer shift = luaL_optinteger(L, 2, 1);
470 posit p = positlib_push(L);
471 if (shift > 0) {
472 p->v = (a->v >> shift) & 0xFFFFFFFF;
473 } else if (shift < 0) {
474 p->v = (a->v << -shift) & 0xFFFFFFFF;
475 } else {
476 p->v = a->v;
477 }
478 return 1;
479}
480
481static int positlib_left(lua_State *L)
482{
483 posit a = positlib_get(L, 1);
484 lua_Integer shift = luaL_optinteger(L, 2, 1);
485 posit p = positlib_push(L);
486 p->v = (a->v << shift) & 0xFFFFFFFF;
487 return 1;
488}
489
490static int positlib_right(lua_State *L)
491{
492 posit_t *a = positlib_get(L, 1);
493 lua_Integer shift = - luaL_optinteger(L, 2, 1);
494 posit_t *p = positlib_push(L);
495 p->v = (a->v >> shift) & 0xFFFFFFFF;
496 return 1;
497}
498
499static int positlib_and(lua_State *L)
500{
501 posit a = positlib_get(L, 1);
502 posit b = positlib_get(L, 2);
503 posit p = positlib_push(L);
504 p->v = (a->v) & (b->v);
505 return 1;
506}
507
508static int positlib_or(lua_State *L)
509{
510 posit a = positlib_get(L, 1);
511 posit b = positlib_get(L, 2);
512 posit p = positlib_push(L);
513 p->v = (a->v) | (b->v);
514 return 1;
515}
516
517static int positlib_xor(lua_State *L)
518{
519 posit a = positlib_get(L, 1);
520 posit b = positlib_get(L, 2);
521 posit p = positlib_push(L);
522 p->v = (a->v) ^ (b->v);
523 return 1;
524}
525
526static const luaL_Reg positlib_function_list[] =
527{
528
529 { "new", positlib_new },
530 { "copy", positlib_copy },
531 { "tostring", positlib_tostring },
532 { "tonumber", positlib_tonumber },
533 { "integer", positlib_integer },
534 { "rounded", positlib_rounded },
535 { "toposit", positlib_toposit },
536 { "fromposit", positlib_fromposit },
537
538 { "__add", positlib_add },
539
540 { "__div", positlib_div },
541
542 { "__eq", positlib_eq },
543 { "__le", positlib_le },
544 { "__lt", positlib_lt },
545 { "__mul", positlib_mul },
546 { "__sub", positlib_sub },
547 { "__unm", positlib_neg },
548 { "__pow", positlib_pow },
549 { "__bor", positlib_or },
550 { "__bxor", positlib_xor },
551 { "__band", positlib_and },
552 { "__shl", positlib_left },
553 { "__shr", positlib_right },
554
555 { "NaN", positlib_NaN },
556 { "NaR", positlib_NaR },
557
558 { "bor", positlib_or },
559 { "bxor", positlib_xor },
560 { "band", positlib_and },
561 { "shift", positlib_shift },
562 { "rotate", positlib_rotate },
563
564 { "min", positlib_min },
565 { "max", positlib_max },
566 { "abs", positlib_abs },
567 { "conj", positlib_neg },
568 { "modf", positlib_modf },
569
570 { "acos", positlib_acos },
571
572 { "asin", positlib_asin },
573
574 { "atan", positlib_atan },
575
576
577
578 { "ceil", positlib_ceil },
579
580 { "cos", positlib_cos },
581
582
583
584
585 { "exp", positlib_exp },
586 { "exp2", positlib_exp2 },
587
588
589
590 { "floor", positlib_floor },
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607 { "log", positlib_log },
608 { "log10", positlib_log10 },
609 { "log1p", positlib_log1p },
610 { "log2", positlib_log2 },
611 { "logb", positlib_logb },
612
613
614
615 { "pow", positlib_pow },
616
617
618
619 { "round", positlib_round },
620
621 { "sin", positlib_sin },
622
623 { "sqrt", positlib_sqrt },
624 { "tan", positlib_tan },
625
626
627
628
629
630
631
632 { NULL, NULL },
633};
634
635int luaopen_posit(lua_State *L)
636{
637 luaL_newmetatable(L, POSIT_METATABLE);
638 luaL_setfuncs(L, positlib_function_list, 0);
639 lua_pushliteral(L, "__index");
640 lua_pushvalue(L, -2);
641 lua_settable(L, -3);
642 lua_pushliteral(L, "__tostring");
643 lua_pushliteral(L, "tostring");
644 lua_gettable(L, -3);
645 lua_settable(L, -3);
646 lua_pushliteral(L, "__name");
647 lua_pushliteral(L, "posit");
648 lua_settable(L, -3);
649 return 1;
650}
651 |