summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--emacs/pit.el36
-rw-r--r--include/lcq/pit/runtime.h16
-rw-r--r--src/library.c18
-rw-r--r--src/main.c12
-rw-r--r--src/parser.c10
-rw-r--r--src/runtime.c48
-rw-r--r--test/error2.pit4
-rw-r--r--whereweleftoff.org8
9 files changed, 92 insertions, 64 deletions
diff --git a/Makefile b/Makefile
index baa81e8..0b5d02f 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,6 @@ EXE ?= pit
CC ?= gcc
AR ?= ar
-CHK_SOURCES ?= src/main.c $(SRCS)
override CPPFLAGS += -MMD -MP
override CFLAGS += -Oz -fPIC --std=c99 -g -Ideps/ -Isrc/ -Iinclude/ -Wall -Wextra -Wpedantic -Wconversion -Wformat-security -Wshadow -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes -Wnull-dereference -Wfloat-equal -Wundef -Wpointer-arith -Wbad-function-cast -Wlogical-op -Wmissing-braces -Wcast-align -Wstrict-overflow=5 -fwrapv # -ftrapv
override LDFLAGS += -g -static
@@ -16,6 +15,9 @@ SRCS_NATIVE := src/native.c
OBJECTS_NATIVE := $(SRCS_NATIVE:src/%.c=$(BUILD)/%.o)
LIB_NATIVE := libcolonq-pit-native.a
+SRCS := src/main.c $(SRCS_CORE) $(SRCS_NATIVE)
+CHK_SOURCES ?= $(SRCS)
+
prefix ?= /usr/local
exec_prefix ?= $(prefix)
bindir ?= $(exec_prefix)/bin
diff --git a/emacs/pit.el b/emacs/pit.el
index 9a357a3..3665d93 100644
--- a/emacs/pit.el
+++ b/emacs/pit.el
@@ -102,41 +102,5 @@
(cider--update-host-port)
(cider--check-existing-session))))))
-(defun cider-repl-handler (buffer)
- "Make an nREPL evaluation handler for the REPL BUFFER."
- (message "running cider-repl-handler")
- (let ((show-prompt t))
- (nrepl-make-response-handler
- buffer
- (lambda (buffer value)
- (message "value-handler")
- (cider-repl-emit-result buffer value t))
- (lambda (buffer out)
- (dolist (f cider--repl-stdout-functions)
- (funcall f buffer out))
- (cider-repl-emit-stdout buffer out))
- (lambda (buffer err)
- (dolist (f cider--repl-stderr-functions)
- (funcall f buffer err))
- (cider-repl-emit-stderr buffer err))
- (lambda (buffer)
- (message "done-handler: %s" show-prompt)
- (when show-prompt
- (cider-repl-emit-prompt buffer))
- (when cider-repl-buffer-size-limit
- (cider-repl-maybe-trim-buffer buffer))
- (dolist (f cider--repl-done-functions)
- (funcall f buffer)))
- nrepl-err-handler
- (lambda (buffer value content-type)
- (if-let* ((content-attrs (cadr content-type))
- (content-type* (car content-type))
- (handler (cdr (assoc content-type*
- cider-repl-content-type-handler-alist))))
- (setq show-prompt (funcall handler content-type buffer value nil t))
- (cider-repl-emit-result buffer value t t)))
- (lambda (buffer warning)
- (cider-repl-emit-stderr buffer warning)))))
-
(provide 'pit)
;;; pit.el ends here
diff --git a/include/lcq/pit/runtime.h b/include/lcq/pit/runtime.h
index 48e2bcd..da93dda 100644
--- a/include/lcq/pit/runtime.h
+++ b/include/lcq/pit/runtime.h
@@ -81,12 +81,28 @@ pit_runtime_eval_program *pit_runtime_eval_program_new(u8 *buf, i64 buf_len);
void pit_runtime_eval_program_push_literal(struct pit_runtime *rt, pit_runtime_eval_program *s, pit_value x);
void pit_runtime_eval_program_push_apply(struct pit_runtime *rt, pit_runtime_eval_program *s, i64 arity);
+/* annotation attached to (some) heavy values detaiking things like line numbers */
+typedef struct {
+ pit_ref ref;
+ i64 line;
+ i64 column;
+} pit_expr_annotation;
+typedef struct {
+ i64 capacity, next;
+ pit_expr_annotation data[];
+} pit_expr_annotations;
+pit_expr_annotations *pit_expr_annotations_new(u8 *buf, i64 buf_len);
+void pit_expr_annotations_push(pit_expr_annotations *s, pit_ref ref, i64 line, i64 column);
+pit_expr_annotation *pit_expr_annotations_lookup(pit_expr_annotations *s, pit_ref ref);
+
typedef struct pit_runtime {
/* interpreter state */
pit_arena *heap; /* all heavy values, bytestrings, and arrays. */
/* bytestrings and arrays are allocated at the end (descending), heavy values are allocated at the front */
/* this allows us to iterate over only heavy values at the front (useful in Cheney's algorithm for GC */
pit_arena *backbuffer; /* additional allocation, the same size as the heap (used by GC) */
+ pit_expr_annotations *annotations;
+ pit_expr_annotations *annotations_backbuffer;
pit_arena *symtab; i64 symtab_len; /* all symbols - effectively an array of pit_symtab_entry */
/* temporary/"scratch" memory */
pit_arena *scratch; /* temporary arena used during parsing and evaluation */
diff --git a/src/library.c b/src/library.c
index 8e243b9..383105b 100644
--- a/src/library.c
+++ b/src/library.c
@@ -805,7 +805,6 @@ void pit_install_library_essential(pit_runtime *rt) {
/* eval */
pit_fset(rt, pit_intern_cstr(rt, "eval!"), pit_nativefunc_new(rt, impl_eval));
/* predicates */
- /*
pit_fset(rt, pit_intern_cstr(rt, "eq?"), pit_nativefunc_new(rt, impl_eq_p));
pit_fset(rt, pit_intern_cstr(rt, "equal?"), pit_nativefunc_new(rt, impl_equal_p));
pit_fset(rt, pit_intern_cstr(rt, "integer?"), pit_nativefunc_new(rt, impl_integer_p));
@@ -815,25 +814,19 @@ void pit_install_library_essential(pit_runtime *rt) {
pit_fset(rt, pit_intern_cstr(rt, "array?"), pit_nativefunc_new(rt, impl_array_p));
pit_fset(rt, pit_intern_cstr(rt, "bytes?"), pit_nativefunc_new(rt, impl_bytes_p));
pit_fset(rt, pit_intern_cstr(rt, "function?"), pit_nativefunc_new(rt, impl_function_p));
- */
/* symbols */
- /*
pit_fset(rt, pit_intern_cstr(rt, "set!"), pit_nativefunc_new(rt, impl_set));
pit_fset(rt, pit_intern_cstr(rt, "fset!"), pit_nativefunc_new(rt, impl_fset));
pit_fset(rt, pit_intern_cstr(rt, "symbol-is-macro!"), pit_nativefunc_new(rt, impl_symbol_is_macro));
pit_fset(rt, pit_intern_cstr(rt, "funcall"), pit_nativefunc_new(rt, impl_funcall));
pit_fset(rt, pit_intern_cstr(rt, "apply"), pit_nativefunc_new(rt, impl_apply));
- */
/* cons cells */
- /*
pit_fset(rt, pit_intern_cstr(rt, "cons"), pit_nativefunc_new(rt, impl_cons));
pit_fset(rt, pit_intern_cstr(rt, "car"), pit_nativefunc_new(rt, impl_car));
pit_fset(rt, pit_intern_cstr(rt, "cdr"), pit_nativefunc_new(rt, impl_cdr));
pit_fset(rt, pit_intern_cstr(rt, "setcar!"), pit_nativefunc_new(rt, impl_setcar));
pit_fset(rt, pit_intern_cstr(rt, "setcdr!"), pit_nativefunc_new(rt, impl_setcdr));
- */
/* cons lists*/
- /*
pit_fset(rt, pit_intern_cstr(rt, "list"), pit_nativefunc_new(rt, impl_list));
pit_fset(rt, pit_intern_cstr(rt, "list/nth"), pit_nativefunc_new(rt, impl_list_nth));
pit_fset(rt, pit_intern_cstr(rt, "list/iota"), pit_nativefunc_new(rt, impl_list_iota));
@@ -851,14 +844,10 @@ void pit_install_library_essential(pit_runtime *rt) {
pit_fset(rt, pit_intern_cstr(rt, "list/contains?"), pit_nativefunc_new(rt, impl_list_contains_p));
pit_fset(rt, pit_intern_cstr(rt, "list/all?"), pit_nativefunc_new(rt, impl_list_all_p));
pit_fset(rt, pit_intern_cstr(rt, "list/zip-with"), pit_nativefunc_new(rt, impl_list_zip_with));
- */
/* bytestrings */
- /*
pit_fset(rt, pit_intern_cstr(rt, "bytes/len"), pit_nativefunc_new(rt, impl_bytes_len));
pit_fset(rt, pit_intern_cstr(rt, "bytes/range"), pit_nativefunc_new(rt, impl_bytes_range));
- */
/* array */
- /*
pit_fset(rt, pit_intern_cstr(rt, "array"), pit_nativefunc_new(rt, impl_array));
pit_fset(rt, pit_intern_cstr(rt, "array/to-list"), pit_nativefunc_new(rt, impl_array_to_list));
pit_fset(rt, pit_intern_cstr(rt, "array/from-list"), pit_nativefunc_new(rt, impl_array_from_list));
@@ -868,7 +857,6 @@ void pit_install_library_essential(pit_runtime *rt) {
pit_fset(rt, pit_intern_cstr(rt, "array/set!"), pit_nativefunc_new(rt, impl_array_set));
pit_fset(rt, pit_intern_cstr(rt, "array/map"), pit_nativefunc_new(rt, impl_array_map));
pit_fset(rt, pit_intern_cstr(rt, "array/map!"), pit_nativefunc_new(rt, impl_array_map_mut));
- */
/* arithmetic */
pit_fset(rt, pit_intern_cstr(rt, "abs"), pit_nativefunc_new(rt, impl_abs));
pit_fset(rt, pit_intern_cstr(rt, "+"), pit_nativefunc_new(rt, impl_add));
@@ -876,25 +864,19 @@ void pit_install_library_essential(pit_runtime *rt) {
pit_fset(rt, pit_intern_cstr(rt, "*"), pit_nativefunc_new(rt, impl_mul));
pit_fset(rt, pit_intern_cstr(rt, "/"), pit_nativefunc_new(rt, impl_div));
/* booleans */
- /*
pit_fset(rt, pit_intern_cstr(rt, "not"), pit_nativefunc_new(rt, impl_not));
- */
/* comparisons */
- /*
pit_fset(rt, pit_intern_cstr(rt, "<"), pit_nativefunc_new(rt, impl_lt));
pit_fset(rt, pit_intern_cstr(rt, ">"), pit_nativefunc_new(rt, impl_gt));
pit_fset(rt, pit_intern_cstr(rt, "<="), pit_nativefunc_new(rt, impl_le));
pit_fset(rt, pit_intern_cstr(rt, ">="), pit_nativefunc_new(rt, impl_ge));
- */
/* bitwise arithmetic */
- /*
pit_fset(rt, pit_intern_cstr(rt, "bitwise/and"), pit_nativefunc_new(rt, impl_bitwise_and));
pit_fset(rt, pit_intern_cstr(rt, "bitwise/or"), pit_nativefunc_new(rt, impl_bitwise_or));
pit_fset(rt, pit_intern_cstr(rt, "bitwise/xor"), pit_nativefunc_new(rt, impl_bitwise_xor));
pit_fset(rt, pit_intern_cstr(rt, "bitwise/not"), pit_nativefunc_new(rt, impl_bitwise_not));
pit_fset(rt, pit_intern_cstr(rt, "bitwise/lshift"), pit_nativefunc_new(rt, impl_bitwise_lshift));
pit_fset(rt, pit_intern_cstr(rt, "bitwise/rshift"), pit_nativefunc_new(rt, impl_bitwise_rshift));
- */
}
static pit_value impl_plist_get(pit_runtime *rt, pit_value args, void *data) {
diff --git a/src/main.c b/src/main.c
index f29245b..76da802 100644
--- a/src/main.c
+++ b/src/main.c
@@ -8,15 +8,15 @@
#include <lcq/pit/library.h>
int main(int argc, char **argv) {
- // i64 sz = 256 * 1024 * 1024;
- i64 sz = 32 * 1024;
+ i64 sz = 256 * 1024 * 1024;
+ // i64 sz = 32 * 1024;
u8 *buf = malloc((size_t) sz);
pit_runtime *rt = pit_runtime_new(buf, sz);
pit_install_library_essential(rt);
- // pit_install_library_io(rt);
- // pit_install_library_plist(rt);
- // pit_install_library_alist(rt);
- // pit_install_library_bytestring(rt);
+ pit_install_library_io(rt);
+ pit_install_library_plist(rt);
+ pit_install_library_alist(rt);
+ pit_install_library_bytestring(rt);
if (argc < 2) {
pit_repl(rt);
} else {
diff --git a/src/parser.c b/src/parser.c
index 77b4172..002641e 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -3,6 +3,8 @@
#include <lcq/pit/parser.h>
#include <lcq/pit/runtime.h>
+#include <stdio.h>
+
static pit_lex_token peek(pit_parser *st) {
if (!st) return PIT_LEX_TOKEN_ERROR;
return st->next.token;
@@ -106,6 +108,14 @@ pit_value pit_parse(pit_runtime *rt, pit_parser *st, bool *eof) {
ret = pit_cons(rt, *v, ret);
}
rt->scratch->next = scratch_reset;
+ if (pit_value_sort(ret) == PIT_VALUE_SORT_REF) {
+ fprintf(stderr, "adding annotation (%ld): ", pit_as_ref(rt, ret));
+ pit_trace_(rt, "%s\n", ret);
+ pit_expr_annotations_push(rt->annotations,
+ pit_as_ref(rt, ret),
+ rt->source_line, rt->source_column
+ );
+ }
return ret;
}
case PIT_LEX_TOKEN_LSQUARE: {
diff --git a/src/runtime.c b/src/runtime.c
index 2d5dede..007a62f 100644
--- a/src/runtime.c
+++ b/src/runtime.c
@@ -4,6 +4,8 @@
#include <lcq/pit/runtime.h>
#include <lcq/pit/library.h>
+#include <stdio.h>
+
enum pit_value_sort pit_value_sort(pit_value v) {
/* if this isn't a NaN, or it's a quiet NaN, this is a real double */
/* if (((v >> 52) & 0b011111111111) != 0b011111111111 || ((v >> 51) & 0b1) == 1) return PIT_VALUE_SORT_DOUBLE; */
@@ -26,11 +28,14 @@ pit_runtime *pit_runtime_new(u8 *buf, i64 len) {
pit_arena *a = pit_arena_new(buf, len, sizeof(u8));
pit_runtime *ret = pit_arena_alloc_back(a, sizeof(*ret));
i64 heap_size = len / 4;
- i64 symtab_size = len / 8;
- i64 scratch_size = len / 16;
- i64 stack_size = len / 16;
+ i64 annotations_size = len / 32;
+ i64 symtab_size = len / 16;
+ i64 scratch_size = len / 32;
+ i64 stack_size = len / 32;
ret->heap = pit_arena_new(pit_arena_alloc_back(a, heap_size), heap_size, sizeof(pit_value_heavy));
ret->backbuffer = pit_arena_new(pit_arena_alloc_back(a, heap_size), heap_size, sizeof(pit_value_heavy));
+ ret->annotations = pit_expr_annotations_new(pit_arena_alloc_back(a, annotations_size), annotations_size);
+ ret->annotations_backbuffer = pit_expr_annotations_new(pit_arena_alloc_back(a, annotations_size), annotations_size);
ret->symtab = pit_arena_new(pit_arena_alloc_back(a, symtab_size), symtab_size, sizeof(pit_symtab_entry));
ret->symtab_len = 0;
ret->scratch = pit_arena_new(pit_arena_alloc_back(a, scratch_size), scratch_size, sizeof(u8));
@@ -965,6 +970,32 @@ void pit_runtime_eval_program_push_apply(pit_runtime *rt, pit_runtime_eval_progr
(void) rt;
}
+pit_expr_annotations *pit_expr_annotations_new(u8 *buf, i64 buf_len) {
+ uintptr_t base = (uintptr_t) buf;
+ uintptr_t aligned = pit_align_up(base, sizeof(void *));
+ pit_expr_annotations *ret = (pit_expr_annotations *) aligned;
+ uintptr_t data = aligned + sizeof(pit_arena);
+ i64 offset = (i64) data - (i64) base;
+ i64 remaining = (i64) (buf_len - offset);
+ i64 cap = remaining / (i64) sizeof(pit_expr_annotation);
+ ret->next = 0;
+ ret->capacity = cap;
+ return ret;
+}
+void pit_expr_annotations_push(pit_expr_annotations *s, pit_ref ref, i64 line, i64 column) {
+ pit_expr_annotation *ent = &s->data[s->next++];
+ ent->ref = ref;
+ ent->line = line;
+ ent->column = column;
+}
+
+pit_expr_annotation *pit_expr_annotations_lookup(pit_expr_annotations *s, pit_ref ref) {
+ for (i64 i = 0; i < s->next; ++i) {
+ if (s->data[i].ref == ref) return &s->data[i];
+ }
+ return NULL;
+}
+
pit_value pit_expand_macros(pit_runtime *rt, pit_value top) {
i64 expr_stack_reset = rt->expr_stack->next;
i64 result_stack_reset = rt->result_stack->next;
@@ -1066,6 +1097,16 @@ pit_value pit_eval(pit_runtime *rt, pit_value top) {
if (pit_is_cons(rt, cur)) { /* compound expressions: function/macro application special forms */
pit_value fsym = pit_car(rt, cur);
bool is_symbol = pit_is_symbol(rt, fsym);
+ pit_expr_annotation *ann = pit_expr_annotations_lookup(rt->annotations, pit_as_ref(rt, cur));
+ fprintf(stderr, "looking up annotation (%ld): ", pit_as_ref(rt, cur));
+ pit_trace_(rt, "%s\n", cur);
+ if (ann) {
+ fprintf(stderr, "%ld:%ld\n", ann->line, ann->column);
+ rt->source_line = ann->line;
+ rt->source_column = ann->column;
+ } else {
+ fprintf(stderr, "failed to find ann\n");
+ }
if (is_symbol && pit_is_symbol_special_form(rt, fsym)) { /* special forms */
pit_value f = pit_fget(rt, fsym);
pit_value args = pit_cdr(rt, cur);
@@ -1160,6 +1201,7 @@ static pit_value gc_copy_value(pit_runtime *rt, pit_arena *tospace, pit_value v)
}
}
void pit_collect_garbage(pit_runtime *rt) {
+ return; // TODO
rt->frozen_values = 0;
rt->frozen_symtab = 0;
pit_arena *fromspace = rt->heap;
diff --git a/test/error2.pit b/test/error2.pit
new file mode 100644
index 0000000..63ab173
--- /dev/null
+++ b/test/error2.pit
@@ -0,0 +1,4 @@
+(defun! foo ()
+ (error! "yuck"))
+
+(foo)
diff --git a/whereweleftoff.org b/whereweleftoff.org
new file mode 100644
index 0000000..3b89918
--- /dev/null
+++ b/whereweleftoff.org
@@ -0,0 +1,8 @@
+[2026-06-26]
+
+- annotations do not work properly because macroexpansion creates an entirely new body for lambdas
+- we realized that we are handling macro application in two separate places: pit_expand_macros expands lambda bodies, and pit_eval expands macros encountered while evaling. we ought to unify this so that only one is used (probably pit_expand_macros, because we need to expand macros eagerly to identify free variables to capture)
+- we probably can make pit_expand_macros and pit_eval much nicer
+- we can probably make pit_expand_macros operate in place
+- if we want to be really smart, cool, happy, rich:
+ let's just make stuff translate to a little VM before it evaluates, and let's store VM programs as functions instead of sexps