一键导入
verona-conventions
Verona compiler coding conventions, C++ style, trieste patterns, and project structure. Applies when writing or reviewing Verona compiler code.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Verona compiler coding conventions, C++ style, trieste patterns, and project structure. Applies when writing or reviewing Verona compiler code.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Structured debugging protocol with checkpoints. Load when debugging non-trivial issues — before forming any hypothesis about the cause.
Verona compiler test suite infrastructure — running tests, updating golden files, verifying pass completeness, checking error codes. Use when debugging test failures, regenerating golden files, or understanding the test framework.
Patterns, pitfalls, and idioms for writing Verona source code (.v files). Use when writing library code, _builtin types, or user programs.
Patterns, pitfalls, and idioms for writing Verona source code (.v files). Use when writing library code, _builtin types, or user programs.
Verona compiler type inference model — bidirectional refinement, per-function inference, lambda/context propagation, algebraic and structural typing, generics, and debugging. Use when changing or debugging `vc/passes/infer.cc` or investigating type inference failures.
Create a new Verona compiler test case. Use when the user wants to add a test, create a test, or scaffold a test for the compiler.
| name | verona-conventions |
| description | Verona compiler coding conventions, C++ style, trieste patterns, and project structure. Applies when writing or reviewing Verona compiler code. |
| user-invocable | false |
snake_case for functions, variables, namespaces. PascalCase for types/classes.PascalCase: inline const auto TypeName = TokenDef(...).goto. Use flags, early returns, or helper functions.#pragma once, not include guards.constexpr/consteval, structured bindings, if constexpr, std::span, [[nodiscard]].static constexpr over #define for constants.Node n = SomeToken creates a node. NOT auto n = SomeToken (copies TokenDef).n / ChildToken (named WF accessor), not n->at(i) (positional).node << child. Set value: node ^ value. Duplicate: clone().clone() nodes inserted into multiple AST locations.node->type() == OtherToken, NOT node == other_node (compares pointers).err(node, "message") wraps in Error << ErrorMsg << ErrorAst.traverse() iterators are invalidated by replace()/erase(). Collect first, mutate after.<<= for children, ++ for zero-or-more, | for choices.lookup() walks up + follows includes. lookdown() searches own symtab only, no includes. look() is immediate, no flags.PassDef with name, WF, direction (dir::topdown/dir::bottomup/dir::once), rewrite rules. pre()/post() hooks.build/ directory. ninja install to build. Use dist/vc/vc and dist/vbci/vbci (installed binaries have _builtin).ninja install before debugging or validating compiler/runtime behavior on the current branch.vc from build/: dist/vc/vc build ../testsuite/v/hello. Do NOT cd into source dir.dist/ tree. Do not use non-installed build outputs when validating behavior.ctest --output-on-failure -j$(nproc) for full test suite.-p <passname> stops after a pass. --dump_passes=<dir> dumps intermediate ASTs.ninja update-dump-clean && ninja update-dump && cmake ..exit_code.txt has NO trailing newline (printf '0', not echo).testsuite/v/ must be self-contained. No external deps, no use "https://...".use "_builtin" — it is always implicitly available.var result = 0; then if cond { result = result + N; } with powers of 2. Exit 0 = all passed.exit_code.txt: 1 in compile/, no run/ directory.testsuite/v/<name>/<name>.v with golden dirs <name>/<name>/compile/ and <name>/<name>/run/.myclass[T] { ... } (no class keyword).val: T;. No let/var on class fields.for, if, while.new { field = val } — no class name after new.use X imports for unqualified lookup. use "url" for packages. _builtin is always implicit.(obj.field)(args) to call apply on field access result.Type(args) constructor sugar calls create method (e.g., callback(f) → callback::create(f)).x.method for zero-arg methods (no parens).!expr for boolean negation.::(expr, ...).(match expr { (pattern) -> body; ... }) else (default).:::name(args) for direct FFI, ffi::func(args) for _builtin/ffi/ wrappers.array[u8] → uint8_t*), objects pass as pointers to their fields (like a C struct). No wrapper types cross the FFI boundary.use "url" "tag" imports from a git repo. use "~/dev/pkg" "main" works for local repos.assert() liberally for invariants.Adding a new bytecode op requires updates in ~15 places across the codebase. Use this checklist:
include/vbcc.h (token), include/vbci.h (Op enum)vc/lang.h: wfExprDot, wfPassDot (with <<= Args), wfBodyANF, wfPassANF (with <<= wfDst * wfSrc)dot.cc (builtin reg), anf.cc (lowering), infer.cc (type tracking), reify.cc (IR transform)include/vbcc.h: wfStatement, wfIRDef pattern in vbcc/lang.h: manually maintained list — MUST include if op has a dst LocalIdvbcc/passes/liveness.cc: manually categorized ops — add to correct use/def categoryvbcc/bytecode.cc: encoding handlervbcc/passes/typecheck.cc: if neededvbci/thread.cc: op handler + op name in name arrayMissing items 5 or 6 causes "undefined register" errors in later passes, not at the registration site.
node->type() == other->type() for token comparison, NOT node == other_node.dist/ binaries.AGENTS.md, not in agent-specific memory stores.