Skip to content

Switch statement coverage: state-machine tests, mini-sample, docs#535

Open
Copilot wants to merge 2 commits into
mainfrom
copilot/add-csharp-switch-support
Open

Switch statement coverage: state-machine tests, mini-sample, docs#535
Copilot wants to merge 2 commits into
mainfrom
copilot/add-csharp-switch-support

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 22, 2026

The transpiler already lowers the IL switch opcode to CMP/BNE+JMP trampolines (with correct fall-through to default:), but the feature lacked coverage for the canonical game-state-machine pattern from the issue and a runnable sample. Existing SwitchSmall and SwitchEnum tests covered dense dispatch and enum : byte, but nothing exercised default: or the full pad_trigger/PAD.START dispatch loop.

Changes

  • Tests (src/dotnes.tests/ControlFlowTests.cs)

    • SwitchWithDefault — 5-way switch (byte) with default:; asserts CMP #$01..#$03, BNE/JMP trampolines, and that the default arm's LDA #$26 is emitted.
    • SwitchStateMachine — the exact title/playing/over example from the issue, including pad_trigger(0) & PAD.START and a default: arm.
  • Sample (samples/statemachine/) — minimal title/playing/over state machine that recolors the backdrop on START. Disassembly of the produced ROM shows the expected dispatch:

    $8550: AD 25 03  LDA $0325       ; state
    $8553: D0 03     BNE +3          ; case 0 (STATE_TITLE)
    $8555: 4C 69 85  JMP $8569
    $8558: C9 01     CMP #$01        ; case 1 (STATE_PLAYING)
    $855A: D0 03     BNE +3
    $855C: 4C 87 85  JMP $8587
    $855F: C9 02     CMP #$02        ; case 2 (STATE_OVER)
    $8561: D0 03     BNE +3
    $8563: 4C A5 85  JMP $85A5
    $8566: 4C C3 85  JMP $85C3       ; default
    
  • Docs (docs/8bitworkshop-samples.md)

    • Drop switch/case from crypto.c's missing-features list.
    • Extend the climber TODO entry to note default: fall-through and reference the four switch tests (Small, Enum, WithDefault, StateMachine).

No transpiler code changed; the existing HandleSwitch implementation in IL2NESWriter.ILDispatch.cs already handled all four acceptance scenarios.

Copilot AI linked an issue May 22, 2026 that may be closed by this pull request
5 tasks
Agent-Logs-Url: https://github.com/jonathanpeppers/dotnes/sessions/75bd402b-4c42-406c-86de-f4a5e97f7589

Co-authored-by: jonathanpeppers <840039+jonathanpeppers@users.noreply.github.com>
Copilot AI changed the title [WIP] Add transpiler support for C# switch statements Switch statement coverage: state-machine tests, mini-sample, docs May 22, 2026
Copilot AI requested a review from jonathanpeppers May 22, 2026 20:56
@jonathanpeppers jonathanpeppers marked this pull request as ready for review May 22, 2026 22:35
Copilot AI review requested due to automatic review settings May 22, 2026 22:35
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds coverage and a runnable example for the IL switch opcode lowering in dotnes (IL → CMP/BNE + JMP trampolines), plus updates docs to reflect current support.

Changes:

  • Added two Roslyn-based tests exercising larger switch patterns (including default: and a controller-driven state machine loop).
  • Added a new samples/statemachine/ project demonstrating a game-style switch (state) loop on the NES.
  • Updated 8bitworkshop sample documentation to remove switch/case from the missing-features list and to reference the new tests.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/dotnes.tests/ControlFlowTests.cs Adds SwitchWithDefault and SwitchStateMachine tests for switch dispatch patterns
samples/statemachine/statemachine.csproj New sample project file for the state machine demo
samples/statemachine/Program.cs New sample program demonstrating switch-based state machine
samples/statemachine/chr_generic.s CHR data for the new sample
docs/8bitworkshop-samples.md Documentation updates reflecting switch/case support and test coverage

Comment on lines +145 to +155
var hex = Convert.ToHexString(bytes);
// CMP #$01, #$02, #$03 for cases 1..3
Assert.Contains("C901", hex);
Assert.Contains("C902", hex);
Assert.Contains("C903", hex);
// BNE (D0) for skipping JMP on mismatch
Assert.Contains("D0", hex);
// JMP (4C) for jumping to case/default targets
Assert.Contains("4C", hex);
// The default value 0x26 must appear (LDA #$26 = A926)
Assert.Contains("A926", hex);
Comment on lines +161 to +205
// The state-machine pattern from the issue: title / playing / over with a default.
// Roslyn lowers a dense byte switch with default into IL `switch` + br to default.
var bytes = GetProgramBytes(
"""
const byte STATE_TITLE = 0;
const byte STATE_PLAYING = 1;
const byte STATE_OVER = 2;

byte state = STATE_TITLE;
byte lives = 3;

while (true)
{
pad_poll(0);
switch (state)
{
case STATE_TITLE:
if ((pad_trigger(0) & PAD.START) != 0)
state = STATE_PLAYING;
break;
case STATE_PLAYING:
if (lives == 0)
state = STATE_OVER;
break;
case STATE_OVER:
if ((pad_trigger(0) & PAD.START) != 0)
state = STATE_TITLE;
break;
default:
state = STATE_TITLE;
break;
}
ppu_wait_nmi();
}
""");
Assert.NotNull(bytes);
Assert.NotEmpty(bytes);

var hex = Convert.ToHexString(bytes);
// CMP #$01 and CMP #$02 for case 1 and case 2 of the dense switch
Assert.Contains("C901", hex);
Assert.Contains("C902", hex);
// JMP (4C) trampolines from the switch dispatch
Assert.Contains("4C", hex);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Transpiler: support switch/case statements

3 participants