From e2283f6c7f5abc60dc7ba7ea59deee94da714da7 Mon Sep 17 00:00:00 2001 From: lemon Date: Sat, 8 Oct 2022 11:08:42 +0200 Subject: initial commit --- pez.h | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 pez.h (limited to 'pez.h') 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 +#include +#include +#include + +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 -- cgit v1.2.3