feat(grammar)!: require semicolons on microflow and nanoflow statements - #66
Merged
Conversation
BREAKING CHANGE: every statement inside a microflow or nanoflow body must now end with `;`, including block terminators (`end if;`, `end loop;`, `end while;`, `end case;`). Omitting one is a parse error, where it was previously accepted. Semicolons were optional on all 54 body-statement alternatives, which made statement boundaries ambiguous whenever a keyword can both continue a statement and start one. The concrete case that surfaced it: adding a trailing `commit` modifier to create/change for mendixlabs#779 would let $a = create Mod.E commit $b; bind `commit` to the create rather than starting a commit activity. Diagnosing that per keyword does not scale; requiring the terminator removes the class. Scoped deliberately to microflow/nanoflow BODIES. The document terminator (`end;` / `end` then `/`) stays optional, as it is for pages and every other document type — measured, that variant breaks 88 of 234 example files, 75 of them pages, because block-bodied documents have never required a terminator and three styles coexist in the corpus (168 bare `}`, 56 `};`, 62 `}` + `/`). Tightening that is a separate, much larger decision. Impact measured over all 273 files in mdl-examples: 2 needed fixing, both genuine omissions (`end loop` with no `;`, a `log` line with no `;`), plus a `raise error` inside an on-error block. Example corpus is back at baseline parity (234 pass / 39 fail, 0 regressions). Test fixtures embedding MDL needed the same treatment in enginecompare, executor and visitor. Doc and skill code blocks were extracted and parse-checked against both the old and new parser: 0 regressions, so no documentation migration was required. Diagnostics were already precise for this ("line 143:2 missing ';' at 'return'"), so no error-reporting work was needed. Documented in write-microflows.md, write-nanoflows.md and MDL_QUICK_REFERENCE.md, each stating that the definition terminator remains optional. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012XR649rKk68z6gBpngu6MA
ako
pushed a commit
that referenced
this pull request
Aug 1, 2026
Resolves the recurring conflict in .claude/skills/fix-issue.md: every fix appends a symptom row at the same anchor, so any two branches that both add one collide. Both sides kept — this branch's mendixlabs#812 row plus the two loop rows that arrived from #63. Main has since gained #64 (runUpdateWidgets) and #66 (mandatory microflow semicolons). Parser regenerated against the new grammar; full suite green, and the example corpus is unchanged at 235/39 including this branch's repro script.
ako
pushed a commit
that referenced
this pull request
Aug 1, 2026
Same recurring conflict as #68: .claude/skills/fix-issue.md, where every fix appends a symptom row at the identical anchor. Both sides kept. check.go auto-merged cleanly — #64's runUpdateWidgets and this branch's localMxForVersion touch different functions. Parser regenerated against #66's grammar; full suite green.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
BREAKING CHANGE. Every statement inside a microflow or nanoflow body must now end with
;, including block terminators (end if;,end loop;,end while;,end case;). Omitting one is a parse error where it was previously accepted.Why
Semicolons were optional on all 54 body-statement alternatives, which leaves statement boundaries ambiguous whenever a keyword can both continue a statement and start one. The concrete case that surfaced it — adding a trailing
commitmodifier to create/change for mendixlabs#779:ANTLR is greedy, so
commitbinds to the create rather than starting a commit activity. Diagnosing that per keyword does not scale; requiring the terminator removes the class.Scope
Deliberately limited to microflow/nanoflow bodies. The document terminator (
end;, orendfollowed by/) stays optional, as it is for pages and every other document type.That boundary is measured, not assumed. Tightening the top-level statement rule instead:
;mandatory (this PR);mandatory;or/Of those 77, 75 are page / snippet / layout and 0 are domain models. Block-bodied documents have never required a terminator, and three styles coexist in the corpus — 168 definitions ending on a bare
}, 56 on};, 62 on}then/. Tightening that is a separate and much larger decision, worth an ADR if it is wanted at all.Migration
2 of 273 example files needed fixing, all genuine omissions:
Example corpus is back at exact baseline parity — 234 pass / 39 fail, 0 regressions.
Test fixtures embedding MDL needed the same treatment:
enginecompare(8 —RETURN true END→RETURN true; END,end loop END→end loop; END),validate_microflow_hints_test.go(8),visitor_test.go(1).Docs needed no migration — verified, not assumed
I extracted every self-contained
create microflow/nanoflow … endblock from.claude/skills/,docs-site/src/and the quick reference, then parse-checked all of them against both the old and the new binary. Identical results, 0 regressions. (An earlier line-based scan flagged 39 doc lines; those were false positives — multi-line statements whose semicolon sits on a continuation line.)The rule is now documented in
write-microflows.md,write-nanoflows.mdandMDL_QUICK_REFERENCE.md, each stating explicitly that the definition terminator remains optional — otherwise agents will "helpfully" add;afterendtoo.Diagnostics
Already precise for this case, so no error-reporting work was needed:
🤖 Generated with Claude Code
https://claude.ai/code/session_012XR649rKk68z6gBpngu6MA
Generated by Claude Code