Add string concatenation in attributes, lazy mixin loading, and benchmarks

Features:
- Fix string concatenation in attribute values (e.g., class="btn btn-" + type)
- Lexer now properly captures full expressions with operators
- Runtime evaluates expressions for class attributes

ViewEngine improvements:
- Change mixin loading from eager to lazy (on-demand)
- Mixins are now loaded from mixins directory only when first called
- Template-defined mixins take precedence over directory mixins

Benchmarks:
- Add src/benchmark.zig with three template complexity levels
- Simple: ~150k renders/sec, 6KB memory
- Medium: ~70k renders/sec, 45KB memory
- Complex: ~32k renders/sec, 94KB memory
- Memory leak detection confirms no leaks

Documentation:
- Update CLAUDE.md with lazy mixin loading details
- Document mixin resolution order
This commit is contained in:
2026-01-17 20:01:37 +05:30
parent 05bbad64a4
commit 1fff91d7d9
7 changed files with 606 additions and 117 deletions

View File

@@ -106,6 +106,26 @@ pub fn build(b: *std.Build) void {
const demo_step = b.step("demo", "Run the template inheritance demo web app");
demo_step.dependOn(&run_demo.step);
// ─────────────────────────────────────────────────────────────────────────
// Benchmark executable
// ─────────────────────────────────────────────────────────────────────────
const bench = b.addExecutable(.{
.name = "bench",
.root_module = b.createModule(.{
.root_source_file = b.path("src/benchmark.zig"),
.target = target,
.optimize = .ReleaseFast, // Always use ReleaseFast for benchmarks
}),
});
b.installArtifact(bench);
const run_bench = b.addRunArtifact(bench);
run_bench.step.dependOn(b.getInstallStep());
const bench_step = b.step("bench", "Run rendering benchmarks");
bench_step.dependOn(&run_bench.step);
// Just like flags, top level steps are also listed in the `--help` menu.
//
// The Zig build system is entirely implemented in userland, which means