`ludic syntax [--json] [-o FILE]` prints what `ludicc --emit-syntax` does (a line per entry, or the JSON). `ludic-dev syntax` writes, between "ludic-dev syntax: begin" / "end" lines, the keyword, type, phase and attribute tables of ludic_syntax.h, LudicVocabulary's sets (JetBrains), ludic-mode.el's lists and the language server's word tests (is_keyword_word and the rest; is_contextual_word is every word the parser does not reserve, and every declaring or modifying one), and every TextMate pattern marked "comment": "ludic-dev syntax: <group>" (shared and the VS Code copy). The grammars gain module uses port bind action reducer dispatch registry def open component prop view alias friend unsafe numbers of as from mut system; import and extern colour as declarations; the phase clause knows Overlay; the bitwise pattern matches | and ^ on their own again. `ludic-dev syntax --check` - and check-vocabulary, whose old parser comparison it replaces, and the regression suite (syntax_cases, one line per file) - fails when a written list is behind, when a grammar lacks a keyword, type or phase, when docs/language has no page for a keyword, type, phase or attribute, or when the parser (a scan of selfhost/frontend: is_id / text == words, a == / ann == attributes) tests a word or reads an attribute vocab.ludic lacks, or the reverse. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
153 lines
7.9 KiB
Text
153 lines
7.9 KiB
Text
# ludic-dev — the contributor tool for the Ludic toolchain itself: building the
|
|
# compiler from its IR seed, the regression suites, the docs site, releases.
|
|
#
|
|
# It is a separate binary from `ludic` on purpose. Those two have different
|
|
# audiences and nothing in common but the compile step: a person who installed
|
|
# the language cannot bootstrap a compiler they do not have the source of, and
|
|
# should not have to read past a screen of tasks that only mean something inside
|
|
# this repository. So `ludic` ships and `ludic-dev` does not — it is built from a
|
|
# checkout, lives in bin/, and is left out of every release artifact.
|
|
#
|
|
# From a clean checkout (the one step Ludic cannot do for itself, since compiling
|
|
# Ludic needs a compiler):
|
|
#
|
|
# mkdir -p bin && clang selfhost/ludicc.seed.ll -o bin/ludicc
|
|
# bin/ludicc tools/ludic-cli/dev.ludic -o bin/ludic-dev
|
|
# bin/ludic-dev build
|
|
#
|
|
# Thereafter `ludic-dev build` rebuilds the whole toolchain — bin/ludic, this
|
|
# tool, the compiler, the editor tools. Run it from the repository root.
|
|
program LudicDev {
|
|
import "prelude.ludic"
|
|
import "build.ludic"
|
|
import "split.ludic"
|
|
import "toolchain.ludic"
|
|
import "selfhost.ludic"
|
|
import "tools.ludic"
|
|
import "selfhost_test.ludic"
|
|
import "test.ludic"
|
|
import "json.ludic"
|
|
import "lsp_test.ludic"
|
|
import "forgejo.ludic"
|
|
import "checks.ludic"
|
|
import "syntax_gen.ludic"
|
|
import "docgen.ludic"
|
|
import "docgen_gen.ludic"
|
|
import "docgen_check.ludic"
|
|
import "glgen.ludic"
|
|
import "vkgen.ludic"
|
|
import "shaders.ludic"
|
|
import "assets.ludic"
|
|
import "release.ludic"
|
|
import "pkg.ludic"
|
|
import "pkg_test.ludic"
|
|
|
|
function usage() -> void {
|
|
print("ludic-dev — tasks for a checkout of the Ludic toolchain (run from the repository root)")
|
|
print("")
|
|
print("This is the contributor tool. The language's own command line is `ludic`,")
|
|
print("which ships to users and carries none of the below.")
|
|
print("")
|
|
print("build:")
|
|
print(" build build the whole toolchain into bin/ (ludicc, ludic, ludic-dev, ludic-fmt, ludic-lsp, ludic-ui-preview)")
|
|
print(" build-cli build just bin/ludicc from the IR seed")
|
|
print(" tools [--install] [--test] build the editor toolchain (ludic-fmt, ludic-lsp)")
|
|
print(" clean remove build/")
|
|
print(" fetch-assets [--force] fetch the CC0 Poly Haven assets the rendering examples use")
|
|
print("")
|
|
print("test:")
|
|
print(" test the full regression suite")
|
|
print(" test --coverage per-file line coverage over the test specs")
|
|
print(" test-pkg the package-manager suite (hermetic git repos, offline)")
|
|
print(" selfhost-test the self-hosting suite (correctness + bootstrap fixpoints)")
|
|
print(" test-tools the editor-toolchain suite")
|
|
print(" test-lsp drive bin/ludic-lsp over real LSP traffic (exit 2 = no server)")
|
|
print(" golden regenerate selfhost/golden/renders.sha256 (review with git diff)")
|
|
print("")
|
|
print("doc / lint checks (Ludic, no Python):")
|
|
print(" check-docs every ```ludic doc fence parses (or is marked skip/expect-error)")
|
|
print(" check-impl every implemented feature has a docs/language page")
|
|
print(" check-vocabulary the vocabulary is in sync across grammar / lexer / header / parser")
|
|
print(" syntax [--check] write every grammar's keyword, type and phase lists from ludicc --emit-syntax")
|
|
print(" lint-asset <file> validate one editor .json / .xml asset")
|
|
print(" docs-gen [--out DIR] generate the documentation site (default build/pages)")
|
|
print(" docs-check [DIR] coverage/integrity guard over a generated docs site")
|
|
print(" docs-palette [--check] regenerate emit_color.ludic + palette.json from the palette table")
|
|
print(" glgen [--check] regenerate gl_api.ludic + gl_thunks.ll from the platform gl3.h")
|
|
print(" vkgen [--xml f] [--check] regenerate vk_api.ludic + vk_thunks.ll from the Vulkan registry")
|
|
print(" shaders [--check] build render3d's shader variants to SPIR-V + manifest (Vulkan SDK)")
|
|
print("")
|
|
print("release:")
|
|
print(" release [major|minor|patch] [--dry-run] [--publish]")
|
|
print(" cut a release: CHANGELOG + VERSION bump + tag (+ Forgejo release)")
|
|
print(" publish [vX.Y.Z] publish an already-tagged release; what CI runs on a tag push")
|
|
print(" changelog-section <ver> print that release's CHANGELOG.md section")
|
|
print(" changelog-render <ver> <date> <dir>")
|
|
print(" render a CHANGELOG section from a directory of changesets")
|
|
print("")
|
|
print("self-host internals:")
|
|
print(" selfhost-build [ludicc] [out] assemble + compile the self-host compiler")
|
|
print(" bootstrap the self-hosting fixpoint proof (seeded from bin/ludicc)")
|
|
print(" bootstrap-cfree rebuild the compiler from the seed with no C compiler")
|
|
print(" reseed regenerate selfhost/ludicc.seed.ll after a compiler change")
|
|
print(" game-build <ludicc> <game.ludic> <out> compile a Ludic game (headless)")
|
|
print(" sh-compile <ludicc> <in.ludic> <out> compile + link one .ludic file")
|
|
}
|
|
|
|
function dispatch(cmd: pointer) -> int {
|
|
if (cmd == "build") { return cmd_dev_build() }
|
|
if (cmd == "build-cli") { return cmd_dev_build_cli() }
|
|
if (cmd == "tools") { return cmd_tools() }
|
|
if (cmd == "clean") { return cmd_clean() }
|
|
if (cmd == "test") {
|
|
if (argn(2, "") == "--coverage") { return cmd_test_coverage() }
|
|
return cmd_dev_test()
|
|
}
|
|
if (cmd == "selfhost-test") { return cmd_selfhost_test() }
|
|
if (cmd == "test-tools") { return cmd_test_tools() }
|
|
if (cmd == "test-lsp") { return cmd_test_lsp() }
|
|
if (cmd == "test-pkg") { return cmd_test_pkg() }
|
|
if (cmd == "check-docs") { return cmd_check_docs() }
|
|
if (cmd == "check-impl") { return cmd_check_impl() }
|
|
if (cmd == "check-vocabulary") { return cmd_check_vocab() }
|
|
if (cmd == "syntax") { return cmd_syntax_gen() }
|
|
if (cmd == "lint-asset") { return cmd_lint_asset() }
|
|
if (cmd == "docs-palette") { return cmd_docs_palette() }
|
|
if (cmd == "glgen") { return cmd_glgen() }
|
|
if (cmd == "vkgen") { return cmd_vkgen() }
|
|
if (cmd == "shaders") { return cmd_shaders() }
|
|
if (cmd == "fetch-assets") { return cmd_fetch_assets() }
|
|
if (cmd == "docs-gen") { return cmd_docs_gen() }
|
|
if (cmd == "docs-check") { return cmd_docs_check() }
|
|
if (cmd == "golden") { return cmd_golden() }
|
|
if (cmd == "bootstrap") { return cmd_bootstrap() }
|
|
if (cmd == "bootstrap-cfree") { return cmd_bootstrap_cfree() }
|
|
if (cmd == "reseed") { return cmd_reseed() }
|
|
if (cmd == "selfhost-build") { return cmd_selfhost_build(argn(2, "bin/ludicc"), argn(3, "build/selfhost")) }
|
|
if (cmd == "sh-compile") {
|
|
if (arg_count() < 5) { err("usage: ludic-dev sh-compile <ludicc> <in.ludic> <out>\n"); exit(1) }
|
|
return cmd_sh_compile(arg(2), arg(3), arg(4))
|
|
}
|
|
if (cmd == "game-build") {
|
|
if (arg_count() < 5) { err("usage: ludic-dev game-build <ludicc> <game.ludic> <out>\n"); exit(1) }
|
|
return cmd_game_build(arg(2), arg(3), arg(4))
|
|
}
|
|
if (cmd == "release") { return cmd_release() }
|
|
if (cmd == "changelog-render") { return cmd_changelog_render() }
|
|
if (cmd == "changelog-section") { return cmd_changelog_section() }
|
|
if (cmd == "publish") { return cmd_publish() }
|
|
if (cmd == "help") or (cmd == "--help") or (cmd == "-h") { usage(); return 0 }
|
|
return -1
|
|
}
|
|
|
|
entry {
|
|
if (arg_count() < 2) { usage(); exit(1) }
|
|
let cmd = arg(1)
|
|
let code = dispatch(cmd)
|
|
tmp_cleanup()
|
|
if code >= 0 { exit(code) }
|
|
err(`ludic-dev: unknown task '{cmd}'\n`)
|
|
usage()
|
|
exit(1)
|
|
}
|
|
}
|