diff options
| author | LLLL Colonq <llll@colonq> | 2026-09-04 16:29:31 -0400 |
|---|---|---|
| committer | LLLL Colonq <llll@colonq> | 2026-09-04 16:29:31 -0400 |
| commit | 843ea34efc2c5ea10edc4d534304f8287f97fbbc (patch) | |
| tree | 65c2b676b650413a6154ffa7b319d4d0b6f9cff4 | |
| parent | c01f847b68a7fcd48eb0f3d456aa993a6f69ea8d (diff) | |
pit: printf
| -rw-r--r-- | pit/include/lcq/pit/runtime/dump.h | 5 | ||||
| -rw-r--r-- | pit/include/lcq/pit/utils.h | 7 | ||||
| -rw-r--r-- | pit/src/native.c | 16 | ||||
| -rw-r--r-- | pit/src/runtime.c | 2 | ||||
| -rw-r--r-- | pit/src/runtime/compile.c | 4 | ||||
| -rw-r--r-- | pit/src/runtime/dump.c | 21 | ||||
| -rw-r--r-- | pit/src/runtime/eval.c | 5 | ||||
| -rw-r--r-- | pit/src/runtime/macroexpand.c | 6 | ||||
| -rw-r--r-- | pit/src/utils.c | 25 | ||||
| -rw-r--r-- | pit/test/test9.pit | 2 |
10 files changed, 83 insertions, 10 deletions
diff --git a/pit/include/lcq/pit/runtime/dump.h b/pit/include/lcq/pit/runtime/dump.h index 600604e..40b2a70 100644 --- a/pit/include/lcq/pit/runtime/dump.h +++ b/pit/include/lcq/pit/runtime/dump.h @@ -22,4 +22,9 @@ i64 pit_dump(pit_runtime *rt, char *buf, i64 len, pit_value v, bool readable); i64 pit_dump_to_stdout(pit_runtime *rt, char *buf, i64 len, pit_value v, bool readable); void pit_dump_to_file(pit_runtime *rt, void *vf, pit_value v, bool readable); +i64 pit_dump_printf_callback(va_list ap, char *buf, size_t len, void *data); +i64 pit_vsnprintf(pit_runtime *rt, char *buf, i64 len, char *format, va_list ap); +i64 pit_snprintf(pit_runtime *rt, char *buf, i64 len, char *format, ...); +i64 pit_fprintf(pit_runtime *rt, void *vf, char *format, ...); + #endif diff --git a/pit/include/lcq/pit/utils.h b/pit/include/lcq/pit/utils.h index 929472a..d45758f 100644 --- a/pit/include/lcq/pit/utils.h +++ b/pit/include/lcq/pit/utils.h @@ -44,6 +44,13 @@ static inline u8 *pit_libc_string_memcpy(u8 *dest, u8 *src, size_t n) { for (; i < n; ++i) dest[i] = src[i]; return dest; } + +/* printf */ +typedef struct { + char specifier; + i64 (*callback)(va_list ap, char *buf, size_t len, void *data); +} pit_printf_handler; +int pit_vsnprintf_helper(char *buf, size_t len, char *format, va_list ap, pit_printf_handler *handlers, i64 handlers_len, void *data); int pit_libc_string_vsnprintf(char *str, size_t size, char *format, va_list ap); int pit_libc_string_snprintf(char *buf, size_t len, char *format, ...); 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); diff --git a/pit/test/test9.pit b/pit/test/test9.pit new file mode 100644 index 0000000..daf1686 --- /dev/null +++ b/pit/test/test9.pit @@ -0,0 +1,2 @@ +(defun! foo (x) x) +(foo 1)
\ No newline at end of file |
