diff options
Diffstat (limited to 'pez.h')
| -rw-r--r-- | pez.h | 124 |
1 files changed, 124 insertions, 0 deletions
@@ -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 |