summaryrefslogtreecommitdiff
path: root/pez.h
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2022-10-08 11:08:42 +0200
committerlemon <lsof@mailbox.org>2022-10-08 11:08:42 +0200
commite2283f6c7f5abc60dc7ba7ea59deee94da714da7 (patch)
treeb007ad4820b016ec90c614b218c5e529560e1d8f /pez.h
initial commit
Diffstat (limited to 'pez.h')
-rw-r--r--pez.h124
1 files changed, 124 insertions, 0 deletions
diff --git a/pez.h b/pez.h
new file mode 100644
index 0000000..063905c
--- /dev/null
+++ b/pez.h
@@ -0,0 +1,124 @@
+#ifndef PEZ_H_
+#define PEZ_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdio.h>
+
+typedef int32_t PezNumber;
+
+enum {
+ PEZ_TVoid,
+ PEZ_TObject,
+ PEZ_TNumber,
+ PEZ_TBool,
+ PEZ_TString,
+ PEZ_TFn,
+ PEZ_TTuple,
+ PEZ_TRecord,
+ PEZ_TArray,
+};
+
+typedef enum PezError {
+ PEZ_EStack = 1,
+ PEZ_ENoMem,
+ PEZ_ESyntax,
+ PEZ_ERuntime,
+} PezError;
+
+
+typedef struct PezContext PezContext;
+typedef void *PezAllocFn(void *userdata, void *ptr, size_t oldsize, size_t newsize);
+typedef bool PezCFn(PezContext *, int argc);
+
+PezContext *pez_new(PezAllocFn *alloc, void *userdata);
+void pez_del(PezContext *);
+
+/*
+ * opts:
+ * NULL -> reset debug options
+ * 'b': enable print bytecode to stderr
+ */
+void pez_debug(PezContext *, const char *opts);
+
+int pez_geterrno(PezContext *);
+const char *pez_geterr(PezContext *cx);
+
+bool pez_eval_cb(PezContext *, const char *fname, int (*cb)(void *), void *);
+bool pez_eval_str(PezContext *, const char *fname, const char *);
+bool pez_eval_file(PezContext *, const char *path, FILE *);
+
+int pez_top(PezContext *);
+
+void pez_pop(PezContext *cx);
+bool pez_push(PezContext *cx, int idx);
+bool pez_pushvoid(PezContext *cx);
+bool pez_pushnumber(PezContext *, PezNumber);
+bool pez_pushint(PezContext *, int);
+bool pez_pushstring(PezContext *, const char *str, int len);
+bool pez_pushglobal(PezContext *, const char *name);
+
+bool pez_isvoid(PezContext *, int idx);
+bool pez_isnumber(PezContext *, int idx);
+bool pez_isbool(PezContext *, int idx);
+bool pez_isstring(PezContext *, int idx);
+bool pez_isfunction(PezContext *, int idx);
+bool pez_isarray(PezContext *, int idx);
+const char *pez_typename(PezContext *, int idx);
+
+bool pez_getnumber(PezContext *, PezNumber *, int idx);
+bool pez_getbool(PezContext *, bool *, int idx);
+const char *pez_getstring(PezContext *, char buf[8], int idx);
+const char *pez_fnname(PezContext *, int idx);
+int pez_length(PezContext *cx, int idx);
+
+void pez_error(PezContext *cx, const char *fn, const char *fmt, ...);
+
+bool pez_apply(PezContext *cx, int argc);
+bool pez_setapply(PezContext *cx, int argc);
+bool pez_iget(PezContext *cx, int idx, int arg);
+
+static inline double
+pez_numtof(PezNumber x) { return x / 4096.0; }
+
+static inline PezNumber
+pez_ftonum(double x) { return x * 4096.0; }
+
+static inline PezNumber
+pez_fixmul(PezNumber a, PezNumber b)
+{
+ int64_t tmp = (int64_t)a * b;
+ // tmp += (1 << 11); // rounding
+ return tmp >> 12;
+}
+
+static inline PezNumber
+pez_fixdiv(PezNumber a, PezNumber b)
+{
+ if (b == 0) {
+ return a >= 0 ? INT32_MAX : INT32_MIN;
+ }
+ int64_t tmp = (uint64_t)a << 12;
+ /*
+ if ((tmp < 0) == (b < 0)) {
+ tmp += b >> 1;
+ } else {
+ tmp -= b >> 1;
+ }
+ */
+ return tmp / b;
+}
+
+static inline PezNumber
+pez_fixmod(PezNumber a, PezNumber b)
+{
+ if (b == 0) {
+ return 0;
+ } else if (b < 0) {
+ return -a % -b;
+ }
+ return a % b;
+}
+
+#endif