Commit Graph

145 Commits

Author SHA1 Message Date
3a2376cd49 feat: port AST definitions to Lux (self-hosting)
Translate all 30+ type definitions from src/ast.rs (727 lines Rust)
into Lux ADTs in projects/lux-compiler/ast.lux.

Types ported: Span, Ident, Visibility, Version, VersionConstraint,
BehavioralProperty, WhereClause, ModulePath, ImportDecl, Program,
Declaration, FunctionDecl, Parameter, EffectDecl, EffectOp, TypeDecl,
TypeDef, RecordField, Variant, VariantFields, Migration, HandlerDecl,
HandlerImpl, LetDecl, TraitDecl, TraitMethod, TraitBound, ImplDecl,
TraitConstraint, ImplMethod, TypeExpr, Expr (19 variants), Literal,
LiteralKind, BinaryOp, UnaryOp, Statement, MatchArm, Pattern.

Passes `lux check` and `lux run`.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 02:07:30 -05:00
4dfb04a1b6 chore: sync Cargo.lock with version 0.1.3
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 02:05:51 -05:00
3cdde02eb2 feat: add Int.toFloat/Float.toInt JS backend support and fix Map C codegen
- JS backend: Add Int/Float module dispatch in both Call and EffectOp paths
  for toFloat, toInt, and toString operations
- C backend: Fix lux_strdup → lux_string_dup in Map module codegen

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 02:05:40 -05:00
a5762d0397 feat: add built-in Map type with String keys
Add Map<String, V> as a first-class built-in type for key-value storage,
needed for self-hosting the compiler (parser/typechecker/interpreter all
rely heavily on hashmaps).

- types.rs: Type::Map(K,V) variant, all match arms (unify, apply, etc.)
- interpreter.rs: Value::Map, 12 BuiltinFn variants (new/set/get/contains/
  remove/keys/values/size/isEmpty/fromList/toList/merge), immutable semantics
- typechecker.rs: Map<K,V> resolution in resolve_type
- js_backend.rs: Map as JS Map with emit_map_operation()
- c_backend.rs: LuxMap struct (linear-scan), runtime fns, emit_map_operation()
- main.rs: 12 tests covering all Map operations
- validate.sh: now checks all projects/ directories too

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 01:45:13 -05:00
1132c621c6 fix: allow newlines before then in if/then/else expressions
The parser now skips newlines between the condition and `then` keyword,
enabling multiline if expressions like:
  if long_condition
    then expr1
    else expr2

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 01:38:05 -05:00
a0fff1814e fix: JS backend scoping for let/match/if inside closures
Three related bugs fixed:
- BUG-009: let bindings inside lambdas hoisted to top-level
- BUG-011: match expressions inside lambdas hoisted to top-level
- BUG-012: variable name deduplication leaked across function scopes

Root cause: emit_expr() uses writeln() for statements, but lambdas
captured only the return value, not the emitted statements. Also,
var_substitutions from emit_function() leaked to subsequent code.

Fix: Lambda handler now captures all output emitted during body
evaluation and places it inside the function body. Both emit_function
and Lambda save/restore var_substitutions to prevent cross-scope leaks.
Lambda params are registered as identity substitutions to override any
outer bindings with the same name.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 01:10:55 -05:00
4e9e823246 fix: record spread works with named type aliases
Resolve type aliases (e.g. Player -> { pos: Vec2, speed: Float })
before checking if spread expression is a record type. Previously
{ ...p, field: val } failed with "must be a record type, got Player"
when the variable had a named type annotation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 00:01:20 -05:00
6a2e4a7ac1 chore: bump version to 0.1.3 v0.1.3 2026-02-18 23:06:10 -05:00
3d706cb32b feat: add record spread syntax { ...base, field: val }
Adds spread operator for records, allowing concise record updates:
  let p2 = { ...p, x: 5.0 }

Changes across the full pipeline:
- Lexer: new DotDotDot (...) token
- AST: optional spread field on Record variant
- Parser: detect ... at start of record expression
- Typechecker: merge spread record fields with explicit overrides
- Interpreter: evaluate spread, overlay explicit fields
- JS backend: emit native JS spread syntax
- C backend: copy spread into temp, assign overrides
- Formatter, linter, LSP, symbol table: propagate spread

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 23:05:27 -05:00
7c3bfa9301 feat: add Math.sin, Math.cos, Math.atan2 trig functions
Adds trigonometric functions to the Math module across interpreter,
type system, and C backend. JS backend already supported them.
Also adds #include <math.h> to C preamble and handles Math module
calls through both Call and EffectOp paths in C backend.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 23:05:12 -05:00
b56c5461f1 fix: JS const _ duplication and hardcoded version string
- JS backend now emits wildcard let bindings as side-effect statements
  instead of const _ declarations, fixing SyntaxError on multiple let _ = ...
- Version string now uses env!("CARGO_PKG_VERSION") to auto-sync with Cargo.toml
- Add -lm linker flag for math library support

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 23:05:03 -05:00
61e1469845 feat: add ++ concat operator and auto-invoke main
BUG-004: Add ++ operator for string and list concatenation across all
backends (interpreter, C, JS) with type checking and formatting support.

BUG-001: Auto-invoke top-level `let main = fn () => ...` when main is
a zero-parameter function, instead of just printing the function value.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 22:01:41 -05:00
bb0a288210 chore: bump version to 0.1.2 v0.1.2 2026-02-18 21:16:44 -05:00
5d7f4633e1 docs: add explicit commit instructions to CLAUDE.md
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 21:09:27 -05:00
d05b13d840 fix: JS backend compiles print() to console.log()
Bare `print()` calls in Lux now emit `console.log()` in JS output
instead of undefined `print()`. Fixes BUG-006.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 21:09:07 -05:00
0ee3050704 chore: bump version to 0.1.1 v0.1.1 2026-02-18 20:41:43 -05:00
80b1276f9f fix: release script auto-bumps patch by default
Release script now supports: patch (default), minor, major, or explicit
version. Auto-updates Cargo.toml and flake.nix before building.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 20:41:29 -05:00
bd843d2219 fix: record type aliases now work for unification and field access
Expand type aliases via unify_with_env() everywhere in the type checker,
not just in a few places. This fixes named record types like
`type Vec2 = { x: Float, y: Float }` — they now properly unify with
anonymous records and support field access (v.x, v.y).

Also adds scripts/validate.sh for automated full-suite regression
testing (Rust tests + all 5 package test suites + type checking).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 20:21:29 -05:00
d76aa17b38 feat: static binary builds and automated release script
Switch reqwest from native-tls (openssl) to rustls-tls for a pure-Rust
TLS stack, enabling fully static musl builds. Add `nix build .#static`
for portable Linux binaries and `scripts/release.sh` for automated
Gitea releases with changelog generation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
v0.1.0
2026-02-18 19:09:32 -05:00
c23d9c7078 fix: test runner now supports module imports
The `lux test` command used Parser::parse_source() and
check_program() directly, which meant test files with `import`
statements would fail with type errors. Now uses ModuleLoader
and check_program_with_modules() to properly resolve imports,
and run_with_modules() for execution.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 17:11:16 -05:00
fffacd2467 feat: C backend module import support, Int/Float.toString, Test.assertEqualMsg
The C backend can now compile programs that import user-defined modules.
Module-qualified calls like `mymodule.func(args)` are resolved to prefixed
C functions (e.g., `mymodule_func_lux`), with full support for transitive
imports and effect-passing. Also adds Int.toString/Float.toString to type
system, interpreter, and C backend, and Test.assertEqualMsg for labeled
test assertions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 16:35:24 -05:00
2ae2c132e5 docs: add language philosophy document and compiler integration
Write comprehensive PHILOSOPHY.md covering Lux's six core principles
(explicit over implicit, composition over configuration, safety without
ceremony, practical over academic, one right way, tools are the language)
with detailed comparisons against JS/TS, Python, Rust, Go, Java/C#,
Haskell/Elm, and Gleam/Elixir. Includes tooling audit and improvement
suggestions.

Add `lux philosophy` command to the compiler, update help screen with
abbreviated philosophy, and link from README.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 10:19:29 -05:00
4909ff9fff docs: add package ecosystem plan and error documentation workflow
Add PACKAGES.md analyzing the Lux package ecosystem gaps vs stdlib,
with prioritized implementation plans for markdown, xml, rss, frontmatter,
path, and sitemap packages. Add CLAUDE.md instructions for documenting
Lux language errors in ISSUES.md during every major task.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 10:01:56 -05:00
8e788c8a9f fix: embed C compiler path at build time for self-contained binary
build.rs captures the absolute path to cc/gcc/clang during compilation
and bakes it into the binary. On Nix systems this embeds the full
/nix/store path so `lux compile` works without cc on PATH.

Lookup order: $CC env var > embedded build-time path > PATH search.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 08:12:18 -05:00
dbdd3cca57 chore: move blu-site to its own repo at ~/src/blu-site
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 07:57:55 -05:00
3ac022c04a chore: gitignore build output (_site/, docs/)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 07:48:51 -05:00
6bedd37ac7 fix: show help menu when running lux with no arguments
Previously `lux` with no args entered the REPL. Now it shows the help
menu. Use `lux repl` to start the REPL explicitly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 07:34:09 -05:00
2909bf14b6 fix: eliminate all non-json C backend errors (79→0)
Second round of C backend fixes, building on d8871ac which reduced
errors from 286 to 111. This eliminates all 79 non-json errors:

- Fix function references as values (wrap in LuxClosure*)
- Fix fold/map/filter with type-aware calling conventions
- Add String.indexOf/lastIndexOf emission and C runtime functions
- Add File.readDir with dirent.h implementation
- Fix string concat in closure bodies
- Exclude ADT constructors from closure free variable capture
- Fix match result type inference (prioritize pattern binding types)
- Fix Option inner type inference (usage-based for List.head)
- Fix void* to struct cast (dereference through pointer)
- Handle constructors in emit_expr_with_env

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 05:56:21 -05:00
d8871acf7e fix: improve C backend robustness, reduce compilation errors by 61%
- Fix closure captured variable types: look up actual types from var_types
  instead of hardcoding LuxInt for all captured variables
- Register function parameters in var_types so closures can find their types
- Replace is_string_expr() with infer_expr_type() for more accurate string
  detection in binary ops (concat, comparison)
- Add missing String operations to infer_expr_type (substring, indexOf, etc.)
- Add module method call type inference (String.*, List.*, Int.*, Float.*)
- Add built-in Result type (Ok/Err) to C prelude alongside Option
- Register Ok/Err/Some/None in variant_to_type and variant_field_types
- Fix variable scoping: use if-statement pattern instead of ternary when
  branches emit statements (prevents redefinition of h2/h3 etc.)
- Add RC scope management for if-else branches and match arms to prevent
  undeclared variable errors from cleanup code
- Add infer_pattern_binding_type for better match result type inference
- Add expr_emits_statements helper to detect statement-emitting expressions
- Add infer_option_inner_type for String.indexOf (returns Option<Int>)

Reduces blu-site compilation errors from 286 to 111 (remaining are mostly
unsupported json effect and function-as-value references).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 17:56:27 -05:00
73b5eee664 docs: add commit-after-every-piece-of-work instruction to CLAUDE.md
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 16:21:54 -05:00
542255780d feat: add tuple index access, multiline args, and effect unification fix
- Tuple index: `pair.0`, `pair.1` syntax across parser, typechecker,
  interpreter, C/JS backends, formatter, linter, and symbol table
- Multi-line function args: allow newlines inside argument lists
- Fix effect unification for callback parameters (empty expected
  effects means "no constraint", not "must be pure")

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 16:21:48 -05:00
bac63bab2a feat: add blu-site static site generator and fix language issues
Build a complete static site generator in Lux that faithfully clones
blu.cx (elmstatic). Generates 14 post pages, section indexes, tag pages,
and a home page with snippets grid from markdown content.

Language fixes discovered during development:
- Add \{ and \} escape sequences in string literals (lexer)
- Register String.indexOf and String.lastIndexOf in type checker
- Fix formatter to preserve brace escapes in string literals
- Improve LSP hover to show documentation for let bindings and functions

ISSUES.md documents 15 Lux language limitations found during the project.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 15:43:05 -05:00
db82ca1a1c fix: improve LSP hover to show function info when cursor is on fn keyword
When hovering on declaration keywords (fn, type, effect, let, trait),
look ahead to find the declaration name and show that symbol's full
info from the symbol table instead of generic keyword documentation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 08:32:01 -05:00
98605d2b70 feat: add self-hosted Lux lexer as first step toward bootstrapping
The lexer tokenizes Lux source code written entirely in Lux itself.
Supports all token types: keywords, operators, literals, behavioral
properties, doc comments, and delimiters.

This is the first component of the Lux-in-Lux compiler, demonstrating
that Lux's pattern matching, recursion, and string handling are
sufficient for compiler construction.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 08:25:22 -05:00
e3b6f4322a fix: add Char pattern matching and Char comparison operators
- Parser: support Char literals in match patterns (e.g., 'x' => ...)
- Interpreter: add Char comparison for <, <=, >, >= operators
  Previously only Int, Float, and String supported ordering comparisons.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 08:25:15 -05:00
d26fd975d1 feat: enhance LSP with inlay hints, parameter hints, and improved hover
Add inlay type hints for let bindings, parameter name hints at call sites,
behavioral property documentation in hover, and long signature wrapping.

- Inlay hints: show inferred types for let bindings without annotations
- Parameter hints: show param names at call sites for multi-arg functions
- Hover: wrap long signatures, show behavioral property docs (pure, total, etc.)
- Rich docs: detailed hover for keywords like pure, total, idempotent, run, with
- TypeChecker: expose get_inferred_type() for LSP consumption
- Symbol table: include behavioral properties in function type signatures

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 08:06:36 -05:00
1fa599f856 fix: support comma-separated behavioral properties without repeating 'is'
Allows `is pure, commutative` syntax in addition to `is pure is commutative`.
After the initial `is`, comma-separated properties no longer require repeating
the `is` keyword (though it's still accepted for compatibility).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 07:44:18 -05:00
c2404a5ec1 docs: update CLAUDE.md with post-work checklist and CLI aliases table
Adds the post-work checklist (cargo check, cargo test, lux check, lux fmt,
lux lint) and documents all CLI command aliases. Updates test count to 381.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 07:36:09 -05:00
19068ead96 feat: add lux lint command with Lux-specific static analysis
Implements a linter with 21 lint rules across 6 categories (correctness,
suspicious, idiom, performance, style, pedantic). Lux-specific lints include
could-be-pure, could-be-total, unnecessary-effect-decl, and single-arm-match.
Integrates lints into `lux check` for unified type+lint checking. Available
standalone via `lux lint` (alias: `lux l`) with --explain for detailed help.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 07:35:36 -05:00
44ea1eebb0 style: auto-format example files with lux fmt
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 06:52:44 -05:00
8c90d5a8dc feat: CLI UX overhaul with colored output, timing, shorthands, and fuzzy suggestions
Add polished CLI output across all commands: colored help text, green/red
pass/fail indicators (✓/✗), elapsed timing on compile/check/test/fmt,
command shorthands (c/t/f/s/k), fuzzy "did you mean?" on typos, and
smart port-in-use suggestions for serve. Respects NO_COLOR/TERM=dumb.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 06:52:36 -05:00
bc60f1c8f1 fix: improve error message for bare 'run' expressions at top level
When users write `run main() with {}` at top level instead of
`let _ = run main() with {}`, provide a helpful error message
explaining the correct syntax instead of the generic "Expected
declaration" error.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-16 23:40:15 -05:00
52e3876b81 feat: add projects showcase and Lux-powered static file server
- Add website/serve.lux: static file server using HttpServer effect
  - Demonstrates serving the Lux website with Lux itself
  - Handles index files, clean URLs, and 404 responses

- Add website/projects/index.html: example projects showcase
  - Features 6 real project cards (REST API, Todo App, JSON Parser, etc.)
  - Highlights Task Manager API demonstrating all 3 killer features
  - Links to full source code in the repository

- Update examples sidebar with Projects section

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-16 23:34:17 -05:00
7e76acab18 feat: rebuild website with full learning funnel
Website rebuilt from scratch based on analysis of 11 beloved language
websites (Elm, Zig, Gleam, Swift, Kotlin, Haskell, OCaml, Crystal, Roc,
Rust, Go).

New website structure:
- Homepage with hero, playground, three pillars, install guide
- Language Tour with interactive lessons (hello world, types, effects)
- Examples cookbook with categorized sidebar
- API documentation index
- Installation guide (Nix and source)
- Sleek/noble design (black/gold, serif typography)

Also includes:
- New stdlib/json.lux module for JSON serialization
- Enhanced stdlib/http.lux with middleware and routing
- New string functions (charAt, indexOf, lastIndexOf, repeat)
- LSP improvements (rename, signature help, formatting)
- Package manager transitive dependency resolution
- Updated documentation for effects and stdlib
- New showcase example (task_manager.lux)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-16 23:05:35 -05:00
5a853702d1 fix: C backend string comparison, underscore patterns, and list memory
1. String == comparison now uses strcmp instead of pointer comparison
   - Added check in emit_expr() for BinaryOp::Eq/Ne on strings
   - Also fixed in emit_expr_with_env() for closures

2. Support `let _ = expr` pattern to discard values
   - Parser now accepts underscore in let bindings (both blocks and expressions)
   - C backend emits (void)expr; for underscore patterns

3. Fix list head/tail/get memory management
   - Added lux_incref() when extracting elements from lists
   - Prevents use-after-free when original list is freed

4. String.startsWith was already implemented (verified working)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-16 07:14:02 -05:00
fe985c96f5 feat: redesign website to showcase all Lux capabilities
- New tagline: "The Language That Changes Everything"
- Highlight 6 key features: algebraic effects, behavioral types,
  schema evolution, dual compilation, native performance, batteries included
- Add sections for behavioral types (is pure, is total, is idempotent)
- Add section for schema evolution with migration examples
- Add section for dual compilation (C and JavaScript)
- Add "Why Lux?" comparisons (vs Haskell, Rust, Go, TypeScript, Elm, Zig)
- Add built-in effects showcase (Console, File, Http, Sql, etc.)
- Add developer tools section (package manager, LSP, REPL, etc.)
- Fix navigation to use anchor links (single-page site)
- Update footer to link to GitHub docs/examples
- Add README with local testing instructions

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-16 06:59:16 -05:00
4b553031fd fix: parser newline handling in lists and stdlib exports
- Fix parse_list_expr to skip newlines between list elements
- Add `pub` keyword to all exported functions in stdlib/html.lux
- Change List.foldl to List.fold (matching built-in name)
- Update weaknesses document with fixed issues

The module import system now works correctly. This enables:
- import stdlib/html to work as expected
- html.div(), html.render() etc. to be accessible
- Multi-line list expressions in Lux source files

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-16 06:51:37 -05:00
552e7a4972 feat: create Lux website with sleek/noble aesthetic
Website design:
- Translucent black (#0a0a0a) with gold (#d4af37) accents
- Strong serif typography (Playfair Display, Source Serif Pro)
- Glass-morphism cards with gold borders
- Responsive layout with elegant animations

Content:
- Landing page with hero, code demo, value props, benchmarks
- Effects-focused messaging ("No surprises. No hidden side effects.")
- Performance benchmarks showing Lux matches C
- Quick start guide

Technical:
- Added HTML rendering functions to stdlib/html.lux
- Created Lux-based site generator (blocked by module import issues)
- Documented Lux weaknesses discovered during development:
  - Module import system not working
  - FileSystem effect incomplete
  - No template string support

The landing page HTML/CSS is complete and viewable.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-16 06:41:49 -05:00
49ab70829a feat: add comprehensive benchmark suite with flake commands
- Add nix flake commands: bench, bench-poop, bench-quick
- Add hyperfine and poop to devShell
- Document benchmark results with hyperfine/poop output
- Explain why Lux matches C (gcc's recursion optimization)
- Add HTTP server benchmark files (C, Rust, Zig)
- Add Zig versions of all benchmarks

Key findings:
- Lux (compiled): 28.1ms - fastest
- C (gcc -O3): 29.0ms - 1.03x slower
- Rust: 41.2ms - 1.47x slower
- Zig: 47.0ms - 1.67x slower

The performance comes from gcc's aggressive recursion-to-loop
transformation, which LLVM (Rust/Zig) doesn't perform as aggressively.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-16 05:53:10 -05:00
8a001a8f26 fix: C backend struct ordering enables native compilation
The LuxList struct body was defined after functions that used it,
causing "invalid use of incomplete typedef" errors. Moved struct
definition earlier, right after the forward declaration.

Compiled Lux now works and achieves C-level performance:
- Lux (compiled): 0.030s
- C (gcc -O3): 0.028s
- Rust: 0.041s
- Zig: 0.046s

Updated benchmark documentation with accurate measurements for
both compiled and interpreted modes.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-16 05:14:49 -05:00