# Flash shell helpers. Source from ~/.zshrc: # [[ -f /Users/antonhahn/Flash/flash.env.zsh ]] && source /Users/antonhahn/Flash/flash.env.zsh # # Public interface — one verb dispatcher: # flash build|test|gates|run|emit|tree|fmt|tokens|lsp|version|clean|help # # flash build build flashc (stage0 seed) into zig-out/bin # flash test [suite] run the host suite, or one of: # std | selfhost | flash | lsp | driver # flash gates the full pre-commit gate: test + fixpoint + diff-corpus # flash run transpile a .flash file to stdout # flash emit transpile a .flash file into .zig # flash tree transpile a whole tree, mirroring relative paths # flash fmt [--check] reformat a .flash file in place # flash tokens dump the token stream for a .flash file # flash lsp build flashd, the language server # flash version print the flashc version # flash clean remove .zig-cache and zig-out # flash help this list # # run/emit/tree/fmt/tokens go through flashc-stage1 — the live, self-hosted # compiler. The stage0 seed in zig-out/bin/flashc is frozen at the v0.5 # bootstrap surface and rejects newer grammar, so it is the wrong binary for # day-to-day source work. # Directory of this file, captured at source time (%x still points at the # file being sourced here; inside a function it would name the function). typeset -g _FLASH_DIR="${${(%):-%x}:A:h}" typeset -g _FLASH_RED=$'\033[0;31m' typeset -g _FLASH_GREEN=$'\033[0;32m' typeset -g _FLASH_NC=$'\033[0m' _flash_err() { print -u2 -- "${_FLASH_RED}$*${_FLASH_NC}"; } _flash_ok() { print -- "${_FLASH_GREEN}$*${_FLASH_NC}"; } # Run argv from the project root in a subshell, leaving the caller's cwd alone. _flash_root() { ( cd "$_FLASH_DIR" && "$@" ); } # Build stage1 (quiet on success, build errors still reach stderr) and exec # flashc-stage1 with the given arguments. _flash_stage1() { _flash_root sh -c 'zig build stage1 >/dev/null && exec ./zig-out/bin/flashc-stage1 "$@"' _ "$@" } # Absolutize every non-flag argument, so file paths survive the cd to the # project root. Result in $reply. _flash_abs() { reply=() local a for a in "$@"; do if [[ "$a" == -* ]]; then reply+=("$a"); else reply+=("${a:A}"); fi done } _flash_help() { print -- "flash — dev helpers for the Flash compiler" print -- "" print -- " flash build build flashc (stage0 seed) into zig-out/bin" print -- " flash test [suite] host suite, or: std|selfhost|flash|lsp|driver" print -- " flash gates test + fixpoint + diff-corpus" print -- " flash run transpile a .flash file to stdout" print -- " flash emit transpile a .flash file into .zig" print -- " flash tree transpile a whole tree (mirrors paths)" print -- " flash fmt [--check] reformat a .flash file in place" print -- " flash tokens dump the token stream" print -- " flash lsp build flashd, the language server" print -- " flash version print the flashc version" print -- " flash clean remove .zig-cache and zig-out" print -- " flash help this list" print -- "" print -- " run/emit/tree/fmt/tokens use flashc-stage1 (the live compiler);" print -- " --anchors / --plain-diagnostics pass through to it." } flash() { emulate -L zsh local verb="${1:-help}" (( $# )) && shift case "$verb" in build) _flash_root zig build "$@" ;; test) case "${1:-}" in std|selfhost|flash|lsp|driver) local suite="$1"; shift _flash_root zig build "test-$suite" "$@" ;; *) _flash_root zig build test "$@" ;; esac ;; gates) _flash_root zig build test && _flash_root zig build fixpoint && _flash_root zig build diff-corpus && _flash_ok "gates green: test + fixpoint + diff-corpus" ;; run) [[ -z "$1" ]] && { _flash_err "usage: flash run [flags]"; return 1; } _flash_abs "$@"; _flash_stage1 "${reply[@]}" ;; emit) (( $# < 2 )) && { _flash_err "usage: flash emit [flags]"; return 1; } _flash_abs "$@"; _flash_stage1 "${reply[1]}" -o "${reply[2]}" "${reply[@]:2}" ;; tree) (( $# < 2 )) && { _flash_err "usage: flash tree [flags]"; return 1; } _flash_abs "$@"; _flash_stage1 build "${reply[@]}" ;; fmt) [[ -z "$1" ]] && { _flash_err "usage: flash fmt [--check] "; return 1; } _flash_abs "$@"; _flash_stage1 fmt "${reply[@]}" ;; tokens) [[ -z "$1" ]] && { _flash_err "usage: flash tokens "; return 1; } _flash_abs "$@"; _flash_stage1 --dump-tokens "${reply[@]}" ;; lsp) _flash_root zig build lsp && _flash_ok "flashd built into zig-out/bin" ;; version) _flash_root sh -c 'zig build >/dev/null && exec ./zig-out/bin/flashc --version' ;; clean) _flash_root rm -rf .zig-cache zig-out && _flash_ok "cleaned .zig-cache + zig-out" ;; help|-h|--help) _flash_help ;; *) _flash_err "unknown verb: $verb"; _flash_help; return 1 ;; esac } # Warn once at source time when the installed Zig disagrees with the pin — # build.zig would reject it anyway, this just says so up front. () { local want have [[ -r "$_FLASH_DIR/.zigversion" ]] || return 0 want="$(<"$_FLASH_DIR/.zigversion")" have="$(command zig version 2>/dev/null)" || return 0 [[ "$have" == "$want" ]] || print -u2 -- "${_FLASH_RED}flash: zig $have installed, but the project pins $want (.zigversion)${_FLASH_NC}" } # Verb completion (only when the completion system is initialized). if (( $+functions[compdef] )); then _flash_verbs() { if (( CURRENT == 2 )); then compadd -- build test gates run emit tree fmt tokens lsp version clean help elif [[ "${words[2]}" == "test" ]] && (( CURRENT == 3 )); then compadd -- std selfhost flash lsp driver else _files fi } compdef _flash_verbs flash fi