summaryrefslogtreecommitdiff
path: root/pez.c
diff options
context:
space:
mode:
Diffstat (limited to 'pez.c')
-rw-r--r--pez.c350
1 files changed, 202 insertions, 148 deletions
diff --git a/pez.c b/pez.c
index e34d5b0..3f72b14 100644
--- a/pez.c
+++ b/pez.c
@@ -28,9 +28,9 @@ typedef struct Val {
uint64_t r;
} Val;
-#define vec_of(T) struct { \
- T *at; \
- uint len, cap; \
+#define vec_of(T, Ninl) struct { \
+ T *at, inl[Ninl]; \
+ uint len, cap; \
}
typedef struct Obj Obj;
@@ -42,7 +42,7 @@ struct Obj {
typedef struct Str {
OBJHEADER;
- uint n;
+ uint len;
char dat[];
} Str;
@@ -53,7 +53,8 @@ typedef struct Tuple {
typedef struct Array {
OBJHEADER;
- vec_of(Val);
+ uint len, cap;
+ Val *dat;
} Array;
struct KV { Val k, v; };
@@ -106,10 +107,23 @@ typedef struct Dilambda {
Fn *getf, *setf;
} Dilambda;
-typedef struct Local Local;
-
enum { NAMEMAX = 80 };
+struct local {
+ uint16_t scope : 15;
+ uint16_t has_k : 1;
+ uint16_t sref; // name
+ union {
+ uint16_t kref; // when has_k
+ struct {
+ uint16_t index : 10,
+ isparam : 1,
+ mutable : 1,
+ captured : 1;
+ };
+ };
+};
+
struct cmupval {
uint8_t idx;
bool arg : 1, local : 1;
@@ -123,14 +137,14 @@ typedef struct Comp {
int peekchr;
bool have_peekchr;
char stash_ident[NAMEMAX];
- Local *stash_local;
+ struct local *stash_local;
char stash_binopk;
char stash_binopchr;
int stash_binopop;
Proto *proto;
- vec_of(uint8_t) code;
- vec_of(Val) con;
+ vec_of(uint8_t, 16) code;
+ vec_of(Val, 2) con;
Val k; /* for constant folding */
bool has_k;
@@ -141,30 +155,18 @@ typedef struct Comp {
lvalue_const : 1;
const char *lvalue_name;
- vec_of(char) spool; // for var names
- vec_of(Val) kpool; // for consts
+ vec_of(char, 16) spool; // for var names
+ vec_of(Val, 4) kpool; // for consts
struct fenv {
const char *name;
struct fenv *prev;
- vec_of(Local) locals; // also params
+ vec_of(struct local, 32) locals; // also params
uint16_t scope;
uint16_t nvars; // num of locals in scope not counting konsts
- uint16_t nupval;
- struct cmupval upvals[256];
- } fenv;
+ vec_of(struct cmupval, 32) upvals;
+ } *fenv;
} Comp;
-struct Local {
- uint16_t scope;
- uint16_t sref; // name
- uint16_t kref; // when has_k
- uint16_t index : 10;
- uint16_t isparam : 1,
- has_k : 1,
- mutable : 1,
- captured : 1;
-};
-
static struct Str strpool_deleted;
typedef struct StrPool {
uint count, deleted, N;
@@ -328,59 +330,97 @@ cxrealloc(PezContext *cx, void *p, size_t osz, size_t sz)
}
-static inline void *
+static inline void * FORCEINLINE
cxalloc(PezContext *cx, size_t sz)
{
return cxrealloc(cx, NULL, 0, sz);
}
-static inline void
+static inline void FORCEINLINE
cxfree(PezContext *cx, void *p, size_t sz)
{
cxrealloc(cx, p, sz, 0);
}
-#define delvec(cx, v) \
- (void)((v)->at ? cxfree(cx, (v)->at, (v)->cap * sizeof *(v)->at) : (void)0, \
+#define delvec(cx, v) \
+ (void)((v)->at && (v)->at != (v)->inl ? \
+ cxfree(cx, (v)->at, (v)->cap * sizeof *(v)->at) \
+ : (void)0, \
(v)->at = 0, (v)->cap = (v)->len = 0)
#define vecempty(v) ((v)->len == 0)
-#define vecpush(cx, v, src, n) \
- _vecpush(cx, (void **)&(v)->at, sizeof *(v)->at, \
- &(v)->len, &(v)->cap, (src), (n))
-
+#define vecpush(cx, v, src, n) \
+ _vecpush(cx, (void **)&(v)->at, (void *)(v)->inl, sizeof(v)->inl/sizeof(v)->inl[0], \
+ sizeof *(v)->at, &(v)->len, &(v)->cap, (src), (n))
+#define vecmove(cx, plen, v) \
+ _vecmove(cx, plen, (void **)&(v)->at, (void *)(v)->inl, sizeof(v)->inl/sizeof(v)->inl[0], \
+ sizeof *(v)->at, &(v)->len, &(v)->cap)
#define veclast(v) (&(v)->at[(v)->len - 1])
-static bool
-_vecpush(PezContext *cx, void **at, size_t sz,
+static inline bool FORCEINLINE
+_vecpush(PezContext *cx, void **at, void *inl, uint Ninl, size_t sz,
uint *len, uint *cap, const void *src, size_t n)
{
if (cx->gccanrun && (cx->dbg & DBGstressgc)) {
gc(cx);
}
- if (*len + n - 1 >= *cap) {
+
+
+ if (!(*at && *at != inl) && *len + n <= Ninl) {
+ *at = inl;
+ *cap = *len + n;
+ } else if (*len + n - 1 >= *cap) {
uint newcap = (*len + n - 1) * 2;
uint8_t *new;
newcap = newcap < 4 ? 4 : newcap;
- new = cxrealloc(cx, *at, *cap * sz, newcap * sz);
+ if (*at == inl) {
+ new = cxalloc(cx, newcap * sz);
+ } else {
+ new = cxrealloc(cx, *at, *cap * sz, newcap * sz);
+ }
if (!new) {
- if (*at) {
+ if (*at && *at != inl) {
cxfree(cx, *at, *cap * sz);
}
*at = NULL;
*len = *cap = 0;
return 0;
}
+ if (*at == inl) {
+ memcpy(new, inl, Ninl * sz);
+ }
*at = new;
*cap = newcap;
}
+ assert(*at);
memcpy((char *)*at + *len * sz, src, n * sz);
*len += n;
return 1;
}
static void *
+_vecmove(PezContext *cx, uint *plen, void **at, void *inl, uint Ninl, size_t sz, uint *len, uint *cap)
+{
+ void *p = NULL;
+ *plen = *len;
+ if (!*len) {
+ return NULL;
+ }
+ if (*at == inl) {
+ assert(*len <= Ninl);
+ p = cxalloc(cx, *len * sz);
+ memcpy(p, inl, *len * sz);
+ } else {
+ p = cxrealloc(cx, *at, *cap * sz, *len * sz);
+ }
+ *at = NULL;
+ memset(inl, 0, Ninl * sz);
+ *len = *cap = 0;
+ return p;
+}
+
+static void *
newobj(PezContext *cx, int type, size_t sz)
{
Obj *o = cxalloc(cx, sz);
@@ -477,7 +517,7 @@ delproto(PezContext *cx, Proto *pr)
}
}
-static void
+static inline void FORCEINLINE
closeups(PezContext *cx, Val *ptr)
{
for (Upval *up = cx->openup, *prev = NULL, *next; up; up = next) {
@@ -651,7 +691,7 @@ strpool_lookup(PezContext *cx, const char *str, int len)
if (!s0 || s0 == &strpool_deleted) {
continue;
}
- h = fnv1a(FNV1A_INI, s0->dat, s0->n);
+ h = fnv1a(FNV1A_INI, s0->dat, s0->len);
for (idx = h & (pool->N - 1);; idx = (idx + 1) & (pool->N - 1)) {
if (!new[idx]) {
new[idx] = s0;
@@ -666,7 +706,7 @@ strpool_lookup(PezContext *cx, const char *str, int len)
h = fnv1a(FNV1A_INI, str, len);
for (idx = h & (pool->N - 1);; idx = (idx + 1) & (pool->N - 1)) {
Str *s = pool->dat[idx];
- if (!s || (s != &strpool_deleted && s->n == len && !memcmp(s->dat, str, len))) {
+ if (!s || (s != &strpool_deleted && s->len == len && !memcmp(s->dat, str, len))) {
return &pool->dat[idx];
}
}
@@ -690,7 +730,7 @@ box_str(PezContext *cx, Val *pv, const char *s, int len)
if (!o) {
return 0;
}
- o->n = len;
+ o->len = len;
memcpy(o->dat, s, len + 1);
*slot = o;
++cx->strpool.count;
@@ -702,7 +742,7 @@ box_str(PezContext *cx, Val *pv, const char *s, int len)
static inline size_t
sizeofstr(Str *str)
{
- return sizeof(*str) + str->n + 1;
+ return sizeof(*str) + str->len + 1;
}
static Array *
@@ -717,7 +757,7 @@ newarr(PezContext *cx, uint cap)
cxfree(cx, arr, sizeof *arr);
return NULL;
}
- arr->at = cxalloc(cx, cap * sizeof(Val));
+ arr->dat = cxalloc(cx, cap * sizeof(Val));
arr->cap = cap;
pop(cx);
}
@@ -727,20 +767,47 @@ newarr(PezContext *cx, uint cap)
static bool
arrpushn(PezContext *cx, Array *arr, Val *src, uint n)
{
- return n == 0 ? 1 : vecpush(cx, arr, src, n);
+ if (n > 0) {
+ if (cx->gccanrun && (cx->dbg & DBGstressgc)) {
+ gc(cx);
+ }
+ if (arr->len + n - 1 >= arr->cap) {
+ uint newcap = (arr->len + n - 1) * 2;
+ Val *new;
+ newcap = newcap < 4 ? 4 : newcap;
+ new = cxrealloc(cx, arr->dat, arr->cap * sizeof(Val), newcap * sizeof(Val));
+ if (!new) {
+ if (arr->dat) {
+ cxfree(cx, arr->dat, arr->cap * sizeof(Val));
+ }
+ arr->dat = NULL;
+ arr->len = arr->cap = 0;
+ return 0;
+ }
+ arr->dat = new;
+ arr->cap = newcap;
+ }
+ memcpy(arr->dat + arr->len, src, n * sizeof(Val));
+ arr->len += n;
+ }
+ return 1;
}
static void
delarray(PezContext *cx, Array *arr)
{
- delvec(cx, arr);
+ if (arr->dat) {
+ cxfree(cx, arr->dat, arr->cap * sizeof(Val));
+ arr->dat = NULL;
+ }
+ arr->len = arr->cap = 0;
}
static void
delstring(PezContext *cx, Str *str)
{
uint N = cx->strpool.N;
- for (uint i = fnv1a(FNV1A_INI, str->dat, str->n) & (N - 1);; i = (i + 1) & (N - 1)) {
+ for (uint i = fnv1a(FNV1A_INI, str->dat, str->len) & (N - 1);; i = (i + 1) & (N - 1)) {
Str **slot = &cx->strpool.dat[i];
if (*slot == str) {
*slot = NULL;
@@ -829,8 +896,8 @@ static void
markarray(PezContext *cx, Array *arr)
{
for (uint i = 0; i < arr->len; ++i) {
- if (isobj(arr->at[i])) {
- gcmark(cx, unbox_obj(arr->at[i]));
+ if (isobj(arr->dat[i])) {
+ gcmark(cx, unbox_obj(arr->dat[i]));
}
}
}
@@ -1169,7 +1236,7 @@ inspectproto(Proto *pr)
assert(*argp < pr->ncon);
v = pr->con[*argp];
assert(isobj_of(v, PEZ_TString));
- inspectstr(((Str *)unbox_obj(v))->dat, ((Str *)unbox_obj(v))->n);
+ inspectstr(((Str *)unbox_obj(v))->dat, ((Str *)unbox_obj(v))->len);
break;
case Olambda:
++ip;
@@ -1316,7 +1383,7 @@ apply(PezContext *cx, Val *ret, void *srcfn, int srcpc, Val recv, uint n)
return 1;
}
TRY(checkindex(cx, &idx, srcfn, srcpc, "array", arr->len, arg));
- *ret = arr->at[idx];
+ *ret = arr->dat[idx];
} else if (issstr(recv) || isobj_of(recv, PEZ_TString)) {
char buf[8];
const char *str;
@@ -1325,7 +1392,7 @@ apply(PezContext *cx, Val *ret, void *srcfn, int srcpc, Val recv, uint n)
len = unbox_sstr(recv, buf);
str = buf;
} else {
- len = ((Str *)unbox_obj(recv))->n;
+ len = ((Str *)unbox_obj(recv))->len;
str = ((Str *)unbox_obj(recv))->dat;
}
if (n != 1) {
@@ -1374,7 +1441,7 @@ setapply(PezContext *cx, Val *ret, void *srcfn, int srcpc, Val recv, uint n, Val
return runerr(cx, srcfn, srcpc, "cannot mutate array length"), 0;
}
TRY(checkindex(cx, &idx, srcfn, srcpc, "array", arr->len, arg));
- *ret = arr->at[idx] = rval;
+ *ret = arr->dat[idx] = rval;
} else if (issstr(recv) || isobj_of(recv, PEZ_TString)) {
return runerr(cx, srcfn, srcpc, "cannot mutate string"), 0;
} else {
@@ -1783,7 +1850,7 @@ exefn(PezContext *cx, Fn *fn, uint nargs)
/* Core functions */
/******************/
-struct vals { vec_of(Val); };
+struct vals { vec_of(Val, 2); };
static bool
xprint1(PezContext *cx, struct vals *seen,
bool (*cb)(PezContext *, void *, const char *, uint), void *u, Val v)
@@ -1814,7 +1881,7 @@ xprint1(PezContext *cx, struct vals *seen,
len = unbox_sstr(v, buf);
str = buf;
} else {
- len = ((Str *)unbox_obj(v))->n;
+ len = ((Str *)unbox_obj(v))->len;
str = ((Str *)unbox_obj(v))->dat;
}
ok &= cb(cx, u, "\"", 1);
@@ -1858,7 +1925,7 @@ xprint1(PezContext *cx, struct vals *seen,
TRY(vecpush(cx, seen, &v, 1));
ok &= cb(cx, u, "#[", 2);
for (uint i = 0; i < arr->len; ++i) {
- ok &= xprint1(cx, seen, cb, u, arr->at[i]);
+ ok &= xprint1(cx, seen, cb, u, arr->dat[i]);
if (i != arr->len - 1) {
ok &= cb(cx, u, ", ", 2);
}
@@ -1943,14 +2010,14 @@ f_printf(PezContext *cx, int argc)
static bool
printtostr(PezContext *cx, void *V, const char *d, uint n)
{
- vec_of(char) *v = V;
+ vec_of(char, 100) *v = V;
return vecpush(cx, v, d, n);
}
static bool
f_sprintf(PezContext *cx, int argc)
{
- vec_of(char) s = {0};
+ vec_of(char, 100) s = {0};
ETRY(f_xprintf1(cx, "sprintf", printtostr, &s, argc));
ETRY(pez_pushstring(cx, s.at, s.len));
delvec(cx, &s);
@@ -1988,7 +2055,7 @@ f_arrayfill(PezContext *cx, int argc)
TRY(arr = newarr(cx, fixtoint(n)));
arr->len = fixtoint(n);
for (int i = 0; i < fixtoint(n); ++i) {
- arr->at[i] = cx->stktop[-1];
+ arr->dat[i] = cx->stktop[-1];
}
return push(cx, box_obj(arr));
}
@@ -2045,12 +2112,13 @@ static void
delfenv(PezContext *cx, struct fenv *fenv)
{
delvec(cx, &fenv->locals);
+ delvec(cx, &fenv->upvals);
}
static void
deinitcomp(Comp *cm)
{
- delfenv(cm->cx, &cm->fenv);
+ delfenv(cm->cx, cm->fenv);
delvec(cm->cx, &cm->code);
delvec(cm->cx, &cm->spool);
delvec(cm->cx, &cm->kpool);
@@ -2060,19 +2128,19 @@ static bool
fincompfn(Comp *cm)
{
Proto *pr = cm->proto;
- const uint8_t *code = cxrealloc(cm->cx, cm->code.at, cm->code.cap, cm->code.len);
- const Val *con = cxrealloc(cm->cx, cm->con.at,
- cm->con.cap * sizeof(Val), cm->con.len * sizeof(Val));
- assert(code != NULL && (cm->con.len == 0 || con != NULL) && "can't shrink?");
+ uint ncode, ncon;
+ const uint8_t *code = vecmove(cm->cx, &ncode, &cm->code);
+ const Val *con = vecmove(cm->cx, &ncon, &cm->con);
+ assert(code != NULL && (ncon == 0 || con != NULL) && "can't shrink?");
pr->lineend = cm->line;
pr->code = code;
- pr->ncode = cm->code.len;
+ pr->ncode = ncode;
pr->con = con;
- pr->ncon = cm->con.len;
+ pr->ncon = ncon;
pr->upval = NULL;
- if ((pr->nupval = cm->fenv.nupval) != 0) {
- pr->upval = cxalloc(cm->cx, cm->fenv.nupval * sizeof *pr->upval);
- memcpy(pr->upval, cm->fenv.upvals, pr->nupval * sizeof(struct cmupval));
+ if ((pr->nupval = cm->fenv->upvals.len) != 0) {
+ pr->upval = cxalloc(cm->cx, cm->fenv->upvals.len * sizeof *pr->upval);
+ memcpy(pr->upval, cm->fenv->upvals.at, pr->nupval * sizeof(struct cmupval));
}
memset(&cm->code, 0, sizeof cm->code);
memset(&cm->con, 0, sizeof cm->con);
@@ -2194,11 +2262,11 @@ resetlastops(Comp *cm)
static bool
addparam(Comp *cm, const char *name)
{
- struct fenv *fenv = &cm->fenv;
- Local l = { .sref = cm->spool.len,
- .scope = fenv->scope,
- .isparam = 1,
- .mutable = 1 };
+ struct fenv *fenv = cm->fenv;
+ struct local l = { .sref = cm->spool.len,
+ .scope = fenv->scope,
+ .isparam = 1,
+ .mutable = 1 };
assert(l.scope == 0);
assert(l.sref == cm->spool.len);
TRY(vecpush(cm->cx, &cm->spool, name, strlen(name) + 1));
@@ -2210,23 +2278,22 @@ addparam(Comp *cm, const char *name)
static void
beginscope(Comp *cm)
{
- ++cm->fenv.scope;
+ ++cm->fenv->scope;
}
-static Local *
+static struct local *
addlocal(Comp *cm, uint *idx, const char *name, bool mutable, bool has_k, Val k)
{
- struct fenv *fenv = &cm->fenv;
- Local l = { .sref = cm->spool.len,
- .scope = fenv->scope,
- .kref = cm->kpool.len,
- .has_k = has_k,
- .mutable = mutable, };
+ struct fenv *fenv = cm->fenv;
+ struct local l = { .sref = cm->spool.len,
+ .scope = fenv->scope,
+ .has_k = has_k,
+ .mutable = mutable, };
assert(l.scope > 0);
if (l.sref != cm->spool.len) {
return comperr(cm, *name, "locals name pool overflow"), NULL;
}
- if (has_k && l.kref != cm->kpool.len) {
+ if (has_k && (l.kref = cm->kpool.len) != cm->kpool.len) {
return comperr(cm, *name, "constants pool overflow"), NULL;
}
TRY(vecpush(cm->cx, &cm->spool, name, strlen(name) + 1));
@@ -2245,19 +2312,19 @@ addlocal(Comp *cm, uint *idx, const char *name, bool mutable, bool has_k, Val k)
return veclast(&fenv->locals);
}
-static Local *
+static struct local *
findlocal(Comp *cm, const char *name)
{
- for (int i = cm->fenv.locals.len - 1; i >= 0; --i) {
- Local *l = &cm->fenv.locals.at[i];
+ for (int i = cm->fenv->locals.len - 1; i >= 0; --i) {
+ struct local *l = &cm->fenv->locals.at[i];
if (!strcmp(&cm->spool.at[l->sref], name)) {
return l;
}
}
// search for foldablable consts in enclosing functions
- for (struct fenv *fenv = cm->fenv.prev; fenv; fenv = fenv->prev) {
+ for (struct fenv *fenv = cm->fenv->prev; fenv; fenv = fenv->prev) {
for (int i = fenv->locals.len - 1; i >= 0; --i) {
- Local *l = &fenv->locals.at[i];
+ struct local *l = &fenv->locals.at[i];
if (l->has_k && !strcmp(&cm->spool.at[l->sref], name)) {
return l;
}
@@ -2270,21 +2337,21 @@ static int
addupval(Comp *cm, struct fenv *fenv, uint8_t idx, bool arg, bool local)
{
struct cmupval up = { idx, arg, local };
- for (int i = 0; i < fenv->nupval; ++i) {
- struct cmupval *up = &fenv->upvals[i];
+ for (int i = 0; i < fenv->upvals.len; ++i) {
+ struct cmupval *up = &fenv->upvals.at[i];
if (up->idx == idx && up->local == local && up->arg == arg) {
return up->idx;
}
}
- if (fenv->nupval == 256) {
+ if (fenv->upvals.len == 256) {
return comperr(cm, peekchr(cm), "too many upvalues"), -2;
}
- fenv->upvals[fenv->nupval] = up;
- return fenv->nupval++;
+ TRY(vecpush(cm->cx, &fenv->upvals, &up, 1));
+ return fenv->upvals.len - 1;
}
static int
-findupval(Comp *cm, Local **pl, struct fenv *fenv, const char *name)
+findupval(Comp *cm, struct local **pl, struct fenv *fenv, const char *name)
{
int idx;
if (!fenv->prev) {
@@ -2292,7 +2359,7 @@ findupval(Comp *cm, Local **pl, struct fenv *fenv, const char *name)
}
for (int i = fenv->prev->locals.len - 1; i >= 0; --i) {
- Local *l = &fenv->prev->locals.at[i];
+ struct local *l = &fenv->prev->locals.at[i];
if (!strcmp(&cm->spool.at[l->sref], name)) {
assert(!l->has_k); // would've been found by findlocal earlier
l->captured = 1;
@@ -2311,21 +2378,21 @@ findupval(Comp *cm, Local **pl, struct fenv *fenv, const char *name)
static bool
endscope(Comp *cm)
{
- while (!vecempty(&cm->fenv.locals)) {
- Local *l = veclast(&cm->fenv.locals);
- if (l->scope < cm->fenv.scope) {
+ while (!vecempty(&cm->fenv->locals)) {
+ struct local *l = veclast(&cm->fenv->locals);
+ if (l->scope < cm->fenv->scope) {
break;
} else {
if (!l->has_k) {
- --cm->fenv.nvars;
+ --cm->fenv->nvars;
if (l->scope > 0 && l->captured) {
TRY(compop(cm, Oclose) && compbyte(cm, l->index));
}
}
- --cm->fenv.locals.len;
+ --cm->fenv->locals.len;
}
}
- --cm->fenv.scope;
+ --cm->fenv->scope;
return 1;
}
@@ -2505,10 +2572,10 @@ lambdaexpr(Comp *cm, const char *name)
{
Proto *proto = newproto(cm->cx, cm->proto->file, name, cm->line);
Proto *prevfn = cm->proto;
- vec_of(uint8_t) prevcode;
- vec_of(Val) prevcon;
- struct fenv prevfenv = cm->fenv;;
- struct fenv fenv = { .prev = &prevfenv, .name = name };
+ vec_of(uint8_t, sizeof cm->code.inl) prevcode;
+ vec_of(Val, sizeof cm->con.inl / sizeof(Val)) prevcon;
+ struct fenv *prevfenv = cm->fenv;
+ struct fenv fenv = { .prev = prevfenv, .name = name };
bool ret = 1;
memcpy(&prevcode, &cm->code, sizeof prevcode);
@@ -2516,7 +2583,7 @@ lambdaexpr(Comp *cm, const char *name)
memcpy(&prevcon, &cm->con, sizeof prevcon);
memset(&cm->con, 0, sizeof cm->con);
cm->proto = proto;
- cm->fenv = fenv;
+ cm->fenv = &fenv;
if (matchspchr(cm, '[')) {
while (!matchspchr(cm, ']')) {
@@ -2556,7 +2623,7 @@ Cleanup:
cm->proto = prevfn;
memcpy(&cm->code, &prevcode, sizeof prevcode);
memcpy(&cm->con, &prevcon, sizeof prevcon);
- delfenv(cm->cx, &cm->fenv);
+ delfenv(cm->cx, &fenv);
cm->fenv = prevfenv;
return ret && compclosure(cm, proto);
@@ -2581,7 +2648,7 @@ static bool
primaryexpr(Comp *cm)
{
char buf[NAMEMAX];
- Local *local;
+ struct local *local;
int c;
if (*cm->stash_ident) {
@@ -2668,7 +2735,7 @@ primaryexpr(Comp *cm)
cm->lvalue = 1;
cm->lvalue_const = !local->mutable;
cm->lvalue_name = &cm->spool.at[local->sref];
- } else if ((idx = findupval(cm, &local, &cm->fenv, buf)) != -1) {
+ } else if ((idx = findupval(cm, &local, cm->fenv, buf)) != -1) {
if (idx == -2) return 0; // propagate some error
assert(idx >= 0 && idx < 256);
TRY(compop(cm, Oupval) && compbyte(cm, idx));
@@ -2715,17 +2782,12 @@ primaryexpr(Comp *cm)
}
if (c == '"') {
// string
- int i = 0;
- vec_of(char) big = {0};
- bool bigp = 0;
+ vec_of(char, 80) str = {0};
while ((c = nextchr(cm)) != '"') {
- if (i >= sizeof buf - 2) {
- bigp = 1;
- vecpush(cm->cx, &big, buf, i);
- }
+ char cc;
if (c == EOF) {
Eof:
- delvec(cm->cx, &big);
+ delvec(cm->cx, &str);
return comperr(cm, c, "unterminated string constant"), 0;
}
if (c == '\\') {
@@ -2754,29 +2816,19 @@ primaryexpr(Comp *cm)
}
case EOF: goto Eof;
default: Bad:
- delvec(cm->cx, &big);
+ delvec(cm->cx, &str);
return comperr(cm, c, "bad escape sequence"), 0;
}
}
- if (bigp) {
- if (!vecpush(cm->cx, &big, &c, 1)) {
- delvec(cm->cx, &big);
- return 0;
- }
- } else {
- buf[i++] = c;
- }
- }
- if (bigp) {
- vecpush(cm->cx, &big, "", 1);
- } else {
- buf[i] = 0;
+ cc = c;
+ TRY(vecpush(cm->cx, &str, &cc, 1));
}
- if (!box_str(cm->cx, &cm->k, buf, i)) {
- delvec(cm->cx, &big);
+ TRY(vecpush(cm->cx, &str, "", 1));
+ if (!box_str(cm->cx, &cm->k, str.at, str.len-1)) {
+ delvec(cm->cx, &str);
return 0;
}
- delvec(cm->cx, &big);
+ delvec(cm->cx, &str);
cm->has_k = 1;
return 1;
}
@@ -3342,7 +3394,7 @@ setexpr(Comp *cm)
TRY(condexpr(cm));
if ((binop = getbinop(&kind, &chr, cm)) && kind == 'S') {
int idx = -1, argc = -1, opcode;
- vec_of(uint8_t) *code = (void *)&cm->code.at;
+ vec_of(uint8_t, sizeof cm->code.inl) *code = (void *)&cm->code.at;
if (!cm->lvalue) {
return comperr(cm, chr, "not an lvalue"), 0;
}
@@ -3475,7 +3527,7 @@ discard(Comp *cm)
&& (code[cm->lastop2] == Odup || code[cm->lastop2] == Odupbck))
{
switch (code[cm->lastop]) {
- case Osetloc: case Osetarg:
+ case Osetloc: case Osetarg: case Osetupv:
memmove(code + cm->lastop2, code + cm->lastop, 2);
--cm->code.len;
resetlastops(cm);
@@ -3492,13 +3544,13 @@ discard(Comp *cm)
// @local declarations
static bool
-decl(Comp *cm, Local **pl, bool nofold)
+decl(Comp *cm, struct local **pl, bool nofold)
{
int c;
char name[NAMEMAX];
bool mutable;
uint idx = -1u;
- Local *l;
+ struct local *l;
eatspaces(cm);
if ((c = peekchr(cm)) != '_' && !aisalpha(c)) {
@@ -3601,7 +3653,7 @@ forstmt(Comp *cm)
* we copy the generated <cont> code to a temp buffer
* to move it to be after <body>
*/
- Local *local;
+ struct local *local;
uint8_t tmp[256];
int ilocal, cont, ncont;
@@ -3612,7 +3664,7 @@ forstmt(Comp *cm)
if (local->index >= 256) {
return comperr(cm, cm->spool.at[local->sref], "too many locals"), 0;
}
- ilocal = local - cm->fenv.locals.at;
+ ilocal = local - cm->fenv->locals.at;
TRY(expectspchr(cm, ']'));
// cond
@@ -3621,7 +3673,7 @@ forstmt(Comp *cm)
if (matchspchr(cm, ']')) {
return comperr(cm, ']', "expected operator"), 0;
}
- cm->stash_local = &cm->fenv.locals.at[ilocal];
+ cm->stash_local = &cm->fenv->locals.at[ilocal];
TRY(expr(cm));
TRY(expectspchr(cm, ']'));
TRY(compop(cm, Obf));
@@ -3635,7 +3687,7 @@ forstmt(Comp *cm)
if (matchspchr(cm, ']')) {
return comperr(cm, ']', "expected operator"), 0;
}
- cm->stash_local = &cm->fenv.locals.at[ilocal];
+ cm->stash_local = &cm->fenv->locals.at[ilocal];
TRY(expr(cm));
TRY(expectspchr(cm, ']'));
assert(!cm->has_k);
@@ -3654,7 +3706,7 @@ forstmt(Comp *cm)
// cont (2)
TRY(vecpush(cm->cx, &cm->code, tmp, ncont));
resetlastops(cm);
- local = &cm->fenv.locals.at[ilocal];
+ local = &cm->fenv->locals.at[ilocal];
TRY(compop(cm, local->isparam ? Osetarg : Osetloc));
TRY(compbyte(cm, local->index));
@@ -3757,6 +3809,7 @@ pez_eval_cb(PezContext *cx, const char *fname, int (*cb)(void *), void *ud)
Val *stktop = cx->stktop;
Proto *pr;
Fn *fn;
+ struct fenv fenv = {0};
Comp cm;
int gccanrun = cx->gccanrun;
cx->gccanrun = 0;
@@ -3768,6 +3821,7 @@ pez_eval_cb(PezContext *cx, const char *fname, int (*cb)(void *), void *ud)
return 0;
}
initcomp(&cm, cx, pr, cb, ud);
+ cm.fenv = &fenv;
ETRY(block(&cm, EOF));
ETRY(compop(&cm, Oret));
@@ -3792,7 +3846,7 @@ pez_eval_cb(PezContext *cx, const char *fname, int (*cb)(void *), void *ud)
Err:
cx->stktop = stktop;
deinitcomp(&cm);
- delfenv(cx, &cm.fenv);
+ delfenv(cx, cm.fenv);
cx->gccanrun = gccanrun;
return 0;
}
@@ -3890,7 +3944,7 @@ pez_del(PezContext *cx)
}
if (cx->nalloc != 0) {
fprintf(stderr, "ERR nalloc %d\n", cx->nalloc);
- assert(cx->nalloc == 0);
+ // assert(cx->nalloc == 0);
}
cx->alloc(cx->ud, cx, sizeof *cx, 0);
}
@@ -4177,7 +4231,7 @@ pez_length(PezContext *cx, int idx)
return sstr_len(v);
}
if (isobj_of(v, PEZ_TString)) {
- return ((Str *)unbox_obj(v))->n;
+ return ((Str *)unbox_obj(v))->len;
}
return -1;
}