summaryrefslogtreecommitdiff
path: root/pez.c
diff options
context:
space:
mode:
Diffstat (limited to 'pez.c')
-rw-r--r--pez.c45
1 files changed, 31 insertions, 14 deletions
diff --git a/pez.c b/pez.c
index 098b2ff..98f7d08 100644
--- a/pez.c
+++ b/pez.c
@@ -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 {