Programming Language

Nocter

A self-contained systems language built around simplicity, encapsulation, and foolproof design.

Targets and Distribution

Target Model

Nocter currently has one implemented target, while target-specific behavior remains isolated.

Implemented target:

arm64-darwin

Target properties:

  • CPU architecture: ARM64
  • OS: macOS
  • executable format: Mach-O
  • pointer width: 64-bit
  • usize: u64 range
  • isize: i64 range

Rules:

  • The compiler currently targets only arm64-darwin.
  • Cross compilation beyond arm64-darwin is not supported, but the compiler still models host and target separately.
  • The default active target is the host target.
  • The language grammar, type system, ownership model, borrow rules, regions, and high-level standard-library APIs should not depend on macOS-specific names.
  • Target-specific logic belongs in target backends, primitive lowering, executable writers, and target-gated standard-library declarations.
  • The compiler must not depend on external assemblers, linkers, C toolchains, or external runtimes for any target.
  • A recognized target name is not the same as an implemented target. A target becomes implemented only when its backend, executable writer, primitive set, and target-gated standard-library boundary exist.

Current target-specific standard-library boundary:

~/.nocter/std/internal/os/index.nct

Target-dependent declarations use #target: "..." inside stable ordinary directory modules under std/. The current standard package uses boundaries such as:

~/.nocter/std/internal/os/index.nct
~/.nocter/std/internal/path/index.nct
~/.nocter/std/io/index.nct
~/.nocter/std/fs/index.nct
~/.nocter/std/process/index.nct

Target declarations beyond arm64-darwin are not currently buildable.

Recognized targets:

arm64-darwin    implemented
x64-linux      reserved, not implemented
arm64-linux    reserved, not implemented
x64-windows    reserved, not implemented
arm64-windows  reserved, not implemented

If a reserved target is requested before implementation, the compiler must report a clear error:

error: target x64-linux is recognized but not implemented

Distribution Layout

The downloadable archive name is host-specific, but the archive root and normal user installation directory are host-independent.

Archive name and root:

nocter-v<version>-arm64-darwin.tar.gz

.nocter/
    nocter
    VERSION
    MANIFEST.json
    LICENSE
    NOTICE
    std/

The archive root is always .nocter/. Users install Nocter by extracting the archive so that .nocter/ becomes ~/.nocter/, or by moving the extracted .nocter/ to another chosen Nocter home, then linking the installed nocter binary into a directory already on PATH.

After a trusted Nocter home exists, nocter install can verify and install a local release archive. The command requires a caller-supplied SHA-256 over the complete compressed archive. That digest binds the bytes Nocter validates and extracts; it is not an authenticity mechanism. Users obtain the digest through a separately trusted release channel. Initial bootstrap remains ordinary archive extraction because no trusted Nocter compiler exists yet.

The installed layout is:

~/.nocter/
    nocter
    VERSION
    MANIFEST.json
    LICENSE
    NOTICE
    std/
        prelude/index.nct
        fmt/index.nct
        io/index.nct
        mem/index.nct
        internal/os/index.nct
        process/index.nct
        ptr/index.nct
        string/index.nct
        vec/index.nct

The host part in the archive name identifies the environment that runs the nocter compiler binary. The current host is arm64-darwin, and every archive extracts a .nocter/ root.

The installed Nocter home contains standard-library directory modules under std/. Target-dependent type, helper, and primitive declarations in those modules use #target: "..."; ordinary public wrapper functions remain normal functions. The public surface is owned by the checked standard-library contracts, while the compiler boundary is specified in Standard-Library Primitive and OS Boundary.

Because cross compilation beyond arm64-darwin is not implemented, the default active target is the host target. The arm64-darwin archive contains the compiler that runs on ARM64 macOS, and std/internal/os/index.nct contains the #target: "arm64-darwin" primitive boundary for that target.

Release Metadata

Each Nocter home contains release metadata at its root.

.nocter/
    nocter
    VERSION
    MANIFEST.json
    LICENSE
    NOTICE
    std/

VERSION is a single UTF-8 text line containing the release version:

<version>

MANIFEST.json is structured metadata for tools:

{
  "schema": "nocter.manifest",
  "schema_version": 2,
  "release": "<version>",
  "host": "arm64-darwin",
  "default_target": "arm64-darwin",
  "compiler": {
    "path": "nocter",
    "sha256": "<lowercase SHA-256>"
  },
  "std": {
    "path": "std",
    "tree_sha256": "<lowercase SHA-256>"
  },
  "license": {
    "id": "Apache-2.0",
    "path": "LICENSE",
    "notice": "NOTICE"
  },
  "implemented_targets": [
    {
      "name": "arm64-darwin",
      "backend": "arm64",
      "executable": "macho",
      "os": "darwin"
    }
  ],
  "archive": {
    "name": "nocter-v<version>-arm64-darwin.tar.gz",
    "root": ".nocter"
  }
}

Rules:

  • VERSION, MANIFEST.json, LICENSE, and NOTICE are required in a release archive.
  • VERSION must match MANIFEST.json's release.
  • MANIFEST.json.license.id is Apache-2.0.
  • MANIFEST.json.license.path and MANIFEST.json.license.notice are relative to Nocter home.
  • MANIFEST.json.host identifies the host that runs the bundled nocter binary.
  • MANIFEST.json.default_target is the target used when --target is omitted.
  • MANIFEST.json.implemented_targets lists implemented targets bundled with this Nocter home, not merely reserved target names.
  • compiler.path is nocter and is relative to Nocter home.
  • std.path is std and is relative to Nocter home.
  • compiler.sha256 is SHA-256 over the exact bytes of compiler.path.
  • std.tree_sha256 binds the complete physical regular tree at std.path. The tree hash starts with nocter-regular-tree-v1 followed by a zero byte. Each directory is visited in ascending UTF-8 name order. Every descendant contributes its kind (D or F), normalized /-separated relative-path byte length as big-endian u64, relative UTF-8 path, and content length as big-endian u64; directories use length zero and files then contribute their exact bytes. Symlinks, special files, and non-Unicode paths are invalid.
  • A release <version> uses source tag v<version>.
  • Its ARM64 macOS asset is nocter-v<version>-arm64-darwin.tar.gz.
  • The release checksum authenticates nothing by itself. It supplies content identity only after the user trusts the channel that supplied the checksum.

Nocter Home Resolution

nocter uses an explicit, deterministic Nocter home. It does not silently search unrelated directories.

Resolution order:

  1. 1. If NOCTER_HOME is set, use it as the active Nocter home.
  2. Otherwise, resolve the real path of the running nocter executable and use its parent directory.

Rules:

  • NOCTER_HOME must point to a Nocter home directory, not to std/.
  • The executable path resolution should resolve symlinks when the host can provide the real executable path.
  • cwd/.nocter is not searched automatically.
  • ~/.nocter is not searched automatically.
  • A symlink such as /usr/local/bin/nocter -> ~/.nocter/nocter works naturally because the resolved real executable path still points inside Nocter home.
  • Copying nocter outside Nocter home is not a normal installation method. If executable-path resolution no longer points into Nocter home, the user must set NOCTER_HOME.
  • The running compiler digest must equal compiler.sha256, whether the executable is inside or outside the selected home.
  • The selected home's compiler and standard-library tree must match their manifest digests before the installation can supply a toolchain snapshot. A corrupted or partially updated home is rejected before package or source analysis.
  • The selected standard package must declare package name std and the same release as MANIFEST.json. Package resolution validates this source declaration without duplicating its parser in the installation layer.
  • The selected Nocter home must contain VERSION, MANIFEST.json, and std/.
  • The compiler should report a command-line or Nocter-home error if the selected home is missing required files.

The complete command set, package and file input selection, output naming, and target-option behavior are specified only by the Command Line Interface. This platform chapter defines which targets are implemented and the guarantees an implemented target must provide.

Build profile rules:

  • Language semantics do not define different safety levels for debug and release builds.
  • Profile options must not disable the safety checks specified in Control Flow.
  • A release build may be faster because the optimizer proves checks unnecessary, not because checks are globally removed.

Users install Nocter by placing the extracted .nocter/ directory at ~/.nocter or another location, then creating a symlink named nocter in a directory already on PATH.

Example shell setup:

ln -s "$HOME/.nocter/nocter" /usr/local/bin/nocter

If the target bin directory requires elevated permissions, the user may use sudo ln -s ... or a user-owned directory that is already on PATH. NOCTER_HOME may point to the active Nocter home when symlink-based executable resolution is unavailable or intentionally bypassed.

Future Direction

Additional targets require a target backend, executable writer, primitive set, and target-gated standard-library declarations. Those declarations must remain in the same stable directory modules used by portable code; ordinary programs must not name CPU instructions, object formats, or OS syscall details. Cross compilation will use an explicit target option such as --target x64-linux.

Additional host archives may use names such as nocter-v<version>-x64-linux.tar.gz or nocter-v<version>-arm64-linux.tar.gz, while retaining .nocter/ as their archive root.

Future build-profile options may control optimization level, debug information, and diagnostics, but cannot weaken language safety checks.