From e762a0eb26912ea88b2cb05a6fe40ceffaabbeac Mon Sep 17 00:00:00 2001 From: o1lo01ol1o Date: Wed, 4 Mar 2026 10:38:37 +0000 Subject: [PATCH] Extend FFI API for term graph traversal and book access MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The existing FFI API (ABI v1) exposes enough to write simple primitives that construct and inspect individual terms, but not enough to walk, serialize, or reconstruct arbitrary term graphs. This limits what external plugins can do without modifying HVM4 internals. Bump to ABI v2 and add: Constructors: term_new_era, term_new_ref, term_new_mat Needed to reconstruct complete term graphs including erasure markers, book references, and pattern match nodes. Accessors: term_arity, term_sub_get, term_sub_set Needed to walk term children generically (arity), and to follow or create substitution chains (the SUB bit mechanism that linked binders use for variable resolution). Book/names: table_get, book_get, book_set table_get retrieves a name string by ID (reverse of table_find). book_get/book_set read and write BOOK entries, allowing plugins to inject definitions (e.g. mounting a deserialized term as @name) or read existing ones (e.g. collecting dependencies for serialization). These additions are append-only — existing struct fields are unchanged and existing FFI plugins continue to work after recompilation against the new header (ABI version check catches stale binaries). --- clang/ffi/api.c | 32 ++++++++++++++++++++++++++++---- clang/hvm_ffi.h | 17 +++++++++++++---- 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/clang/ffi/api.c b/clang/ffi/api.c index b9a36d7..6d71552 100644 --- a/clang/ffi/api.c +++ b/clang/ffi/api.c @@ -13,19 +13,34 @@ fn Term term_new_app(Term f, Term x); fn Term term_new_lam_at(u64 loc, Term body); fn Term term_new_lam(Term body); fn Term term_new_var(u64 loc); +fn Term term_new_era(void); +fn Term term_new_ref(u32 nam); +fn Term term_new_mat(u32 nam, Term val, Term nxt); -fn u8 term_tag(Term t); -fn u32 term_ext(Term t); -fn u64 term_val(Term t); +fn u8 term_tag(Term t); +fn u32 term_ext(Term t); +fn u64 term_val(Term t); +fn u32 term_arity(Term t); +fn u8 term_sub_get(Term t); +fn Term term_sub_set(Term t, u8 sub); fn Term heap_read(u64 loc); fn void heap_set(u64 loc, Term t); fn u64 heap_alloc(u64 words); -fn u32 table_find(const char *name, u32 len); +fn u32 table_find(const char *name, u32 len); +fn char *table_get(u32 id); fn void sys_runtime_error(const char *msg); +fn u64 ffi_book_get(u32 id) { + return BOOK[id]; +} + +fn void ffi_book_set(u32 id, u64 loc) { + BOOK[id] = loc; +} + static const HvmApi HVM_API = { .abi_version = ABI_VERSION, @@ -40,10 +55,16 @@ static const HvmApi HVM_API = { .term_new_lam_at = term_new_lam_at, .term_new_lam = term_new_lam, .term_new_var = term_new_var, + .term_new_era = term_new_era, + .term_new_ref = term_new_ref, + .term_new_mat = term_new_mat, .term_tag = term_tag, .term_ext = term_ext, .term_val = term_val, + .term_arity = term_arity, + .term_sub_get = term_sub_get, + .term_sub_set = term_sub_set, .heap_read = heap_read, .heap_set = heap_set, @@ -51,6 +72,9 @@ static const HvmApi HVM_API = { .table_find = table_find, .name_from_str = table_find, + .table_get = table_get, + .book_get = ffi_book_get, + .book_set = ffi_book_set, .runtime_error = sys_runtime_error }; diff --git a/clang/hvm_ffi.h b/clang/hvm_ffi.h index 5bc9d0b..719c05f 100644 --- a/clang/hvm_ffi.h +++ b/clang/hvm_ffi.h @@ -7,7 +7,7 @@ extern "C" { #endif -#define ABI_VERSION 1 +#define ABI_VERSION 2 #ifndef HVM_RUNTIME typedef uint8_t u8; @@ -38,20 +38,29 @@ typedef struct { Term (*term_new_lam_at)(u64 loc, Term body); Term (*term_new_lam)(Term body); Term (*term_new_var)(u64 loc); + Term (*term_new_era)(void); + Term (*term_new_ref)(u32 name); + Term (*term_new_mat)(u32 name, Term hit, Term miss); // accessors u8 (*term_tag)(Term t); u32 (*term_ext)(Term t); u64 (*term_val)(Term t); + u32 (*term_arity)(Term t); + u8 (*term_sub_get)(Term t); + Term (*term_sub_set)(Term t, u8 sub); // heap Term (*heap_read)(u64 loc); void (*heap_set)(u64 loc, Term t); u64 (*heap_alloc)(u64 words); - // names - u32 (*table_find)(const char *name, u32 len); - u32 (*name_from_str)(const char *name, u32 len); + // book / names + u32 (*table_find)(const char *name, u32 len); + u32 (*name_from_str)(const char *name, u32 len); + char *(*table_get)(u32 id); + u64 (*book_get)(u32 id); + void (*book_set)(u32 id, u64 loc); // errors void (*runtime_error)(const char *msg);