summaryrefslogtreecommitdiff
path: root/pez.c
diff options
context:
space:
mode:
Diffstat (limited to 'pez.c')
-rw-r--r--pez.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/pez.c b/pez.c
index 3f64b28..e12ad46 100644
--- a/pez.c
+++ b/pez.c
@@ -9,6 +9,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <math.h>
#ifdef __GNUC__
#define FORCEINLINE __attribute__((always_inline))
@@ -2406,6 +2407,63 @@ f_ioclose(PezContext *cx, int argc)
return 1;
}
+static bool
+f_abs(PezContext *cx, int argc)
+{
+ PezNumber n;
+ TRY(pez_checksig(cx, argc, "abs", "number"));
+ pez_getnumber(cx, &n, -1);
+ return pez_pushnumber(cx, n < 0 ? -n : n);
+}
+
+static bool
+f_sqrt(PezContext *cx, int argc)
+{
+ PezNumber n;
+ TRY(pez_checksig(cx, argc, "sqrt", "number"));
+ pez_getnumber(cx, &n, -1);
+ return pez_pushnumber(cx, pez_ftonum(sqrtf(pez_numtof(n))));
+}
+
+static PezNumber
+xsin(PezNumber x)
+{
+ static uint16_t lut[4096];
+ PezNumber t;
+ bool neg;
+
+ if (!lut[8]) {
+ for (int i = 0; i <= 0xFFF; ++i) {
+ double f = (double)i * M_PI / 0x1000;
+ lut[i] = sin(f) * 0x1000;
+ }
+ }
+ if ((neg = x < 0)) x = -x;
+ t = lut[x&0xFFF];
+ if (x % FX(2) > FX(1)) t = -t;
+ return neg ? -t : t;
+}
+
+static bool
+f_xsin(PezContext *cx, int argc)
+{
+
+ PezNumber n;
+ TRY(pez_checksig(cx, argc, "xsin", "number"));
+ pez_getnumber(cx, &n, -1);
+ return pez_pushnumber(cx, xsin(n));
+}
+
+static bool
+f_xcos(PezContext *cx, int argc)
+{
+
+ PezNumber n;
+ TRY(pez_checksig(cx, argc, "xcos", "number"));
+ pez_getnumber(cx, &n, -1);
+ return pez_pushnumber(cx, xsin(n + 0x800));
+}
+
static const struct coredef { const char *n; PezCFn *f; } core[] = {
{ "printf", f_printf },
{ "sprintf", f_sprintf },
@@ -2419,6 +2477,10 @@ static const struct coredef { const char *n; PezCFn *f; } core[] = {
{ "io#read", f_ioread },
{ "io#write", f_iowrite },
{ "io#close", f_ioclose },
+ { "abs", f_abs },
+ { "sqrt", f_sqrt },
+ { "xsin", f_xsin },
+ { "xcos", f_xcos },
};
static bool