# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview UCL is an embeddable command-based scripting language implemented in Go, with Tcl/shell-like syntax. It is a **library** — there is no root `main.go`. All executables live under `cmd/`. ## Build & Test Commands - **Run all tests:** `make test` (or `go test ./ucl/...`) - **Run a single test:** `go test ./ucl/... -run TestName` - **Run builtin module tests:** `go test ./ucl/builtins/...` - **Build site + WASM playground:** `make site` - **Clean build artifacts:** `make clean` ## Architecture ### Core Package (`ucl/`) The language engine follows a **parse → tree-walk evaluate** pipeline: - **`ast.go`** — AST node types and parser (using `participle` library with struct-tag grammar) - **`eval.go`** — Tree-walk evaluator: scripts, statements, commands, pipelines, arguments, dot-access, string interpolation - **`objs.go`** — Object type system: `StringObject`, `IntObject`, `BoolObject`, `ListObject`, `HashObject`, `TimeObject`, plus proxy types for Go interop via reflection - **`inst.go`** — `Inst` (interpreter instance): the public API for creating and configuring the evaluator - **`builtins.go`** — Built-in functions and macros (control flow, math, collections) - **`env.go`** — `evalCtx`: scoped evaluation context (linked-list chain for variable/command lookup) - **`userbuiltin.go`** — Public embedding API (`BuiltinHandler`, `CallArgs` with reflection-based argument binding) ### Two Command Dispatch Kinds - **Invokables** (`invokable` interface): receive fully-evaluated arguments. Used by all regular functions, Go builtins, user `proc`s, and blocks. - **Macros** (`macroable` interface): receive unevaluated AST + evaluator. Used by `if`, `for`, `while`, `proc`, `try` for lazy evaluation control. ### Optional Builtin Modules (`ucl/builtins/`) Modules (`strs`, `lists`, `itrs`, `fns`, `os`, `fs`, `log`, `csv`, `time`, `urls`) are opt-in via `ucl.WithModule(builtins.Strs())` etc. Each is a self-contained file. ### Other Packages - **`repl/`** — REPL wrapper with `EvalAndDisplay()`, help system, and `AddTypePrinter[T]` generic - **`cmd/cmsh/`** — Interactive shell using `readline` - **`cmd/playwasm/`** — WASM playground (builds with `GOOS=js GOARCH=wasm`) - **`cmd/gendocs/`** — Markdown-to-HTML doc site generator (goldmark + frontmatter) ## Testing Conventions - Tests use `testify/assert` with **table-driven** patterns (`[]struct{ desc, expr string; want any }`) - Test packages use the `_test` suffix for black-box testing - Shared test helpers (e.g., `WithTestBuiltin()`) are in `ucl/builtins_test.go` and provide test-only commands (`firstarg`, `toUpper`, `sjoin`, etc.) ## CI Forgejo workflows in `.forgejo/workflows/`: - `test.yaml` — runs `make test` on `feature/*` branches - `build.yaml` — runs tests + `make site-deploy` on `main`