summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bench.lua2
-rw-r--r--pez.c45
-rw-r--r--pez.h3
-rw-r--r--pez.pngbin0 -> 11408 bytes
-rw-r--r--test.pez1
-rw-r--r--ycomb.pez5
6 files changed, 39 insertions, 17 deletions
diff --git a/bench.lua b/bench.lua
index 18e8116..b653cc9 100644
--- a/bench.lua
+++ b/bench.lua
@@ -1,4 +1,4 @@
-function fib(n)
+local function fib(n)
if n < 2 then return n end
return fib(n - 2) + fib(n - 1)
end
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 {
diff --git a/pez.h b/pez.h
index 081634b..2330f1b 100644
--- a/pez.h
+++ b/pez.h
@@ -33,6 +33,7 @@ typedef enum PezError {
typedef struct PezContext PezContext;
typedef void *PezAllocFn(void *userdata, void *ptr, size_t oldsize, size_t newsize);
typedef bool PezCFn(PezContext *, int argc);
+typedef int PezReadFn(void *userdata, char *dst, int n);
PezContext *pez_new(PezAllocFn *alloc, void *userdata, size_t stacksize);
void pez_del(PezContext *);
@@ -49,7 +50,7 @@ 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_cb(PezContext *, const char *fname, PezReadFn cb, void *);
bool pez_eval_str(PezContext *, const char *fname, const char *);
bool pez_eval_file(PezContext *, const char *path, FILE *);
diff --git a/pez.png b/pez.png
new file mode 100644
index 0000000..e415103
--- /dev/null
+++ b/pez.png
Binary files differ
diff --git a/test.pez b/test.pez
index 7f35b30..cd7d608 100644
--- a/test.pez
+++ b/test.pez
@@ -34,7 +34,6 @@ printf["%a == %a\n", m[3,7], 3^7]
acc
}
-
printf["4+1+3: %a\n", add[4,1,3]]
@gather: {[*]
diff --git a/ycomb.pez b/ycomb.pez
new file mode 100644
index 0000000..dff0f40
--- /dev/null
+++ b/ycomb.pez
@@ -0,0 +1,5 @@
+@Y: {[f] {[i] i[i]}[{[i] f[{[x] i[i][x]}]}]}
+
+@fact: {[n] Y[{[f] {[n] n == 0 ? 1 : n * f[n - 1]}}][n]}
+
+printf["%a\n", fact[5]]