Skip to content

Commit b3754cf

Browse files
authored
Merge pull request #3580 from GaijinEntertainment/bbatkin/hot-path-lint-and-env-docs
lint: hot-path contracts (PERF026-028) + dasLLAMA env registry and 64-bit sweep
2 parents 98d4ceb + 9c187c9 commit b3754cf

85 files changed

Lines changed: 2589 additions & 529 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CLAUDE.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ Task-specific instructions are split into skill files under `skills/`. You MUST
7878
| `skills/daslang_lsp.md` | Working on `utils/lsp/` (the LSP server for Claude Code / stdio clients) — locked architecture, coordinate conventions, CC wire facts, headless dev rig, protocol tests |
7979
| `utils/dasHerd/dasherder.md` | Running INSIDE a dasHerd-managed agent session (any `DASHERD_SESSION_ID` env var set) — the session cooperation contract: inbox/outbox mailbox, declaring participating repositories, Review Bundles, the `dasherd.ps1` CLI |
8080
| `skills/imgui_ui_debugging.md` | **CRITICAL UI SKILL** — diagnosing/fixing ANY dasImgui UI or interaction bug. The discipline: reproduce + screenshot → make it observable in `imgui_snapshot` (fix the inspection if it isn't) → fix → prove via snapshot + test → 'after' screenshot. UI is hard; **never claim a UI fix works from logic or a screenshot — only from structured snapshot state.** |
81-
| `skills/perf_lint.md` | Adding rules to `daslib/perf_lint.das` |
81+
| `skills/environment_variables.md` | Reading or ADDING any environment variable — the full daslang set, plus the read-once/typed-default rules a new one must follow. dasLLAMA's own ~130 knobs are generated into `modules/dasLLAMA/ENVIRONMENT.md` |
82+
| `skills/perf_lint.md` | Adding rules to `daslib/perf_lint.das`**and before declaring any hot path off-limits to allocation**: `[hot_path]` / `[no_alloc]` / `[no_env]` / `[no_io]` contracts (PERF026-028), `[cold_path]` to prune, `@scratch` to declare a reused buffer |
8283
| `skills/style_lint.md` | Adding rules to `daslib/style_lint.das` |
8384
| `skills/strings.md` | Any `.das` string operation — `find`/`replace`/`split`/parsing/`build_string`/`peek_data` (covers `strings`, `daslib/strings_boost`, `daslib/strings_convert`) |
8485
| `skills/regex.md` | Writing regular expressions in `.das` code |
@@ -300,6 +301,9 @@ A generic that should accept `array<T>`, `array<array<T>>`, … (any nesting)
300301
### Common gotchas
301302

302303
- Lambda params can shadow function params — use distinct names
304+
- **`where` and `shared` are reserved words too**`where` is the comprehension filter keyword and
305+
`shared` the module modifier; both are a syntax error as a variable name (`let where = ...`,
306+
`let shared = ...`). Rename (`sink_pos`, `shared_node`); hit while writing PERF026-028
303307
- **`label`, `expect`, and `pass` are reserved words** (lexer keywords `DAS_LABEL`/`DAS_EXPECT`/`DAS_PASS``pass` is the no-op statement) — using any as a parameter/variable name is a syntax error; rename (`tag`, `want`, `cpass`)
304308
- **`range`/`urange`/`range64`/`urange64` are lexer TYPE tokens** (`DAS_TRANGE` etc., like `int`) — unusable as struct-field, parameter, or annotation-argument names (`@range = ...` is a syntax error); the grammar whitelists them back to a plain name only in call position, which is why `range(10)` works. Rename (`rng`, `span`); grammar-verified 2026-07-23
305309
- **Literal `{`/`}` in string literals must be escaped `\{`/`\}`** — unescaped `{...}` is interpolation. Bites when embedding shader/C source as inline strings. String literals may span multiple lines (raw newlines are legal); probe-verified 2026-07-11

ci/check_shipped_skills.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,10 @@
4747
# junction workflow in external_module_debugging.md uses illustrative C:/DummyRoot paths
4848
# 17 times on purpose, and flagging those would force 17 noise markers onto correct
4949
# content. A bare `\\`-UNC branch is also out -- it matched `\\d` / `\\s` in regex prose.
50+
# AppData needs a leading separator: bare `APPDATA` is the ENV VAR NAME, which
51+
# environment_variables.md documents alongside XDG_CONFIG_HOME. Only a real path is a leak.
5052
MACHINE_PATH = re.compile(
51-
r"(?:[A-Za-z]:[\\/](?:Users|Work|DASPKG)\b|/home/[A-Za-z0-9_.]+|AppData)", re.I)
53+
r"(?:[A-Za-z]:[\\/](?:Users|Work|DASPKG)\b|/home/[A-Za-z0-9_.]+|[\\/]AppData\b)", re.I)
5254

5355
SKILL_REF = re.compile(r"skills/([a-z_0-9]+\.md)")
5456
MD_LINK = re.compile(r"\[[^\]]*\]\(([^)\s]+)\)")

daslib/lint_config.das

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,16 @@ module lint_config shared private
2222
//! Anything that is not a boolean entry under ``[rules]`` is ignored.
2323
//! If the file is missing, unreadable, or fails to parse the call is a
2424
//! no-op — built-in defaults stand.
25+
//!
26+
//! Two environment variables feed the same cascade: ``DAS_LINT_CONFIG_PATH``
27+
//! redirects which file is read, and ``DAS_LINT_DISABLE`` (comma-separated
28+
//! codes) turns rules off for one run, overriding everything above.
2529

2630
require daslib/fio
2731
require daslib/json
2832
require daslib/toml
2933
require daslib/ast_boost
34+
require daslib/strings_boost
3035

3136
//! Path override env var. When ``DAS_LINT_CONFIG_PATH`` is set, the macro
3237
//! cascade reads that path instead of ``{get_das_root()}/.lint_config`` —
@@ -41,11 +46,25 @@ def private resolved_config_path() : string {
4146
return "{get_das_root()}/.lint_config"
4247
}
4348

44-
//! Loads the repo-level lint config (``{get_das_root()}/.lint_config`` by
45-
//! default; ``$DAS_LINT_CONFIG_PATH`` if set) into ``disabled_codes``.
46-
//! No-op when the file is missing or unreadable.
49+
//! Ad-hoc rule opt-out for one run: ``DAS_LINT_DISABLE=PERF026,LINT017`` (bare codes, comma
50+
//! separated, surrounding whitespace ignored, unknown codes harmless). Needs no source edit —
51+
//! the "let me add a log line while I debug this" hatch. Applied last, so it overrides the config.
52+
def public load_env_disabled(var disabled_codes : table<string>) : void {
53+
return if (!has_env_variable("DAS_LINT_DISABLE"))
54+
for (part in split(get_env_variable("DAS_LINT_DISABLE"), ",")) {
55+
let code = strip(part)
56+
if (!empty(code) && !key_exists(disabled_codes, code)) {
57+
disabled_codes |> insert(code)
58+
}
59+
}
60+
}
61+
62+
//! Loads the repo-level lint config (``{get_das_root()}/.lint_config`` by default;
63+
//! ``$DAS_LINT_CONFIG_PATH`` if set) into ``disabled_codes``, then layers ``$DAS_LINT_DISABLE``
64+
//! on top. No-op when the file is missing or unreadable.
4765
def public load_lint_config(var disabled_codes : table<string>) : void {
4866
load_lint_config_from_path(resolved_config_path(), disabled_codes)
67+
load_env_disabled(disabled_codes)
4968
}
5069

5170
//! Parser entry point. Reads ``path`` (TOML) and folds the ``[rules]``
@@ -130,6 +149,8 @@ def public build_lint_macro_disabled(prog : ProgramPtr) : table<string> {
130149
for (code in keys(_cache_on)) {
131150
if (key_exists(disabled, code)) disabled |> erase(code)
132151
}
152+
// last, so a one-run DAS_LINT_DISABLE beats a `CODE = true` in the repo config
153+
load_env_disabled(disabled)
133154
return <- disabled
134155
}
135156

0 commit comments

Comments
 (0)