summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2025-05-06 16:57:19 +0200
committerlemon <lsof@mailbox.org>2025-05-06 16:57:19 +0200
commit96cc96cb635f31a62582c04a7d0b6b3c75b4f019 (patch)
tree9434ccf61401937d21880b3547fdef84be93ed9d
parent2297267c65a30fc6212f92bde78748fd8b4dcd2f (diff)
tostring
-rw-r--r--pez.c36
1 files changed, 30 insertions, 6 deletions
diff --git a/pez.c b/pez.c
index fac8308..306e3ca 100644
--- a/pez.c
+++ b/pez.c
@@ -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 },