summaryrefslogtreecommitdiff
path: root/pit/src
diff options
context:
space:
mode:
authorLLLL Colonq <llll@colonq>2026-09-04 16:29:31 -0400
committerLLLL Colonq <llll@colonq>2026-09-04 16:29:31 -0400
commit843ea34efc2c5ea10edc4d534304f8287f97fbbc (patch)
tree65c2b676b650413a6154ffa7b319d4d0b6f9cff4 /pit/src
parentc01f847b68a7fcd48eb0f3d456aa993a6f69ea8d (diff)
pit: printf
Diffstat (limited to 'pit/src')
-rw-r--r--pit/src/native.c16
-rw-r--r--pit/src/runtime.c2
-rw-r--r--pit/src/runtime/compile.c4
-rw-r--r--pit/src/runtime/dump.c21
-rw-r--r--pit/src/runtime/eval.c5
-rw-r--r--pit/src/runtime/macroexpand.c6
-rw-r--r--pit/src/utils.c25
7 files changed, 69 insertions, 10 deletions
diff --git a/pit/src/native.c b/pit/src/native.c
index dbb461d..2d28679 100644
--- a/pit/src/native.c
+++ b/pit/src/native.c
@@ -31,6 +31,20 @@ void pit_dump_to_file(pit_runtime *rt, void *vf, pit_value v, bool readable) {
pit_dump_with_callback(rt, v, readable, pit_dump_to_file_callback, vf);
}
+i64 pit_fprintf(pit_runtime *rt, void *vf, char *format, ...) {
+ FILE *f = (FILE *) vf;
+ va_list ap;
+ va_start(ap, format);
+ char buf[8192];
+ pit_printf_handler h[1];
+ h[0].specifier = 'v'; h[0].callback = pit_dump_printf_callback;
+ int ret = pit_vsnprintf_helper(buf, sizeof(buf) - 1, format, ap, h, 1, rt);
+ buf[ret] = 0;
+ va_end(ap);
+ fputs(buf, f);
+ return ret;
+}
+
bool pit_runtime_print_error(pit_runtime *rt) {
if (!pit_value_eq(rt->error, PIT_NIL)) {
for (i64 i = 0; i < rt->callstack->next; ++i) {
@@ -54,7 +68,7 @@ void pit_debug_trace_(pit_runtime *rt, char *format, pit_value v) {
char buf[1024] = {0};
i64 end = pit_dump(rt, buf, sizeof(buf) - 1, v, true);
buf[end] = 0;
- fprintf(stderr, format, buf);
+ pit_fprintf(rt, stderr, format, buf);
}
pit_value pit_value_bytes_new_file(pit_runtime *rt, char *path) {
diff --git a/pit/src/runtime.c b/pit/src/runtime.c
index 633bff5..d4a0a62 100644
--- a/pit/src/runtime.c
+++ b/pit/src/runtime.c
@@ -80,7 +80,7 @@ void pit_error(pit_runtime *rt, char *format, ...) {
char buf[1024] = {0};
va_list vargs;
va_start(vargs, format);
- pit_libc_string_vsnprintf(buf, sizeof(buf), format, vargs);
+ pit_vsnprintf(rt, buf, sizeof(buf), format, vargs);
va_end(vargs);
rt->error = rt->msg_out_of_memory; /* we set the error now to prevent infinite recursion */
rt->error = pit_value_bytes_new_cstr(rt, buf); /* in case this errs also */
diff --git a/pit/src/runtime/compile.c b/pit/src/runtime/compile.c
index e7a4ab8..7cfc091 100644
--- a/pit/src/runtime/compile.c
+++ b/pit/src/runtime/compile.c
@@ -180,6 +180,8 @@ static void compile_interpret_traversal_entry(pit_runtime *rt, pit_traversal_ent
}
}
+#include <stdio.h>
+
pit_value pit_compile(pit_runtime *rt, pit_value top) {
/* compilation proceeds in a somewhat unintuitive manner */
/* typically, we would simply recursively traverse the tree, accumulating the output code */
@@ -290,6 +292,7 @@ end: {
if (rt->compilation_stack->next > compilation_stack_reset) {
/* if the compilation stack is not empty, the top is our compiled code! */
pit_compilation_entry ent;
+ ent.in.value = PIT_NIL;
pit_vec_pop(pit_compilation_entry)(rt->compilation_stack, &ent);
ret = ent.in.value;
}
@@ -299,6 +302,7 @@ end: {
}
rt->compilation_stack->next = compilation_stack_reset;
rt->traversal->next = traversal_reset;
+ pit_fprintf(rt, stderr, "here: %v\n", ret, ret);
return ret;
}
}
diff --git a/pit/src/runtime/dump.c b/pit/src/runtime/dump.c
index 9627a36..4d67bb6 100644
--- a/pit/src/runtime/dump.c
+++ b/pit/src/runtime/dump.c
@@ -183,3 +183,24 @@ i64 pit_dump(pit_runtime *rt, char *buf, i64 len, pit_value v, bool readable) {
pit_dump_with_callback(rt, v, readable, pit_dump_to_buf_callback, &cl);
return cl.off;
}
+
+i64 pit_dump_printf_callback(va_list ap, char *buf, size_t len, void *data) {
+ pit_runtime *rt = (pit_runtime *) data;
+ pit_value arg = va_arg(ap, pit_value);
+ return pit_dump(rt, buf, (i64) len, arg, false);
+}
+i64 pit_vsnprintf(pit_runtime *rt, char *buf, i64 len, char *format, va_list ap) {
+ if (len == 0) return 0;
+ pit_printf_handler h[1];
+ h[0].specifier = 'v'; h[0].callback = pit_dump_printf_callback;
+ i64 ret = pit_vsnprintf_helper(buf, (size_t) (len - 1), format, ap, h, 1, rt);
+ buf[ret] = 0;
+ return ret;
+}
+i64 pit_snprintf(pit_runtime *rt, char *buf, i64 len, char *format, ...) {
+ va_list ap;
+ va_start(ap, format);
+ i64 ret = pit_vsnprintf(rt, buf, len, format, ap);
+ va_end(ap);
+ return ret;
+}
diff --git a/pit/src/runtime/eval.c b/pit/src/runtime/eval.c
index a2b9e79..5966fdb 100644
--- a/pit/src/runtime/eval.c
+++ b/pit/src/runtime/eval.c
@@ -128,9 +128,10 @@ bool pit_vm_run_one(pit_runtime *rt) {
// fprintf(stderr, "frame: "); pit_dump_to_file(rt, stderr, e->code, false); fprintf(stderr, "\n");
// }
pit_value ins = pit_value_cons_car(rt, ent->code);
- // fprintf(stderr, "ins: "); pit_dump_to_file(rt, stderr, ins, false); fprintf(stderr, "\n");
+ fprintf(stderr, "ins: "); pit_dump_to_file(rt, stderr, ins, false); fprintf(stderr, "\n");
+ fprintf(stderr, "code: "); pit_dump_to_file(rt, stderr, ent->code, false); fprintf(stderr, "\n");
// fprintf(stderr, "foo: "); pit_dump_to_file(rt, stderr, pit_symtab_get_function_cell(rt, pit_symtab_intern_cstr(rt, "foo")), false); fprintf(stderr, "\n");
- if (ins == PIT_NIL) { pit_error(rt, "malformed vm instruction"); return false; }
+ if (ins == PIT_NIL) { pit_error(rt, "malformed vm instruction: %v %v", ins); return false; }
ent->code = pit_value_cons_cdr(rt, ent->code);
pit_value op = pit_value_cons_car(rt, ins);
if (pit_symtab_symbol_name_match_cstr(rt, op, "literal")) {
diff --git a/pit/src/runtime/macroexpand.c b/pit/src/runtime/macroexpand.c
index fdc1f14..9a557dd 100644
--- a/pit/src/runtime/macroexpand.c
+++ b/pit/src/runtime/macroexpand.c
@@ -7,7 +7,7 @@ pit_value pit_macroexpand_1(pit_runtime *rt, pit_value top) {
if (pit_vec_push(pit_value)(rt->expr_stack, top) < 0)
pit_error(rt, "macro expansion stack overflow");
while (rt->expr_stack->next > expr_stack_reset) {
- pit_value cur;
+ pit_value cur = PIT_NIL;
if (rt->error != PIT_NIL) goto end;
if (pit_vec_pop(pit_value)(rt->expr_stack, &cur) < 0)
pit_error(rt, "macro expansion stack underflow");
@@ -66,7 +66,7 @@ pit_value pit_macroexpand_1(pit_runtime *rt, pit_value top) {
if (pit_vec_pop(pit_value)(rt->result_stack, &f) < 0)
pit_error(rt, "macro expansion stack underflow");
for (i64 i = 0; i < ent->in.application.arity; ++i) {
- pit_value a;
+ pit_value a = PIT_NIL;
if (pit_vec_pop(pit_value)(rt->result_stack, &a) < 0)
pit_error(rt, "macro expansion stack underflow");
args = pit_value_cons(rt, a, args);
@@ -76,7 +76,7 @@ pit_value pit_macroexpand_1(pit_runtime *rt, pit_value top) {
pit_annotation_set(rt, pit_value_as_ref(rt, app), *ent->in.application.annotation);
}
if (pit_vec_push(pit_value)(rt->result_stack, app) < 0)
- pit_error(rt, "macro expansion stack overflow");
+ pit_error(rt, "macroexpansion stack overflow");
break;
}
default:
diff --git a/pit/src/utils.c b/pit/src/utils.c
index 75d59a6..ac8087c 100644
--- a/pit/src/utils.c
+++ b/pit/src/utils.c
@@ -11,8 +11,10 @@ enum vsnprintf_mode {
#define SCRATCH_LEN 256
#define WRITE(c) { buf[idx++] = c; if (idx >= len - 1) goto done; }
#define WRITE_SCRATCH(c) { scratch[sidx++] = c; if (sidx >= SCRATCH_LEN) goto error; }
-int pit_libc_string_vsnprintf(char *buf, size_t len, char *format, va_list ap) {
- // vsnprintf
+int pit_vsnprintf_helper(
+ char *buf, size_t len, char *format, va_list ap,
+ pit_printf_handler *handlers, i64 handlers_len, void *data
+) {
size_t idx = 0;
size_t flen = pit_libc_string_strlen(format);
size_t fidx = 0;
@@ -81,8 +83,21 @@ int pit_libc_string_vsnprintf(char *buf, size_t len, char *format, va_list ap) {
mode = VSNPRINTF_MODE_NORMAL;
break;
}
- default: goto error;
+ default:
+ if (handlers) {
+ for (i64 i = 0; i < handlers_len; ++i) {
+ if (c == handlers[i].specifier) {
+ i64 res = handlers[i].callback(ap, buf + idx, len - idx, data);
+ if (res < 0) goto error;
+ idx += (size_t) res;
+ mode = VSNPRINTF_MODE_NORMAL;
+ goto handled;
+ }
+ }
+ }
+ goto error;
}
+ handled:
break;
}
}
@@ -92,6 +107,10 @@ done:
error:
return -1;
}
+int pit_libc_string_vsnprintf(char *buf, size_t len, char *format, va_list ap) {
+ // vsnprintf
+ return pit_vsnprintf_helper(buf, len, format, ap, NULL, 0, NULL);
+}
int pit_libc_string_snprintf(char *buf, size_t len, char *format, ...) {
va_list ap;
va_start(ap, format);