No description
  • Swift 79.6%
  • C 19.4%
  • C++ 1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-11-09 20:21:00 -05:00
CFFI Initial commit 2026-11-09 20:21:00 -05:00
Host Initial commit 2026-11-09 20:21:00 -05:00
klir Initial commit 2026-11-09 20:21:00 -05:00
klnl/recipekl/parser Initial commit 2026-11-09 20:21:00 -05:00
Native Initial commit 2026-11-09 20:21:00 -05:00
Sources Initial commit 2026-11-09 20:21:00 -05:00
Tests/recipeKLTests Initial commit 2026-11-09 20:21:00 -05:00
README.md Initial commit 2026-11-09 20:21:00 -05:00

KLIR host and recipeKL implementation

Swift currently implements KLIR assembly, module loading, hashing, locks, linking, the VM, primitive host operations, and the generic libffi call bridge. Recipe grammar and evaluation live in KLIRT under klnl/recipekl/parser. String, dictionary, AST, platform, and Git policy modules are also in KLIRT. Host capability migration into KLIR is incomplete, and this README describes the current implementation rather than the intended final boundary.

swift build
swift test
.build/debug/klir run recipeKL/klnl/recipekl/parser/recipe.klirt klnlPm/platforms/linux/porter/debian/debian.klnl
.build/debug/klir compile recipeKL/klnl/recipekl/parser/recipe.klirt /tmp/recipe.klir
.build/debug/klir run /tmp/recipe.klir klnlPm/platforms/linux/porter/debian/debian.klnl

File commands create a .lock sidecar on first use and verify it thereafter. Locks cover the complete linked instruction model, including included functions and extern library paths and symbol declarations. They do not hash external library contents or host implementations. Compiled .klir artifacts use canonical JSON. After reviewing a source change, explicitly update its lock.

.build/debug/klir lock recipeKL/klnl/recipekl/parser/recipe.klirt

KLIR and externs

KLIR v2 supports local variables, shared per-run globals, functions, recursion, dynamic application and labels. Calls share a one million instruction budget and a maximum depth of 256. Checked arithmetic, invalid operands and exhausted limits report errors. Includes resolve relative to their including module, are deduplicated by resolved path and reject cycles and duplicate functions. Use one interpreter per concurrent execution.

klir 2
func twice value
load value
load value
add
return
end
const int 21
call twice 1
halt

Instructions include const, load, store, getglobal, setglobal, add, sub, mul, div, eq, concat, dup, pop, jump, jump_false, call, apply, return, halt and extern. Constants support integers, booleans, null and JSON quoted strings. apply consumes a function name and a list of arguments. KLIR functions take precedence over host externs.

Recipe source declares typed native functions directly. A library opens only when the first call occurs, and libffi dispatches the declared C ABI.

extern fn nativeSum(left: Int64, right: Int64): Int64 from "libexample.so" as "native_sum";
result = nativeSum(20, 22);

The supported C types are Int64, Int32, UInt64, UInt32, Bool, CString, Pointer, and Void. Every argument and return type is explicit.

#include <stdint.h>
int64_t native_sum(int64_t left, int64_t right);

The standard libraries use soname-based linking for libc and libssh2. Other shared libraries must be present on the selected platform and target.

Native compilation

KLIRNativeCompiler.llvmIR directly lowers scalar KLIR instructions to LLVM basic blocks. It supports integer, boolean and null values, checked arithmetic, equality, local and global variables, branches, functions and declared integer C externs. Dynamic libraries load lazily in the native runtime too. Unsupported instructions and values fail compilation. There is no VM fallback inside generated executables.

The optional object backend uses swiftlang/swift-llvm-bindings, pinned in Package.swift. Its StringRef bridge passes generated IR to Native/LLVM.cpp, which parses and verifies the module and emits a host object through LLVM's target machine. Clang compiles the small C runtime and links the executable. Generated executables require the C runtime and system loader, but do not require Swift or LLVM at execution time.

A working Swift C++ interoperability toolchain, LLVM development headers, a shared libLLVM, matching C++ standard-library headers and Clang are required. Normal VM builds have no LLVM dependency. On a configured development system, use the helper to set the upstream binding's header variables.

KLIR_LLVM_PREFIX=/path/to/llvm scripts/native-swift build --scratch-path .build/native
.build/native/debug/klir native recipeKL/klir/arithmetic.klirt /tmp/arithmetic /path/to/clang
/tmp/arithmetic

KLIR_LLVM_BINDINGS_CHECKOUT optionally selects a local checkout instead of the pinned remote package. KLIR_CLANG supplies the CLI's default linker path. Select a C++ standard library matching LLVM's ABI and configure its include and library paths for your toolchain.

The LLVM bindings object backend could not be validated on the current development host. Swift 6.3.3's embedded Clang fails while importing the installed GCC 16 C++ standard-library overlay. The bridge C++ source compiles against LLVM 23, and tests independently compile the generated LLVM IR with Clang and execute scalar programs, dynamic externs and runtime error cases. They exercise the binding object backend instead when it is enabled and builds successfully.

LLVM text emission also works in the default build and can be inspected independently.

.build/debug/klir emit-llvm recipeKL/klir/arithmetic.klirt /tmp/arithmetic.ll

The generated native runtime supports strings, lists, objects, apply, bundled source imports and the recipe parser's functional evaluation path. Some host services remain VM-only, so native compilation rejects unsupported calls.

Recipe grammar

The entry module is klnl/recipekl/parser/recipe.klirt, with source supplied as its initial source variable. The full root README recipe example is a regression fixture. Its namespace and using declarations, named blocks, timer metadata, scoped enum members, callable bracket arguments, list and dictionary indexing, receiver join calls, build descriptors and normalization tables parse and evaluate in KLIR. Evaluation of that example requires a caller-supplied profile.install_prefix. The test supplies a profile block explicitly.

The lexer handles comments, Unicode strings, integer literals and scalar offsets. Expressions support references, literals, lists, object bindings, parentheses, member access, calls, unary minus, arithmetic, lambdas, named functions, conditionals, matching, and functional list operations. Bindings evaluate in source order and nested blocks can read outer bindings. Repeated namespace declarations merge their contents. using brings a namespace's members into the current environment. import "./module.klnl" as Module evaluates a file module and exposes only declarations marked with export.

Recipe source declares typed, lazy native bindings with extern fn name(value: Int64): Int64 from "libc.so.6" as "labs";. The runtime resolves the library and symbol on first call, then passes the declared signature through libffi. Supported scalar signatures include signed and unsigned integers, booleans, strings, pointers, and void results. No library-specific C wrapper is needed. Binding declarations remain part of the recipe module and use the generic dynamic extern path.

Normalization descriptors preserve glob patterns, capture selectors, output tokens and nested tables, including @apply[:base]($1). The KLIR normalizer matches glob captures and applies nested rules. Timers, Git source descriptors and build configuration have no execution effects during recipe evaluation. fakehash is an explicit unverified placeholder, never a successful integrity check. The type system checks basic annotations, aliases, record schemas, and object literal fields returned through named interfaces. Generic inference and exhaustive pattern coverage remain limited. Internal call inference still has a dynamic fallback, so static soundness is unfinished.

Standard libraries

The project libraries in ../libs use explicit imports, exported recipeKL functions, record interfaces, and typed libffi externs. libPOSIX binds libc process, identity, file access, permission, and terminal calls. libSSH binds libssh2 initialization functions. libWeb combines typed route functions with direct libc socket calls. It does not yet provide a complete HTTP server loop.

core/core/ast.klirt provides a persistent bottom-up ast.transform traversal with a named KLIR visitor. The core modules follow the README's library structure, with dedicated string, dictionary, command, platform and provider modules.