From d67759c5511e416d3074ebb4261cb2ac83d34cbc Mon Sep 17 00:00:00 2001 From: Christopher Toth Date: Thu, 22 Oct 2026 23:18:41 -0600 Subject: [PATCH 1/2] Fix MOO local definitions in assignment expressions --- agent-notes/moo-expression-assignments.md | 20 ++++++++++++++++++++ src/editor/moocode/semantics.ts | 19 ++++++++++++------- 2 files changed, 32 insertions(+), 7 deletions(-) create mode 100644 agent-notes/moo-expression-assignments.md diff --git a/agent-notes/moo-expression-assignments.md b/agent-notes/moo-expression-assignments.md new file mode 100644 index 00000000..e4d75d6b --- /dev/null +++ b/agent-notes/moo-expression-assignments.md @@ -0,0 +1,20 @@ +# MOO expression assignments + +## Goal +Fix the false undefined-local warning for `if (valid(channel = this:current_channel(player)))` and push a client PR. Q authorized implementation with "MAKE IT SO!". ToastStunt at `~/src/toaststunt` is the syntax authority. + +## State +Branch `fix/moo-expression-assignments`, isolated from the user's dirty primary checkout, based on origin/master at 000c4b15. Scanner fix implemented: scan the entire masked source with an identifier boundary and exclude property names. Ready to commit and open PR; hosted validation pending. + +## Decisions and why +Smallest change: approximately 20 lines in the existing assignment-definition collector. Scan masked source for identifier assignment targets regardless of expression punctuation or line breaks; exclude property names using the existing previous-character helper. No new parser or semantic architecture. + +ToastStunt `src/parser.y:139` accepts expressions in if conditions; `:466-486` constructs assignment expressions. The installed tree-sitter WASM parses the reported example into an assignment_expression with hasError false. Client `src/editor/moocode/semantics.ts:919` instead requires a preceding line start, whitespace or semicolon, missing the target immediately after `(`. Correct that existing rule first. + +No npm package change is justified by this example. Other reported issues have not yet been supplied. Do not publish an unchanged parser package. + +## Surprises +The warning is produced by the client's text-based semantic model, not tree-sitter. The current checkout is older than origin/master and contains unrelated untracked work. + +## Next step +Commit, push and open the PR. Use hosted CI rather than running its steps locally. No new guards or test files added, per Q's standing instruction. Do not merge or release as part of this client PR request. diff --git a/src/editor/moocode/semantics.ts b/src/editor/moocode/semantics.ts index f5ac26ea..7e79f45a 100644 --- a/src/editor/moocode/semantics.ts +++ b/src/editor/moocode/semantics.ts @@ -896,9 +896,9 @@ function collectDefinitions( const lines = masked.split(/\r\n|\r|\n/); const lineOffsets = getLineOffsets(source); + collectAssignmentDefinitions(source, masked, definitions); lines.forEach((line, lineIndex) => { const lineOffset = lineOffsets[lineIndex] ?? 0; - collectAssignmentDefinitions(source, line, lineOffset, definitions); collectForDefinitions(source, line, lineOffset, definitions); collectForkDefinitions(source, line, lineOffset, definitions); collectExceptDefinitions(source, line, lineOffset, definitions); @@ -911,21 +911,26 @@ function collectDefinitions( function collectAssignmentDefinitions( source: string, - line: string, - lineOffset: number, + masked: string, definitions: Array<{ name: string; occurrence: Occurrence }>, ): void { const assignmentPattern = new RegExp( - `(^|[;\\s])(${MOO_IDENTIFIER_PATTERN_SOURCE})\\s*=(?!=|>)`, + `\\b(${MOO_IDENTIFIER_PATTERN_SOURCE})\\s*=(?!=|>)`, 'g', ); - for (const match of line.matchAll(assignmentPattern)) { - const name = match[2]; + for (const match of masked.matchAll(assignmentPattern)) { + const name = match[1]; if (!name) { continue; } - const nameStart = lineOffset + match.index + match[0].indexOf(name); + // Assignment is an expression (ToastStunt parser.y), including in conditions + // and arguments. Property names are not local assignment targets. + const nameStart = match.index; + const previous = previousNonWhitespaceCharacter(masked, nameStart); + if (previous === '.' || previous === ':' || previous === '$') { + continue; + } definitions.push({ name, occurrence: occurrenceAt(source, nameStart, name.length), From f22c02cdb839db422aa5401018c3c42991ff2c38 Mon Sep 17 00:00:00 2001 From: Christopher Toth Date: Thu, 22 Oct 2026 23:19:52 -0600 Subject: [PATCH 2/2] Record MOO assignment fix PR handoff --- agent-notes/moo-expression-assignments.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/agent-notes/moo-expression-assignments.md b/agent-notes/moo-expression-assignments.md index e4d75d6b..ca73695c 100644 --- a/agent-notes/moo-expression-assignments.md +++ b/agent-notes/moo-expression-assignments.md @@ -4,7 +4,7 @@ Fix the false undefined-local warning for `if (valid(channel = this:current_channel(player)))` and push a client PR. Q authorized implementation with "MAKE IT SO!". ToastStunt at `~/src/toaststunt` is the syntax authority. ## State -Branch `fix/moo-expression-assignments`, isolated from the user's dirty primary checkout, based on origin/master at 000c4b15. Scanner fix implemented: scan the entire masked source with an identifier boundary and exclude property names. Ready to commit and open PR; hosted validation pending. +Branch `fix/moo-expression-assignments`, isolated from the user's dirty primary checkout, based on origin/master at 000c4b15. Scanner fix committed as d67759c5 and pushed. PR: https://github.com/MongooseMoo/react-client/pull/204. Scan the entire masked source with an identifier boundary and exclude property names. The normal commit hook completed typecheck and staged lint. Hosted validation is tracked on the PR's current head. ## Decisions and why Smallest change: approximately 20 lines in the existing assignment-definition collector. Scan masked source for identifier assignment targets regardless of expression punctuation or line breaks; exclude property names using the existing previous-character helper. No new parser or semantic architecture. @@ -17,4 +17,4 @@ No npm package change is justified by this example. Other reported issues have n The warning is produced by the client's text-based semantic model, not tree-sitter. The current checkout is older than origin/master and contains unrelated untracked work. ## Next step -Commit, push and open the PR. Use hosted CI rather than running its steps locally. No new guards or test files added, per Q's standing instruction. Do not merge or release as part of this client PR request. +Read PR #204's current hosted CI result and report it. No new guards or test files added, per Q's standing instruction. The requested client fix is pushed and the PR is open; no merge or release is authorized as part of this client PR request. Other parser issues await examples from Q.