diff options
Diffstat (limited to 'pez.c')
| -rw-r--r-- | pez.c | 45 |
1 files changed, 31 insertions, 14 deletions
@@ -131,8 +131,10 @@ struct cmupval { typedef struct Comp { PezContext *cx; - int (*readcb)(void *); + PezReadFn *readcb; void *readud; + char rdbuf[1024]; + uint rdbufi, rdbufsiz; uint line, col; int peekchr; bool have_peekchr; @@ -2236,7 +2238,7 @@ initcore(PezContext *cx) /*******************/ static void -initcomp(Comp *cm, PezContext *cx, Proto *pr, int (*cb)(void *), void *ud) +initcomp(Comp *cm, PezContext *cx, Proto *pr, PezReadFn cb, void *ud) { memset(cm, 0, sizeof *cm); cm->cx = cx; @@ -2547,12 +2549,21 @@ endscope(Comp *cm) static int nextchr(Comp *cm) { - int c; + int c, n; if (cm->have_peekchr) { cm->have_peekchr = 0; return cm->peekchr; } - c = cm->readcb(cm->readud); + if (cm->rdbufsiz == 0) { + cm->rdbufi = 0; + if ((n = cm->readcb(cm->readud, cm->rdbuf, sizeof cm->rdbuf)) <= 0) + return EOF; + assert(n <= sizeof cm->rdbuf); + cm->rdbufsiz = n; + } + c = cm->rdbuf[cm->rdbufi++]; + cm->rdbufi %= sizeof cm->rdbuf; + --cm->rdbufsiz; if (c == '\n') { ++cm->line; cm->col = 0; @@ -3998,13 +4009,13 @@ block(Comp *cm, int endchr) /**************/ bool -pez_eval_cb(PezContext *cx, const char *fname, int (*cb)(void *), void *ud) +pez_eval_cb(PezContext *cx, const char *fname, PezReadFn cb, void *ud) { Val *stktop = cx->stktop; Proto *pr; Fn *fn; - struct fenv fenv = {0}; Comp cm; + struct fenv fenv = {0}; int gccanrun = cx->gccanrun; cx->gccanrun = 0; if (!(pr = newproto(cx, fname, "<eval>", /* line */ 1))) { @@ -4046,15 +4057,14 @@ Err: } static int -str_read_cb(void *ud) +str_read_cb(void *ud, char *dst, int n) { + int i; char **s = ud; - char c = **s; - if (c == 0) { - return EOF; + for (i = 0; **s && n > 0; ++i) { + *dst++ = *(*s)++; } - ++*s; - return c; + return i; } bool @@ -4064,10 +4074,17 @@ pez_eval_str(PezContext *cx, const char *fname, const char *str) return pez_eval_cb(cx, fname, str_read_cb, &str); } +static int +file_read_cb(void *ud, char *dst, int n) +{ + FILE *fp = ud; + return fread(dst, 1, n, fp); +} + bool pez_eval_file(PezContext *cx, const char *fname, FILE *fp) { assert(fp); - return pez_eval_cb(cx, fname, (int(*)(void *))fgetc, fp); + return pez_eval_cb(cx, fname, file_read_cb, fp); } static void * @@ -4327,7 +4344,7 @@ pez_checksig(PezContext *cx, int argc, const char *fn, const char *sig) for (; *sig; ++arg) { uint mask = 0; const char *this = sig; - int thisn; + int thisn = 0; int typ; typ = 1 << pez_typeof(cx, -argc + arg); do { |