Skip to content

Add lib.c and hvm_lib.h for embedding HVM as a library#51

Open
lancejpollard wants to merge 1 commit intoHigherOrderCO:mainfrom
cluesurf:add-lib-entry-point
Open

Add lib.c and hvm_lib.h for embedding HVM as a library#51
lancejpollard wants to merge 1 commit intoHigherOrderCO:mainfrom
cluesurf:add-lib-entry-point

Conversation

@lancejpollard
Copy link
Copy Markdown

@lancejpollard lancejpollard commented Mar 2, 2026

Summary

Adds clang/lib.c and clang/hvm_lib.h so HVM can be compiled as a static or shared library for embedding in other applications.

Since hvm.c uses #define fn static inline, all functions are private. lib.c includes hvm.c and provides non-static wrapper functions that create real linker symbols, following the same single-TU pattern as main.c.

All exported symbols use an hvm_ prefix to avoid name collisions when linked into a host application.

Benefits

  • Enables embedding. Without this, HVM can only be used via the CLI. With lib.c, it can be linked into any C, Rust, Swift, or Kotlin project as a library.
  • Zero architecture change. Follows the same #include "hvm.c" pattern that main.c already uses. No refactoring of the core. The thin wrappers inline away at -O2, so there is no performance cost.
  • Namespaced symbols. The hvm_ prefix prevents collisions when linked into larger applications that may have their own init, free, etc.
  • Supports all targets. The same lib.c compiles for macOS, Linux, iOS (static), Android (shared), and WASM (via emcc). One source file for all platforms.
  • Stable public API. hvm_lib.h gives consumers a versioned header to code against, decoupled from internal function names that may change upstream.

Usage

# Static library
clang -O2 -c lib.c -o hvm.o
ar rcs libhvm.a hvm.o

# Shared library (macOS)
clang -O2 -dynamiclib lib.c -o libhvm.dylib

# Shared library (Linux)
clang -O2 -shared -fPIC lib.c -o libhvm.so -ldl
#include "hvm_lib.h"

int main(void) {
  hvm_init(1, 0, 0, 0);

  u32 main_id;
  char src[] = "@main = 42";
  if (hvm_prepare(&main_id, "inline", src)) {
    Term ref  = hvm_term_new_ref(main_id);
    Term norm = hvm_wnf(ref);
    // use norm...
  }

  hvm_free();
  return 0;
}

Exported API

Category Functions
Lifecycle hvm_init, hvm_free, hvm_prepare, hvm_prepare_text
Evaluation hvm_wnf, hvm_normalize
Constructors hvm_term_new_{num,ctr,sup,dup,app,lam,lam_at,var,ref}
Accessors hvm_term_{tag,ext,val}
Heap hvm_heap_{read,set,alloc}
Table hvm_table_find
Primitives hvm_prim_register

Adds a library entry point (lib.c) and public header (hvm_lib.h) so HVM
can be built as a static or shared library for embedding. lib.c includes
hvm.c and wraps selected static inline functions as real exported symbols
with an hvm_ namespace prefix.

Exported API:
- Lifecycle: hvm_init, hvm_free, hvm_prepare, hvm_prepare_text
- Evaluation: hvm_wnf, hvm_normalize
- Term constructors: hvm_term_new_{num,ctr,sup,dup,app,lam,lam_at,var,ref}
- Term accessors: hvm_term_{tag,ext,val}
- Heap: hvm_heap_{read,set,alloc}
- Symbol table: hvm_table_find
- Primitives: hvm_prim_register

Build:
  clang -O2 -c lib.c -o hvm.o && ar rcs libhvm.a hvm.o
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant