1
4
5
28
29# include <luametatex.h>
30
31# define POSIT_METATABLE "posit number"
32
33static inline 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
40static inline 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
61static inline 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
72static inline 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 posit a = positlib_get(L, 1);
339 posit p = positlib_push(L);
340 if (lua_gettop(L) == 1) {
341 *p = double_to_posit(log(posit_to_double(*a)));
342 } else {
343 posit b = positlib_get(L, 2);
344 double d = posit_to_double(*a);
345 double n = posit_to_double(*b);
346 if (n == 10.0) {
347 n = (lua_Number) log10(d);
348 } else if (n == 2.0) {
349 n = (lua_Number) log2(d);
350 } else {
351 n = (lua_Number) log(d) / (lua_Number) log(n);
352 }
353 *p = double_to_posit(n);
354 }
355 return 1;
356}
357
358static int positlib_exp(lua_State *L)
359{
360 posit a = positlib_get(L, 1);
361 posit p = positlib_push(L);
362 *p = double_to_posit(exp(posit_to_double(*a)));
363 return 1;
364}
365
366static int positlib_exp2(lua_State *L)
367{
368 posit a = positlib_get(L, 1);
369 posit p = positlib_push(L);
370 *p = double_to_posit(exp2(posit_to_double(*a)));
371 return 1;
372}
373
374static int positlib_ceil(lua_State *L)
375{
376 posit a = positlib_get(L, 1);
377 posit p = positlib_push(L);
378 *p = double_to_posit(ceil(posit_to_double(*a)));
379 return 1;
380}
381
382static int positlib_floor(lua_State *L)
383{
384 posit a = positlib_get(L, 1);
385 posit p = positlib_push(L);
386 *p = double_to_posit(floor(posit_to_double(*a)));
387 return 1;
388}
389
390static int positlib_modf(lua_State *L)
391{
392 posit a = positlib_get(L, 1);
393 posit p = positlib_push(L);
394 posit q = positlib_push(L);
395 double d;
396 *q = double_to_posit(modf(posit_to_double(*a),&d));
397 *p = double_to_posit(d);
398 return 2;
399}
400
401static int positlib_sin(lua_State *L)
402{
403 posit a = positlib_get(L, 1);
404 posit p = positlib_push(L);
405 *p = double_to_posit(sin(posit_to_double(*a)));
406 return 1;
407}
408
409static int positlib_cos(lua_State *L)
410{
411 posit a = positlib_get(L, 1);
412 posit p = positlib_push(L);
413 *p = double_to_posit(cos(posit_to_double(*a)));
414 return 1;
415}
416
417static int positlib_tan(lua_State *L)
418{
419 posit a = positlib_get(L, 1);
420 posit p = positlib_push(L);
421 *p = double_to_posit(tan(posit_to_double(*a)));
422 return 1;
423}
424
425static int positlib_asin(lua_State *L)
426{
427 posit a = positlib_get(L, 1);
428 posit p = positlib_push(L);
429 *p = double_to_posit(asin(posit_to_double(*a)));
430 return 1;
431}
432
433static int positlib_acos(lua_State *L)
434{
435 posit a = positlib_get(L, 1);
436 posit p = positlib_push(L);
437 *p = double_to_posit(acos(posit_to_double(*a)));
438 return 1;
439}
440
441static int positlib_atan(lua_State *L)
442{
443 posit a = positlib_get(L, 1);
444 posit p = positlib_push(L);
445 *p = double_to_posit(atan(posit_to_double(*a)));
446 return 1;
447}
448
449static int positlib_rotate(lua_State *L)
450{
451 posit a = positlib_get(L, 1);
452 lua_Integer n = luaL_optinteger(L, 2, 1);
453 posit p = positlib_push(L);
454 if (n > 0) {
455 p->v = (a->v >> n) | (a->v << (posit_bits - n));
456 } else if (n < 0) {
457 p->v = (a->v << n) | (a->v >> (posit_bits - n));
458 } else {
459 p->v = a->v;
460 }
461 return 1;
462}
463
464static int positlib_shift(lua_State *L)
465{
466 posit a = positlib_get(L, 1);
467 lua_Integer shift = luaL_optinteger(L, 2, 1);
468 posit p = positlib_push(L);
469 if (shift > 0) {
470 p->v = (a->v >> shift) & 0xFFFFFFFF;
471 } else if (shift < 0) {
472 p->v = (a->v << -shift) & 0xFFFFFFFF;
473 } else {
474 p->v = a->v;
475 }
476 return 1;
477}
478
479static int positlib_left(lua_State *L)
480{
481 posit a = positlib_get(L, 1);
482 lua_Integer shift = luaL_optinteger(L, 2, 1);
483 posit p = positlib_push(L);
484 p->v = (a->v << shift) & 0xFFFFFFFF;
485 return 1;
486}
487
488static int positlib_right(lua_State *L)
489{
490 posit_t *a = positlib_get(L, 1);
491 lua_Integer shift = - luaL_optinteger(L, 2, 1);
492 posit_t *p = positlib_push(L);
493 p->v = (a->v >> shift) & 0xFFFFFFFF;
494 return 1;
495}
496
497static int positlib_and(lua_State *L)
498{
499 posit a = positlib_get(L, 1);
500 posit b = positlib_get(L, 2);
501 posit p = positlib_push(L);
502 p->v = (a->v) & (b->v);
503 return 1;
504}
505
506static int positlib_or(lua_State *L)
507{
508 posit a = positlib_get(L, 1);
509 posit b = positlib_get(L, 2);
510 posit p = positlib_push(L);
511 p->v = (a->v) | (b->v);
512 return 1;
513}
514
515static int positlib_xor(lua_State *L)
516{
517 posit a = positlib_get(L, 1);
518 posit b = positlib_get(L, 2);
519 posit p = positlib_push(L);
520 p->v = (a->v) ^ (b->v);
521 return 1;
522}
523
524static const luaL_Reg positlib_function_list[] =
525{
526
527 { "new", positlib_new },
528 { "copy", positlib_copy },
529 { "tostring", positlib_tostring },
530 { "tonumber", positlib_tonumber },
531 { "integer", positlib_integer },
532 { "rounded", positlib_rounded },
533 { "toposit", positlib_toposit },
534 { "fromposit", positlib_fromposit },
535
536 { "__add", positlib_add },
537
538 { "__div", positlib_div },
539
540 { "__eq", positlib_eq },
541 { "__le", positlib_le },
542 { "__lt", positlib_lt },
543 { "__mul", positlib_mul },
544 { "__sub", positlib_sub },
545 { "__unm", positlib_neg },
546 { "__pow", positlib_pow },
547 { "__bor", positlib_or },
548 { "__bxor", positlib_xor },
549 { "__band", positlib_and },
550 { "__shl", positlib_left },
551 { "__shr", positlib_right },
552
553 { "NaN", positlib_NaN },
554 { "NaR", positlib_NaR },
555
556 { "bor", positlib_or },
557 { "bxor", positlib_xor },
558 { "band", positlib_and },
559 { "shift", positlib_shift },
560 { "rotate", positlib_rotate },
561
562 { "min", positlib_min },
563 { "max", positlib_max },
564 { "abs", positlib_abs },
565 { "conj", positlib_neg },
566 { "modf", positlib_modf },
567
568 { "acos", positlib_acos },
569
570 { "asin", positlib_asin },
571
572 { "atan", positlib_atan },
573
574
575
576 { "ceil", positlib_ceil },
577
578 { "cos", positlib_cos },
579
580
581
582
583 { "exp", positlib_exp },
584 { "exp2", positlib_exp2 },
585
586
587
588 { "floor", positlib_floor },
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605 { "log", positlib_log },
606 { "log10", positlib_log10 },
607 { "log1p", positlib_log1p },
608 { "log2", positlib_log2 },
609 { "logb", positlib_logb },
610
611
612
613 { "pow", positlib_pow },
614
615
616
617 { "round", positlib_round },
618
619 { "sin", positlib_sin },
620
621 { "sqrt", positlib_sqrt },
622 { "tan", positlib_tan },
623
624
625
626
627
628
629
630 { NULL, NULL },
631};
632
633int luaopen_posit(lua_State *L)
634{
635 luaL_newmetatable(L, POSIT_METATABLE);
636 luaL_setfuncs(L, positlib_function_list, 0);
637 lua_pushliteral(L, "__index");
638 lua_pushvalue(L, -2);
639 lua_settable(L, -3);
640 lua_pushliteral(L, "__tostring");
641 lua_pushliteral(L, "tostring");
642 lua_gettable(L, -3);
643 lua_settable(L, -3);
644 lua_pushliteral(L, "__name");
645 lua_pushliteral(L, "posit");
646 lua_settable(L, -3);
647 return 1;
648}
649 |