GizStack
View .mdOpen in ChatGPTOpen in Claude

Use the Gizlang command line

This guide shows the daily work with the giz command: make a project, run it, check it, test it, format it, build an executable, update it live, and use packages. It also shows the editor setup and the machine-readable output for AI agents.

  • This guide is task-oriented. The command reference gives each option.
  • Each example shows real output from the current toolchain. Long output is trimmed (…).
  • To install the toolchain, refer to the installation guide.

Before you start

Run giz help. It prints the list of commands and exits with status 0. giz with no arguments does the same.

sh
giz help
giz help check
text
usage: giz COMMAND [ARGUMENT...]

  giz run [--record LOG] [--replay LOG] FILE [ARGUMENT...]  Build FILE (cached) and run it with the arguments.
  giz check [--json] FILE               Check FILE (`.giz`, `.gizgraph` or `package.json`).
  …
  • giz help COMMAND and giz COMMAND --help print the flags, examples and exit codes of one command.
  • An unknown command prints unknown command NAME on stderr and exits with status 2.
  • giz --version (or giz version) prints the identity of the toolchain. giz capabilities gives it as JSON (agents).
  • source <(giz completion bash) loads the bash completion.
  • giz doc NAME prints the docs of a module, a declaration or a command, for example giz doc Json.get.

Make a project

giz init NAME makes a folder with main.giz, main.test.giz and a pinned package.json. You can also make the files yourself, as this section shows.

sh
giz init hello

A program of one or more files

A program is a .giz file with a main function. Relative imports bring in more files. No manifest is necessary.

Make a folder hello with these three files.

main.giz:

main.giz
import {System} from "gizlang:system";
import {greeting} from "./greet.giz";

function main(sys: System): void {
    const args = sys.arguments();
    let name = "world";
    if (args.length > 0) { name = args[0]; }
    print(greeting(name));
}

greet.giz:

greet.giz
export function greeting(name: string): string {
    return "Hello, " + name + ".";
}

greet.test.giz (the tests of greet.giz):

greet.test.giz
import {equal} from "gizlang:test";
import {greeting} from "./greet.giz";

function testGreeting(): void {
    equal(greeting("Ada"), "Hello, Ada.");
}

Run the program:

sh
cd hello
giz main.giz Ada
text
Hello, Ada.

The first run compiles the program. The next runs use the cache: in this test, the first run took 0.66 s and the second run took 0.08 s.

A package project

Use a package.json manifest when you want pinned sources, dependencies or publication. The next section shows the manifest. The Playground also exports a project of this type (start).

The project manifest

The gizlang section of package.json declares the package. It is the same contract that the compiler uses (packages).

json
{
  "name": "geo",
  "version": "1.0.0",
  "gizlang": {
    "entry": { "path": "main.giz" },
    "modules": { "shapes": { "path": "shapes.giz" } }
  },
  "license": "MIT"
}
KeyMeaning
name, versionThe package identity. giz publish uses them.
gizlang.versionThe toolchain release that runs the project; giz installs and runs it in the folder and below (install). giz init from a release writes it.
gizlang.entryThe entry source. Necessary. Its sha256 pin is optional (see below).
gizlang.modulesThe other sources, by module name, each with an optional pin. Use {} when there are no other sources.
gizlang.requiresThe lowest registry versions that the package needs, for example {"geo": "1.0.0"}. giz get writes it.
gizlang.dependenciesPackage folders inside this package (vendor/NAME), each pinned by the sha256 of its package.json. giz get writes it.
native (on an entry or module)The C libraries that the source can declare, for example "native": ["m"].

A module imports another module of its package by name ("shapes"), or a module of a dependency as "geo:shapes".

Pin the sources

A source of your package needs no pin: the compiler reads it from your folder. A source that has a sha256 pin must match it. When you change a pinned source, its pin becomes stale, and the package does not compile:

text
app/3:252: error E_PACKAGE_INTEGRITY: package manifest or pin problem

To refresh the pins, run giz get DIR. For a package without requires, it only writes the pins (and runs npm when the package has npm dependencies). A package that you publish needs its pins, because it becomes a dependency of other packages, and every source of a dependency is pinned.

sh
giz get geo

The command prints nothing and exits with status 0. Then geo/package.json contains the pins:

json
    "entry": {
      "path": "main.giz",
      "sha256": "d4f817e71aebdbbe930308588ec05fe6c5ad2cbcb4d2b47033d55681dc10a611"
    },

For a package with requires, giz get DIR also resolves the requirements from the registry. Use giz pin DIR to refresh only the pins.

giz pin DIR refreshes the pins of DIR/package.json, and of the manifests in its dependency folders first.

Run a program

TaskCommand
Run a filegiz main.giz ARG...
Run a file (the same, explicit)giz run main.giz ARG...
Run a packagegiz package.json ARG...
Record the inputs of a rungiz run --record run.log main.giz ARG...
Run again from the recordgiz run --replay run.log main.giz
sh
giz run main.giz Bob
text
Hello, Bob.

A package runs from its manifest:

sh
giz geo/package.json
text
5

When main returns a value, the CLI prints it. Here main returns distance(Point(3.0, 4.0)).

Scripts

A .giz file can start with #!/usr/bin/env giz. Make it executable, and run it directly. giz must be on PATH.

sh
printf '#!/usr/bin/env giz\nfunction main(): void {\n    print("Hello from a script.");\n}\n' > script.giz
chmod +x script.giz
./script.giz
text
Hello from a script.

Record and replay

--record LOG writes the inputs of the run (arguments and other inputs) to LOG. --replay LOG runs the program again with those inputs.

sh
giz run --record run.log main.giz Zed
giz run --replay run.log main.giz
text
Hello, Zed.
Hello, Zed.

Check a program

giz check FILE checks the types and effects of FILE. FILE is a .giz file, a .gizgraph file or a package.json. Then the command runs the tests of FILE and of each X.test.giz file beside its sources. It runs only the tests whose meaning changed since they passed.

sh
giz check main.giz
text
0 cached, 1 run, 0 failed

An error shows its file, line, column, code and source line. The exit status is 1.

sh
giz check bad.giz
text
bad.giz:2:11: error E_TYPE in main: type mismatch: expected i64, got string
        const n: i64 = "text";
              ^
Exit statusMeaning
0The source checks, and its tests pass.
1An error or a failed test.
2A usage error (for example, no FILE).

For JSON diagnostics without tests, use giz check --json FILE (agents).

Test a program

A test is a function testName(): void with no parameters. It passes when it returns without a fault. The asserts are in gizlang:test (equal, differ, check, includes, equalLines, equalItems).

Run the tests of one file:

sh
giz test greet.test.giz
text
0 cached, 1 run, 0 failed

Run them again. A test that passed at the same meaning does not run again:

text
1 cached, 0 run, 0 failed

The meaning of a test does not include names, comments or layout. Thus a rename or a comment causes no test to run again.

A failed assert shows the values, the line of the test, and a replay test:

text
fail testAdd R004
    gizlang: R004 in equal line 2 (actual = 4, expected = 5) <- testAdd (fail.test.giz:4)
    gizlang: replay: function testReplayEqual(): void { equal(4, 5); }
test runner failed or returned an incomplete verdict (1/1)
0 cached, 1 run, 2 failed
  • giz test FILE runs only the tests in FILE. giz test greet.giz does not run greet.test.giz. Use giz check greet.giz to run both.
  • giz test package.json runs the tests of the package sources.
  • giz test with no argument runs every *.test.giz file under the current folder, outside hidden folders and node_modules.
  • At the top of a Gizlang checkout, giz test with no argument runs the toolchain's own cases and suites; there and below, a FOLDER, a FILTER or --shard I/N runs some of them (the guide to the tests).

Format source files

giz fmt FILE... sets the indentation by bracket depth (4 spaces for each level) and the spaces between tokens. It writes a file only when the tokens stay the same. Thus it cannot change the meaning of a file. Before the layout, it rewrites old spellings, such as join(v, s) and "n=" + string(n), to the modern v.join(s) and `n=${n}`, where the checker proves them the same, and removes unused imports.

sh
giz fmt --check messy.giz main.giz greet.giz
text
messy.giz

--check lists the files that are not formatted, and exits with status 1. Without --check, the command formats the files and lists the changed files.

sh
giz fmt messy.giz

Before:

gizlang
function twice(x:i64):i64{
return x*2;
}

After:

gizlang
function twice(x: i64): i64 {
    return x * 2;
}

Build an executable

giz build FILE -o OUT writes OUT.licenses beside the executable. Keep this file when you distribute the program. Each notice gives the component, its source or system package version, its SPDX identifier and its full license text. The link inputs select the components. A library outside those inputs is not listed. The runtime includes libuv. On Linux and macOS the program loads it from the toolchain's versions folder (libgizlang_runtime.so or .dylib, with OpenSSL), so a copy that runs on a machine without the toolchain is built with GIZLANG_RUNTIME_STATIC=1. The native driver also adds system inputs. The Wasm runtime has no third-party link inputs, so its notice file is empty.

To print the native notices without building an executable, run:

sh
giz licenses main.giz

The text matches the native build's notice file on the same toolchain and system. The command emits link declarations and asks the driver for its link command. It does not run the linker. A missing component mapping, version or license text is an error. The toolchain holds the component mappings and their license texts.

giz build FILE compiles FILE (a .giz file or a package.json) to a native executable for this CPU. It prints the path of the executable.

sh
giz build main.giz -o hello
./hello Eve
text
hello
Hello, Eve.
OptionResult
(none)An executable for any x86-64 or ARM64 CPU, in the build directory (…/build/main). A Linux program runs on glibc 2.35 and later.
-o PATHThe executable at PATH. It may come before or after FILE.
--fastLink fast: -O0. The test runner builds its suites so, and every build inside a suite is linked so too. Do not use it for a program that you ship.
--releaseLink optimized (-O2, ThinLTO) inside a test run as well, for a suite that measures speed.
--storeBuild into the machine store only, with no output file.
--wasmA wasm64 module.

giz run FILE (and running a .giz file directly) is optimized without waiting: it runs the optimized program when the store has it; otherwise it runs a -O0 build at once and builds the optimized one in the background, which the next run takes. run --release waits for the optimized build; run --fast always takes -O0.

  • The build directory is $GIZLANG_CACHE/build for an installed toolchain (environment variables).
  • No build is for the CPU of the machine that builds it, so you can copy an executable to another machine of the same architecture. On x86-64, each function that uses SIMD types also has copies for x86-64-v3 and v4, and runs the copy for the highest level that the CPU has.

WebAssembly

A wasm64 module gets only the console. A program that uses System (for example sys.arguments()) does not link as a module.

sh
giz build --wasm plain.giz -o plain.wasm
giz wasm plain.giz
text
plain.wasm
Hello from wasm.
  • giz wasm FILE runs the module in Node (runtime/wasm.mjs). An installed release does not have this host. It refuses the command and tells you to use build --wasm.

Live updates

giz live FILE runs main. When a .giz file or package.json in the folder of FILE changes, the command builds a new generation. It publishes that code when the code checks. With --tests, it also runs the tests first, also the X.test.giz files, and publishes the code only when they pass. The generation itself holds those tests: the command links no separate test program, and it runs them in a new process that loads the generation (gizlang-live --run-tests). A deployed host (live --accept, deploy --live) always tests a change.

tick.giz:

gizlang
import * as Task from "gizlang:task";

function message(): string {
    return "version 1";
}
function main(): void {
    let i = 0;
    while (i < 40) {
        print(message());
        Task.sleep(500);
        i += 1;
    }
}
sh
giz live tick.giz

Change "version 1" to "version 2" in the file while the program runs. The output (status lines go to standard error):

text
gizlang: generation built: prepare 136 ms, emit 30 ms, tests 5 ms, link 1910 ms
gizlang-live: generation 1 published (10 functions, loaded in 0 ms)
version 1
version 1
…
gizlang: generation built: prepare 9 ms, emit 16 ms, tests 7 ms, link 82 ms
gizlang-live: generation 2 published (10 functions, loaded in 0 ms)
version 2
version 2
…
  • The loop of main keeps the code that it started with. Thus, put the work that you want to change in named functions.

  • When the new code does not check (or, with --tests, a test fails), the program continues with the old code:

    text
    tick.giz:4:5: error E_TYPE in message: type mismatch: expected string, got i64
            return 7;
            ^^^^^^
    gizlang-live: generation rejected; generation 1 keeps running

Deploy to a live host

A deployed program runs under a live host too. Send it only the files that you changed. The process, its named state and its open connections stay.

  1. On the server, run the program as a deployed host. KEYS is a file of the hex Ed25519 public keys that the host trusts, one on each line (giz public-key SEED prints one):

    sh
    giz live --accept 0.0.0.0:7070 --trusted /etc/app/keys \
      --tls-chain /etc/app/chain.pem --tls-key /etc/app/key.pem app/main.giz

    With --tls-chain and --tls-key (a PEM certificate chain and its key) the files travel over TLS. Without them they travel as plain HTTP, readable on the way: use that only on loopback or inside a tunnel.

  2. In the folder of the program on your machine, send the changed files. GIZLANG_SIGNING_KEY is the file of your 32-byte seed:

    sh
    giz deploy --live https://server:7070 --json main.giz
    text
    {"result":"published","generation":2,"error":"","ms":57}

The host writes the files into the folder of its program. Then it checks, tests and compiles them as for an edit, and publishes them into the running process. ms is the time from signing to the new code serving. The host refuses a unit, and the old code keeps serving, when:

CauseStatus
The unit has no signature, a key that the host does not trust, or a signature that does not verify.403
The unit was signed more than 5 minutes from the time of the host, or is older than the last unit taken.403
The compiler or runtime of the sender is not the compiler and runtime of the host.409
The unit does not check, or a test fails. The host takes its files out again.409

The endpoint is plain HTTP. The signature authenticates each unit, but the source is not encrypted. Put a TLS proxy in front of the host when the network is not trusted.

Dependencies and packages

Registries

The registry is $GIZLANG_REGISTRY. It is one of these:

  • a local folder of NAME/VERSION packages;
  • that folder served over HTTP or HTTPS.

When GIZLANG_REGISTRY is not set, the registry is https://gizstack.com/packages. A version never changes after its publication.

The examples below use a local folder registry:

sh
export GIZLANG_REGISTRY="$PWD/registry"

Publish a package

giz publish DIR publishes the package in DIR under the name and version of its manifest. Pin the package first (giz get DIR).

sh
giz publish geo
text
geo@1.0.0

The optional second argument asserts the identity. A different identity fails:

sh
giz publish geo geo@2.0.0
text
gizlang: publish identity does not match package.json

A version that exists already fails:

text
gizlang: geo@1.0.0 is published already or publication failed; a version never changes

The local registry now has registry/geo/1.0.0/ with package.json, main.giz and shapes.giz.

Publication to an HTTPS registry needs GIZLANG_REGISTRY_TOKEN, GIZLANG_REGISTRY_ORG and GIZLANG_REGISTRY_VISIBILITY=public or private. Without them, the command stops with "set GIZLANG_REGISTRY_TOKEN, GIZLANG_REGISTRY_ORG and GIZLANG_REGISTRY_VISIBILITY=public|private to publish". Get the token at gizstack.com/token after you sign in.

Add a dependency

Make a package app that uses geo. app/main.giz:

gizlang
import {Point, distance} from "geo:shapes";
function main(): void {
    print(string(distance(Point(6.0, 8.0))));
}

app/package.json:

json
{
  "name": "app",
  "private": true,
  "gizlang": {
    "entry": { "path": "main.giz", "sha256": "" },
    "modules": {}
  }
}

giz get DIR NAME@VERSION raises the requirement, puts the selected version in DIR/vendor/, and refreshes the pins. It prints each selected package.

sh
giz get app geo@1.0.0
giz app/package.json
text
geo 1.0.0
10

The manifest now has requires and dependencies:

json
    "requires": {
      "geo": "1.0.0"
    },
    "dependencies": {
      "geo": {
        "path": "vendor/geo",
        "sha256": "75009ea412cc175d868e6fd2280ea329ccf16084f5c063acd588a5d01d89fa4a"
      }
    }
  • For each name, get selects the highest version that the requirement graph asks for (minimal version selection). The build changes only when a requirement changes.
  • A new major version is a new name.
  • Run giz get DIR again with no versions to restore the requirements and refresh the pins. This reads the registry. With the default registry, get stops with an error when the registry does not have a required package (for example gizlang: package.json: registry returned HTTP 404).

Validate a package offline

giz get --frozen DIR validates the pinned package closure that is on disk. It does not write files, select versions or use the network. Use it in CI and before a release.

sh
giz get --frozen app
text
geo 1.0.0

A changed dependency source fails:

text
gizlang: vendor/geo/shapes.giz is missing or does not match its sha256

npm packages

giz get DIR npm:NAME@SPEC runs npm install --prefix DIR --save-exact --ignore-scripts and records the package in the npm dependencies of DIR/package.json. Installation scripts never run. A program loads it on the VM in its own process: Vm.javascript(sys).load("NAME") (SYSTEM).

The REPL

giz repl reads, checks, runs and prints. Declarations stay in the session. Statements run after the earlier statements. The REPL prints the value of an expression.

sh
printf 'function square(x: i64): i64 { return x * x; }\nconst n = square(7);\nn + 1\n:quit\n' | giz repl
text
Gizlang REPL. :show, :reset, :quit
giz> giz> giz> 50
giz>

In a terminal, type the same lines after the giz> prompt.

CommandEffect
:showPrints the program of the session.
:resetStarts a new session.
:quitStops the REPL.

An entry continues on the next line while a bracket or a string is open.

Editor setup

giz lsp runs the language server on standard input and output (LSP 3.17). Editors use the same toolchain as the CLI.

The server gives diagnostics on open and change, document symbols, hover with signatures and inferred effects, definitions, references, completion (the members of a value after .), signature help, formatting (as giz fmt), rename (checked by the compiler), semantic tokens, folding ranges and workspace symbols. Positions use UTF-16.

A framed session with an initialize request and a didOpen of a file with a type error gave:

text
{"jsonrpc":"2.0","id":1,"result":{"capabilities":{"positionEncoding":"utf-16","textDocumentSync":{"openClose":true,"change":1},"documentSymbolProvider":true,"hoverProvider":true,"definitionProvider":true,"referencesProvider":true,"completionProvider":{"triggerCharacters":["."]},"signatureHelpProvider":{"triggerCharacters":["(",","],"retriggerCharacters":[")"]},"documentFormattingProvider":true,"renameProvider":{"prepareProvider":true},"semanticTokensProvider":{"legend":{"tokenTypes":["type","enum","interface","function","method","variable"],"tokenModifiers":["declaration"]},"full":true},"foldingRangeProvider":true,"workspaceSymbolProvider":true,"inlayHintProvider":true,"codeActionProvider":{"codeActionKinds":["quickfix"]}},"serverInfo":{"name":"gizlang-lsp","version":"0.1"}}}
{"jsonrpc":"2.0","method":"textDocument/publishDiagnostics","params":{"uri":"file:///…/a.giz","version":1,"diagnostics":[{"range":{"start":{"line":1,"character":10},"end":{"line":1,"character":11}},"severity":1,"code":"E_TYPE","source":"gizlang","message":"E_TYPE in main"}]}}

VS Code

Available Runs today, as shown. Roadmap

The toolchain release carries the Gizlang extension. Install it, and again after each upgrade:

sh
giz vscode

This runs code --install-extension on the release's share/gizlang/vscode/gizlang.vsix.

It starts giz lsp and adds the Test Explorer, debugging (see Debugging), the giz task type and the Run, Debug, Check and Test File commands. Set gizlang.path to your giz when it is not on PATH.

Neovim

For Neovim 0.11 and later, put this in init.lua. The lspconfig plugin is not necessary.

lua
vim.filetype.add({ extension = { giz = 'gizlang' } })
vim.lsp.config('gizlang', {
  cmd = { '/absolute/path/to/gizlang', 'lsp' },
  filetypes = { 'gizlang' },
  root_markers = { 'package.json', '.git' },
})
vim.lsp.enable('gizlang')

Debugging

giz build --debug builds a program for a debugger: unoptimized, with DWARF for its .giz lines, functions, arguments and locals.

sh
giz build --debug main.giz -o app
gdb ./app

In gdb, break main.giz:12 or break total stops there, next and step go by source line, bt shows the Gizlang functions and lines, and info args, info locals and print show values by their Gizlang names:

text
Breakpoint 1, show (n=4, label=...) at main.giz:8
(gdb) info locals
p = {x = 4, y = 1.5}
words = {data = 0x555555a60060, length = 4}
flag = true
(gdb) print *words.data@words.length
$1 = {1, 2, 3, 4}

A string, bytes or Vec value is {data, length}. A record shows its fields. lldb reads the same information.

In VS Code, the Gizlang extension debugs the open file with F5 or Gizlang: Debug File. It builds the file with giz build --debug and runs it under gdb 14 or later (gdb -i=dap), or under lldb-dap with "debugger": "lldb-dap" in launch.json. Breakpoints, stepping, the call stack and the variables work as in any other language:

json
{
  "type": "gizlang",
  "request": "launch",
  "name": "Debug Gizlang file",
  "program": "${file}",
  "args": []
}

Environment variables

VariableEffect
GIZLANG_CACHEThe store of compiled units, test passes and executables. The default is $XDG_CACHE_HOME/gizlang, else $HOME/.cache/gizlang. One store serves all projects on the machine. Once an hour a command removes what nobody used for seven days, then the least recently used files past GIZLANG_CACHE_GB (default 150, at most half of its disk).
GIZLANG_REGISTRYThe package registry: a folder, or an HTTP or HTTPS URL. The default is https://gizstack.com/packages.
GIZLANG_REGISTRY_TOKENThe bearer token for an HTTPS registry. Not sent over plain HTTP.
GIZLANG_REGISTRY_ORG, GIZLANG_REGISTRY_VISIBILITYThe organization and the visibility (public or private) of a remote publication.
GIZLANG_SHARED_CACHE, GIZLANG_TRUSTED_KEYSA shared store of units and executables that other machines built, and the hex Ed25519 public keys (comma separated) whose signatures you accept. A file without a trusted signature is not used.
GIZLANG_SIGNING_KEYA file with a 32-byte Ed25519 seed. The machine signs what it builds, for a shared store.

To set the cache for one command:

sh
GIZLANG_CACHE="$HOME/tmp/gizlang-cache" giz main.giz Cy
text
Hello, Cy.

The cache folder then contains clang, linked, locks, runs and units. You can remove the cache folder. The next command builds again.

The same hourly pass removes the temporary folders of Gizlang programs ($TMPDIR/gizlang-XXXXXX, else /tmp/gizlang-XXXXXX) that are older than a day and that no process has open or works in. These folders are what a program that was killed left behind.

giz public-key SEED prints the public key of a signing seed, for GIZLANG_TRUSTED_KEYS:

sh
giz public-key seed.key
text
1974b90e9fc9dd005bafce07b5914fd1b03c04c5cc18507f2980a2b26ff55a45

Machine-readable output for agents

Humans, editors and agents use the same giz command. Read the exit status together with the output. Refer also to Gizlang for agents.

TaskCommandOutput
Identify the toolchain and its operationsgiz capabilitiesJSON (gizlang.capabilities.v1)
Get source diagnostics, without tests or executiongiz check --json FILEJSON, or nothing
Read declarations, effects and the source hashgiz outline --json FILEJSON
Change declarations in one checked transactiongiz edit FILE (request on standard input)Report, or JSON (gizlang.edit)
Read the declarations about some wordsgiz context FILE WORD...Source text
Read the canonical source, with sugar written outgiz project FILESource text
Make JSON functions for record typesgiz codec FILE TYPE...Source text
Validate pinned packages offlinegiz get --frozen DIROne line for each package

Identify the toolchain

sh
giz capabilities
text
{"schema":"gizlang.capabilities.v1","toolchain":{"id":"c1b4eff5e7c7e66d","runtime":"164448871966e74d","mode":"source","releaseTarget":null,"revision":null,"moduleAbi":null},"operations":[{"command":"FILE.giz","usage":"giz FILE.giz ARG...       run FILE (also as #!/usr/bin/env giz)","available":true,"requiresPrivateSource":false},…],"safety":{…}}
  • operations lists each command with available and requiresPrivateSource.
  • safety states the guarantees, for example: "check --json performs source diagnostics without tests or program execution".
  • The output grants no authority. Keep the same toolchain for all of an operation.

Source diagnostics as JSON

giz check --json FILE prints nothing and exits with 0 when the source checks. It does not run tests. An error is one JSON object, and the exit status is 1:

sh
giz check --json bad.giz
text
{"error":{"code":"E_TYPE","token":8,"error_id":"gizlang.native.E_TYPE.8","stable_id":"main","location":{"buffer":"prepared_input","encoding":"utf8_bytes","start":55,"end":56,"source":{"path":"","start":55,"end":56}},"call_site":null,…,"counterexample":{"available":false,…},"replay":{"available":false,…}}}
  • code is the error code. stable_id names the declaration.
  • The byte offsets in location are offsets in the prepared compiler input, not always in your file. For line and column, use the text output of giz check FILE.

Outline

sh
giz outline greet.giz
text
greet.giz:1  export function greeting(name: string): string  effects {fail}

A script reads the same as JSON:

sh
giz outline --json greet.giz
text
{"hash":"1da311351ed16034","entry":"","declarations":[{"name":"greeting","kind":"function","start":0,"end":85,"location":{"path":"","start":0,"end":85},…,"effects":"fail","exported":true,"parameters":[{"name":"name","type":"string",…}],"result":"string",…}],"files":[…],"symbols":[…],"bindings":[…]}
  • hash is the base of an edit request.
  • For a program of more than one file, location gives the file and the byte span in that file. start and end are offsets in the compiler input.

Edit declarations

giz edit FILE applies a JSON edit request from standard input as one transaction. The edits change declarations by name:

sh
echo '{"base": "1da311351ed16034", "edits": [{"replace": "greeting", "with": "export function greeting(name: string): string { return `Hi, ${name}.`; }"}]}' | giz edit greet.giz
  • An edit is {"replace": NAME, "with": TEXT}, {"delete": NAME} or {"insert": TEXT}. Instead of these, a request can hold only renames ([{"rename": NAME, "to": NEW}]) or one move to another module ([{"move": NAME, "from": MODULE, "to": MODULE}]), which also rewrites the importers.
  • base is the hash of giz outline. When the source changed since then, the edit is refused before anything is written. The edited program must also pass the full check, or no file changes.
  • The report names what changed, the effects that changed, the functions whose behavior can change and the tests that cover them. --json gives it as gizlang.edit.

Context

sh
giz context greet.giz greeting
text
// 1 of 1 declarations mention greeting

export function greeting(name: string): string {
    return "Hello, " + name + ".";
}

Canonical source and codecs

giz project FILE prints the source with sugar written out:

text
function twice(x: i64): i64 {
return (x * 2);
}

giz codec FILE TYPE... prints encodeT, decodeT, writeT and readT for the record types:

sh
giz codec types.giz Item
text
import {JsonReader, JsonError, reader, writeString, writeInteger, writeNumber} from "gizlang:json";
…
export function encodeItem(value: Item): string { let out = b""; writeItem(out, value); return string(out); }
export function decodeItem(text: string): _JsonCodecCore.Result<Item, JsonError> {
…

giz bind HEADER LIB NAME... prints declare lines for the named C functions of a header. Review the lines before you paste them.