correct sections

This commit is contained in:
2026-02-14 15:13:18 -06:00
parent 8ec56e85fa
commit 86609c27f8
14 changed files with 89 additions and 274 deletions

View File

@@ -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

View File

@@ -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/<pkg>/<stem>.dylib`.
## Platform-Specific Code

View File

@@ -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
│ └── <pkg>/ # per-package subdirectories
├── build/ # ephemeral build cache (safe to delete)
├── cache/ # downloaded archives

View File

@@ -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/
│ └── <content-addressed cache>
├── 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/<pkg>/`. 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.

View File

@@ -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/<pkg>/<stem>.dylib`
3. **Internal symbols** — statically linked into the `pit` binary (fat builds)
4. **Cached .mach blob**binary bytecode in `~/.pit/build/<hash>`
5. **Cached .mcode IR**JSON IR in `~/.pit/build/<hash>.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/<pkg>/<stem>.mach`
5. **Cached bytecode**content-addressed in `~/.pit/build/<hash>` (no extension)
6. **Cached .mcode IR**JSON IR in `~/.pit/build/<hash>.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)
│ ├── <hash> # cached bytecode blobs
── <hash>.mcode # cached JSON IR
│ └── <hash>.o # compiled object files
│ ├── <hash> # cached bytecode or dylib blobs (no extension)
── <hash>.mcode # cached JSON IR
├── cache/ # downloaded package zip archives
├── lock.toml # installed package versions and commit hashes
└── link.toml # local development link overrides