diff options
| author | 2025-05-06 16:57:19 +0200 | |
|---|---|---|
| committer | 2025-05-06 16:57:19 +0200 | |
| commit | 96cc96cb635f31a62582c04a7d0b6b3c75b4f019 (patch) | |
| tree | 9434ccf61401937d21880b3547fdef84be93ed9d | |
| parent | 2297267c65a30fc6212f92bde78748fd8b4dcd2f (diff) | |
tostring
| -rw-r--r-- | pez.c | 36 |
1 files changed, 30 insertions, 6 deletions
@@ -2015,9 +2015,9 @@ exefn(PezContext *cx, Fn *fn, uint nargs) /* Core functions */ /******************/ -struct vals { vec_of(Val, 2); }; +struct privals { vec_of(Val, 2); }; static bool -xprint1(PezContext *cx, struct vals *seen, +xprint1(PezContext *cx, struct privals *seen, bool (*cb)(PezContext *, void *, const char *, uint), void *u, Val v) { for (uint i = 0; i < seen->len; ++i) { @@ -2083,7 +2083,7 @@ xprint1(PezContext *cx, struct vals *seen, TRY(cb(cx, u, "#<function>", 11)); } } else if (isobj_of(v, PEZ_TDilambda)) { - TRY(cb(cx, u, "#<dilambda>", 12)); + TRY(cb(cx, u, "#<dilambda>", 11)); } else if (isobj_of(v, PEZ_TArray)) { Array *arr = unbox_obj(v); bool ok = 1; @@ -2147,7 +2147,7 @@ f_xprintf1(PezContext *cx, const char *fn, char sbuf[8]; const char *str; int len; - struct vals seen = {0}; + struct privals seen = {0}; if (arg == argc) { pez_error(cx, fn, "not enough arguments for format string"); return 0; @@ -2196,17 +2196,18 @@ f_printf(PezContext *cx, int argc) return f_xprintf1(cx, "printf", printtofile, stdout, argc); } +struct strpritmp { vec_of(char, 100); }; static bool printtostr(PezContext *cx, void *V, const char *d, uint n) { - vec_of(char, 100) *v = V; + struct strpritmp *v = V; return vecpush(cx, v, d, n); } static bool f_sprintf(PezContext *cx, int argc) { - vec_of(char, 100) s = {0}; + struct strpritmp s = {0}; ETRY(f_xprintf1(cx, "sprintf", printtostr, &s, argc)); ETRY(pez_pushstring(cx, s.at, s.len)); delvec(cx, &s); @@ -2217,6 +2218,28 @@ Err: } static bool +f_tostring(PezContext *cx, int argc) +{ + bool ok; + struct privals seen = {0}; + struct strpritmp s = {0}; + + TRY(pez_checksig(cx, argc, "tostring", "any")); + if (pez_typeof(cx, -argc) == PEZ_TString) + return pez_push(cx, -argc); + + ok = xprint1(cx, &seen, printtostr, &s, cx->stktop[-argc]); + delvec(cx, &seen); + if (!ok) goto Err; + ETRY(pez_pushstring(cx, s.at, s.len)); + delvec(cx, &s); + return 1; +Err: + delvec(cx, &s); + return 0; +} + +static bool f_dilambda(PezContext *cx, int argc) { Dilambda *dl; @@ -2373,6 +2396,7 @@ f_ioclose(PezContext *cx, int argc) static const struct coredef { const char *n; PezCFn *f; } core[] = { { "printf", f_printf }, { "sprintf", f_sprintf }, + { "tostring", f_tostring }, { "dilambda", f_dilambda }, { "typeof", f_typeof }, { "array#new", f_arraynew }, |