diff --git a/docs/actors.md b/docs/actors.md index e25ff919..1e2974a2 100644 --- a/docs/actors.md +++ b/docs/actors.md @@ -224,7 +224,7 @@ use('json') // core json module use('otherlib/foo') // dependency 'otherlib', file foo.cm ``` -Files starting with underscore (`_helper.cm`) are private to the package. +Files in the `internal/` directory are private to the package. ## Example: Simple Actor System diff --git a/docs/c-modules.md b/docs/c-modules.md index 4029eaeb..ee675176 100644 --- a/docs/c-modules.md +++ b/docs/c-modules.md @@ -221,34 +221,6 @@ var n = vector.normalize(3, 4) // {x: 0.6, y: 0.8} var d = vector.dot(1, 0, 0, 1) // 0 ``` -## Combining C and ƿit - -A common pattern is to have a C file provide low-level functions and a `.cm` file provide a higher-level API: - -```c -// _vector_native.c -// ... raw C functions ... -``` - -```javascript -// vector.cm -var native = this // C module passed as 'this' - -var Vector = function(x, y) { - return {x: x, y: y} -} - -Vector.length = function(v) { - return native.length(v.x, v.y) -} - -Vector.normalize = function(v) { - return native.normalize(v.x, v.y) -} - -return Vector -``` - ## Build Process C files are automatically compiled when you run: @@ -258,7 +230,7 @@ pit build pit update ``` -The resulting dynamic library is placed in `~/.pit/lib/`. +Each C file is compiled into a per-file dynamic library at `~/.pit/lib//.dylib`. ## Platform-Specific Code diff --git a/docs/cli.md b/docs/cli.md index a67d631a..c0882fb0 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -161,8 +161,8 @@ pit install /Users/john/work/mylib ``` ~/.pit/ ├── packages/ # installed package sources -├── lib/ # installed per-file dylibs (persistent) -│ ├── core/ # core package dylibs +├── lib/ # installed per-file dylibs and mach (persistent) +│ ├── core/ # core package: .dylib and .mach files │ └── / # per-package subdirectories ├── build/ # ephemeral build cache (safe to delete) ├── cache/ # downloaded archives diff --git a/docs/packages.md b/docs/packages.md index 29576db7..154a1274 100644 --- a/docs/packages.md +++ b/docs/packages.md @@ -19,7 +19,8 @@ mypackage/ ├── helper/ │ └── math.cm # nested module ├── render.c # C extension -└── _internal.cm # private module (underscore prefix) +└── internal/ + └── helpers.cm # private module (internal/ only) ``` ## pit.toml @@ -60,12 +61,12 @@ use('json') // core module ### Private Modules -Files starting with underscore are private: +Files in the `internal/` directory are private to their package: ```javascript -// _internal.cm is only accessible within the same package -use('internal') // OK from same package -use('myapp/internal') // Error from other packages +// internal/helpers.cm is only accessible within the same package +use('internal/helpers') // OK from same package +use('myapp/internal/helpers') // Error from other packages ``` ## Package Locators @@ -105,8 +106,11 @@ Local packages are symlinked into the shop, making development seamless. │ └── work/ │ └── mylib -> /Users/john/work/mylib ├── lib/ -│ ├── local.dylib -│ └── gitea_pockle_world_john_prosperon.dylib +│ ├── core/ +│ │ ├── fd.dylib +│ │ └── time.mach +│ └── gitea_pockle_world_john_prosperon/ +│ └── sprite.dylib ├── build/ │ └── ├── cache/ @@ -171,16 +175,16 @@ pit link delete gitea.pockle.world/john/prosperon ## C Extensions -C files in a package are compiled into a dynamic library: +C files in a package are compiled into per-file dynamic libraries: ``` mypackage/ ├── pit.toml -├── render.c # compiled to mypackage.dylib -└── render.cm # optional ƿit wrapper +├── render.c # compiled to lib/mypackage/render.dylib +└── physics.c # compiled to lib/mypackage/physics.dylib ``` -The library is named after the package and placed in `~/.pit/lib/`. +Each `.c` file gets its own `.dylib` in `~/.pit/lib//`. A `.c` file and `.cm` file with the same stem at the same scope is a build error — use distinct names. See [Writing C Modules](/docs/c-modules/) for details. diff --git a/docs/shop.md b/docs/shop.md index 3ae37a31..e0f49a32 100644 --- a/docs/shop.md +++ b/docs/shop.md @@ -64,28 +64,28 @@ When loading a module, the shop checks (in order): 1. **In-memory cache** — `use_cache[key]`, checked first on every `use()` call 2. **Installed dylib** — per-file `.dylib` in `~/.pit/lib//.dylib` 3. **Internal symbols** — statically linked into the `pit` binary (fat builds) -4. **Cached .mach blob** — binary bytecode in `~/.pit/build/` -5. **Cached .mcode IR** — JSON IR in `~/.pit/build/.mcode` -6. **Adjacent .mach/.mcode** — files alongside the source (e.g., `sprite.mach`) -7. **Source compilation** — full pipeline: analyze, mcode, streamline, serialize +4. **Installed mach** — pre-compiled bytecode in `~/.pit/lib//.mach` +5. **Cached bytecode** — content-addressed in `~/.pit/build/` (no extension) +6. **Cached .mcode IR** — JSON IR in `~/.pit/build/.mcode` +7. **Adjacent .mach/.mcode** — files alongside the source (e.g., `sprite.mach`) +8. **Source compilation** — full pipeline: analyze, mcode, streamline, serialize -Dylib resolution wins over internal symbols, so a dylib in `lib/` can hot-patch a fat binary. Delete the dylib to fall back to the static version. +When both a `.dylib` and `.mach` exist for the same module in `lib/`, the dylib is selected. Dylib resolution also wins over internal symbols, so a dylib in `lib/` can hot-patch a fat binary. Delete the dylib to fall back to mach or static. -Results from steps 5-7 are cached back to the content-addressed store for future loads. +Results from steps 6-8 are cached back to the content-addressed store for future loads. ### Content-Addressed Store -All cached artifacts live in `~/.pit/build/` named by the BLAKE2 hash of their source content: +The build cache at `~/.pit/build/` stores ephemeral artifacts named by the BLAKE2 hash of their inputs: ``` ~/.pit/build/ -├── a1b2c3d4...mach # compiled bytecode blob -├── e5f6a7b8...mach # another compiled module -├── c9d0e1f2...mcode # cached JSON IR -└── f3a4b5c6...macos_arm64.dylib # native compiled module +├── a1b2c3d4... # cached bytecode blob (no extension) +├── c9d0e1f2...mcode # cached JSON IR +└── f3a4b5c6... # compiled dylib (checked before copying to lib/) ``` -This scheme provides automatic cache invalidation: when source changes, its hash changes, and the old cache entry is simply never looked up again. +This scheme provides automatic cache invalidation: when source changes, its hash changes, and the old cache entry is simply never looked up again. When building a dylib, the build cache is checked first — if a matching hash exists, it is copied to `lib/` without recompiling. ### Core Module Caching @@ -110,18 +110,9 @@ symbol: js_gitea_pockle_world_john_prosperon_sprite_use Dylibs are checked first at each resolution scope, so an installed dylib always wins over a statically linked symbol. This enables hot-patching fat binaries by placing a dylib in `lib/`. -### Combined Resolution +### Name Collisions -When both a `.cm` script and a C symbol exist for the same module name, both are resolved. The C module is loaded first (as the base), then the `.cm` script can extend it: - -```javascript -// render.cm — extends the C render module -var c_render = use('internal/render_c') -// Add ƿit-level helpers on top of C functions -return record(c_render, { - draw_circle: function(x, y, r) { /* ... */ } -}) -``` +Having both a `.cm` script and a `.c` file with the same stem at the same scope is a **build error**. For example, `render.cm` and `render.c` in the same directory will fail. Use distinct names — e.g., `render.c` for the C implementation and `render_utils.cm` for the script wrapper. ## Environment Injection @@ -139,9 +130,10 @@ The set of injected capabilities is controlled by `script_inject_for()`, which c ~/.pit/ ├── packages/ # installed packages (directories and symlinks) │ └── core -> ... # symlink to the ƿit core -├── lib/ # INSTALLED per-file dylibs (persistent, human-readable) +├── lib/ # INSTALLED per-file artifacts (persistent, human-readable) │ ├── core/ │ │ ├── fd.dylib +│ │ ├── time.mach │ │ ├── time.dylib │ │ └── internal/ │ │ └── os.dylib @@ -149,9 +141,8 @@ The set of injected capabilities is controlled by `script_inject_for()`, which c │ ├── sprite.dylib │ └── render.dylib ├── build/ # EPHEMERAL cache (safe to delete anytime) -│ ├── # cached bytecode blobs -│ ├── .mcode # cached JSON IR -│ └── .o # compiled object files +│ ├── # cached bytecode or dylib blobs (no extension) +│ └── .mcode # cached JSON IR ├── cache/ # downloaded package zip archives ├── lock.toml # installed package versions and commit hashes └── link.toml # local development link overrides diff --git a/website/content/capi/_index.md b/website/content/capi/_index.md new file mode 100644 index 00000000..252a2088 --- /dev/null +++ b/website/content/capi/_index.md @@ -0,0 +1,5 @@ +--- +title: "C API" +description: "Extending ƿit with native C code" +type: "capi" +--- diff --git a/website/content/cli/_index.md b/website/content/cli/_index.md deleted file mode 100644 index 397dcee5..00000000 --- a/website/content/cli/_index.md +++ /dev/null @@ -1,175 +0,0 @@ ---- -title: "Command Line Interface" -description: "The pit tool" -type: "standalone" ---- - -ƿit provides a command-line interface for managing packages, running scripts, and building applications. - -## Basic Usage - -```bash -pit [arguments] -``` - -## Commands - -### pit version - -Display the ƿit version. - -```bash -pit version -# 0.1.0 -``` - -### pit install - -Install a package to the shop. - -```bash -pit install gitea.pockle.world/john/prosperon -pit install /Users/john/local/mypackage # local path -``` - -### pit update - -Update packages from remote sources. - -```bash -pit update # update all packages -pit update # update specific package -``` - -### pit remove - -Remove a package from the shop. - -```bash -pit remove gitea.pockle.world/john/oldpackage -``` - -### pit list - -List installed packages. - -```bash -pit list # list all installed packages -pit list # list dependencies of a package -``` - -### pit ls - -List modules and actors in a package. - -```bash -pit ls # list files in current project -pit ls # list files in specified package -``` - -### pit build - -Build the current package. - -```bash -pit build -``` - -### pit test - -Run tests. - -```bash -pit test # run tests in current package -pit test all # run all tests -pit test # run tests in specific package -``` - -### pit link - -Manage local package links for development. - -```bash -pit link add # link a package -pit link list # show all links -pit link delete # remove a link -pit link clear # remove all links -``` - -### pit fetch - -Fetch package sources without extracting. - -```bash -pit fetch -``` - -### pit upgrade - -Upgrade the ƿit installation itself. - -```bash -pit upgrade -``` - -### pit clean - -Clean build artifacts. - -```bash -pit clean -``` - -### pit help - -Display help information. - -```bash -pit help -pit help -``` - -## Running Scripts - -Any `.ce` file in the ƿit core can be run as a command: - -```bash -pit version # runs version.ce -pit build # runs build.ce -pit test # runs test.ce -``` - -## Package Locators - -Packages are identified by locators: - -- **Remote**: `gitea.pockle.world/user/repo` -- **Local**: `/absolute/path/to/package` - -```bash -pit install gitea.pockle.world/john/prosperon -pit install /Users/john/work/mylib -``` - -## Configuration - -ƿit stores its data in `~/.pit/`: - -``` -~/.pit/ -├── packages/ # installed packages -├── lib/ # compiled dynamic libraries -├── build/ # build cache -├── cache/ # downloaded archives -├── lock.toml # installed package versions -└── link.toml # local development links -``` - -## Environment - -ƿit reads the `HOME` environment variable to locate the shop directory. - -## Exit Codes - -- `0` — Success -- Non-zero — Error (check output for details) diff --git a/website/content/tools/_index.md b/website/content/tools/_index.md index 9c207dd7..d7a9c361 100644 --- a/website/content/tools/_index.md +++ b/website/content/tools/_index.md @@ -1,5 +1,5 @@ --- -title: "Tools & Packages" -description: "Package management, shop architecture, and development tools" +title: "Packages" +description: "Package management, shop architecture, and the CLI" type: "tools" --- diff --git a/website/data/capi_sections.yaml b/website/data/capi_sections.yaml new file mode 100644 index 00000000..f7774f50 --- /dev/null +++ b/website/data/capi_sections.yaml @@ -0,0 +1,5 @@ +sections: + - title: "Writing C Modules" + page: "/docs/c-modules/" + id: "c-modules" + group: "C API" diff --git a/website/data/docs_nav.yaml b/website/data/docs_nav.yaml index ae68fd7e..97884ca7 100644 --- a/website/data/docs_nav.yaml +++ b/website/data/docs_nav.yaml @@ -7,10 +7,6 @@ sections: url: "/docs/actors/" - title: "Requestors" url: "/docs/requestors/" - - title: "Packages" - url: "/docs/packages/" - - title: "Shop Architecture" - url: "/docs/shop/" - title: "Reference" pages: - title: "Built-in Functions" @@ -37,9 +33,15 @@ sections: url: "/docs/library/json/" - title: "random" url: "/docs/library/random/" - - title: "Tools" + - title: "Packages" pages: + - title: "Packages" + url: "/docs/packages/" + - title: "Shop Architecture" + url: "/docs/shop/" - title: "CLI" url: "/docs/cli/" + - title: "C API" + pages: - title: "C Modules" url: "/docs/c-modules/" diff --git a/website/data/manual_sections.yaml b/website/data/manual_sections.yaml index 056a473e..3ce66051 100644 --- a/website/data/manual_sections.yaml +++ b/website/data/manual_sections.yaml @@ -11,10 +11,6 @@ sections: page: "/docs/requestors/" id: "requestors" group: "Language" - - title: "Packages" - page: "/docs/packages/" - id: "packages" - group: "Language" - title: "Built-in Functions" page: "/docs/functions/" id: "functions" @@ -59,7 +55,3 @@ sections: page: "/docs/library/random/" id: "library-random" group: "Standard Library" - - title: "Writing C Modules" - page: "/docs/c-modules/" - id: "c-modules" - group: "Tools" diff --git a/website/data/tools_sections.yaml b/website/data/tools_sections.yaml index a716f9fa..fe855010 100644 --- a/website/data/tools_sections.yaml +++ b/website/data/tools_sections.yaml @@ -7,15 +7,11 @@ sections: page: "/docs/shop/" id: "shop" group: "Packages" - - title: "Writing C Modules" - page: "/docs/c-modules/" - id: "c-modules" - group: "Development" + - title: "Command Line Interface" + page: "/docs/cli/" + id: "cli" + group: "CLI" - title: "Testing" page: "/docs/testing/" id: "testing" - group: "Development" - - title: "Compiler Tools" - page: "/docs/compiler-tools/" - id: "compiler-tools" - group: "Development" + group: "CLI" diff --git a/website/hugo.toml b/website/hugo.toml index 7af65c40..8d18fcc3 100644 --- a/website/hugo.toml +++ b/website/hugo.toml @@ -21,17 +21,21 @@ theme = 'knr' pageRef = '/manual/' weight = 20 [[menus.main]] - name = 'Spec' - pageRef = '/spec/' + name = 'Packages' + pageRef = '/tools/' weight = 30 [[menus.main]] - name = 'CLI' - pageRef = '/cli/' + name = 'C API' + pageRef = '/capi/' weight = 40 + [[menus.main]] + name = 'Spec' + pageRef = '/spec/' + weight = 50 [[menus.main]] name = 'Contributing' pageRef = '/contributing/' - weight = 50 + weight = 60 [module] [[module.mounts]] diff --git a/website/themes/knr/layouts/capi/list.html b/website/themes/knr/layouts/capi/list.html new file mode 100644 index 00000000..325949da --- /dev/null +++ b/website/themes/knr/layouts/capi/list.html @@ -0,0 +1,19 @@ +{{ define "main" }} +
+ +
+

{{ .Title }}

+ {{ range .Site.Data.capi_sections.sections }} +
+ {{ with $.Site.GetPage .page }} + {{ .Content }} + {{ end }} +
+ {{ end }} +
+
+ +{{ end }}