Skip to content

fix(ccl): execute branch and read-branch jump tables - #436

Merged
eval-exec merged 1 commit into
mainfrom
fix/ccl-branch
Sep 23, 2026
Merged

eval-exec merged 1 commit into
mainfrom
fix/ccl-branch

Conversation

@eval-exec

Copy link
Copy Markdown
Owner

Summary

Fixes #435.

A CCL program whose first instruction is branch failed with Error in CCL program at 3th code. GNU Emacs runs the same program. ccl.el already emitted a valid CCL_Branch (0x0D) jump table; the bytecode driver had no arm for that opcode and treated it as an invalid program. (write "A") alone worked because CCL_WriteConstString was already implemented.

CclCommand is now a #[repr(u8)] enum of every GNU opcode. strum::FromRepr converts the 5-bit field with a safe const match, and the driver matches the enum with no wildcard. branch and read-branch share GNU's jump table: the register selects a slot when it is in range, and one extra slot covers an out-of-range value. read-branch reads one character first; EOF skips the table, and a suspended read resumes on the same word. Opcodes that are still unimplemented stay in one explicit arm and still signal Error in CCL program.

Test plan

  • cargo test -p neovm-core --offline --lib emacs_core::ccl:: (31 passed), including GNU ccl-compile vectors for the reported program, an out-of-range register, a later block, and read-branch (both blocks, the extra slot, EOF, and suspend).
  • Rebuild Neomacs and rerun the issue's repro.el. The installed binary was not rebuilt here.
  • Re-run FLIM's std11-default-ccl-lexical-analyzer. It may still stop on a later unimplemented opcode (expressions, arrays, call, or an extended command).

A CCL program whose first instruction is branch failed in Neomacs with
"Error in CCL program at 3th code" and exited 255. GNU Emacs runs the same
program and prints the selected block. Reported in #435 with
(branch r0 (write "A")), which ccl.el compiles to a vector whose first real
word is opcode 0x0D (CCL_Branch). (write "A") alone already worked, because
CCL_WriteConstString was implemented.

The driver matched raw opcode numbers and treated every unimplemented code as
an invalid program. CCL_Branch was one of those codes, so a valid jump table
was rejected at vector index 2. GNU's driver (src/ccl.c) indexes the following
words by the register when it is in range, and uses one extra slot otherwise.
Each entry is a raw relative offset from the table head. CCL_ReadBranch reads
one character and then uses that same table; EOF skips the table, and a
suspended read resumes on the same word.

CclCommand is now a repr(u8) enum of every GNU opcode. strum::FromRepr turns
the 5-bit field into a variant with a safe const match, and the driver matches
that enum with no wildcard. branch and read-branch share ccl_branch_target.
Opcodes that are still unimplemented stay in one explicit arm and still signal
"Error in CCL program".

The new tests run GNU ccl-compile vectors: r0 selects "A", an out-of-range or
negative register writes nothing, a later register selects "B", and read-branch
covers both blocks, the extra slot, EOF, and suspend.

Verified: cargo test -p neovm-core --offline --lib emacs_core::ccl:: (31
passed). The installed Neomacs binary was not rebuilt.
@coderabbitai

coderabbitai Bot commented Sep 23, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: 863ec1e5-6012-4db0-a3a5-aeea7717c4ed

📥 Commits

Reviewing files that changed from the base of the PR and between c8bd629 and aaec659.

📒 Files selected for processing (3)
  • crates/neovm-core/src/emacs_core/text/ccl/command.rs
  • crates/neovm-core/src/emacs_core/text/ccl/mod.rs
  • crates/neovm-core/src/emacs_core/text/ccl/tests/mod.rs
 ______________________________________
< My code review levels are over 9000! >
 --------------------------------------
  \
   \   \
        \ /\
        ( )
      .( o ).
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@eval-exec
eval-exec marked this pull request as ready for review September 23, 2026 11:25
Copilot AI balanced review requested due to automatic review settings September 23, 2026 11:25
@eval-exec
eval-exec merged commit e352e12 into main Sep 23, 2026
32 of 33 checks passed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot review overview

🟢 Approval recommended

The branch/read-branch handlers, enum discriminants, and all four test vectors were hand-verified against GNU src/ccl.c semantics, the refactor preserves existing opcode behavior, and no issues were found.

Review effort: Balanced
Findings: None

What changed in this PR

This PR fixes issue #435, where a CCL program whose first instruction is branch failed with Error in CCL program at 3th code. The CCL bytecode driver in neovm-core had no arm for the CCL_Branch (0x0D) opcode (nor CCL_ReadBranch, 0x10), so ccl.el-emitted jump tables were rejected as invalid. The change introduces a typed CclCommand enum for all 32 GNU opcodes, converts the 5-bit opcode field via strum::FromRepr, and adds jump-table execution for branch/read-branch matching GNU's src/ccl.c semantics. This restores parity with GNU Emacs for CCL programs that use branch dispatch, benefiting CCL-backed coding systems and ccl-execute-on-string consumers such as FLIM.

Changes:

  • Add command.rs defining CclCommand (#[repr(u8)], strum::FromRepr) with GNU opcode discriminants 0x00–0x1f.
  • Replace the raw code & 0x1f integer dispatch with an exhaustive enum match (no wildcard), and implement Branch/ReadBranch via a shared ccl_branch_target helper; remaining opcodes stay in one explicit arm that still signals Error in CCL program.
  • Add tests covering branch selection, the out-of-range slot, a later block, and read-branch (both blocks, extra slot, EOF, and suspend).
File Description
crates/​neovm-core/​src/​emacs_core/​text/​ccl/​command.rs New CclCommand enum enumerating every GNU 5-bit opcode as repr(u8) discriminants.
crates/​neovm-core/​src/​emacs_core/​text/​ccl/​mod.rs Adds ccl_branch_target, decodes opcodes into CclCommand, and adds exhaustive-match arms for Branch/ReadBranch.
crates/​neovm-core/​src/​emacs_core/​text/​ccl/​tests/​mod.rs Adds an execute_ccl_on_string helper and tests for branch/read-branch against GNU-compiled vectors.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

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.

[Bug]: CCL branch fails with "Error in CCL program at 3th code"

2 participants