Skip to content

cli: engine flags share non-ident positional -> main heuristic with default#341

Merged
danieljohnmorris merged 3 commits into
mainfrom
fix/engine-flag-non-ident-heuristic
May 17, 2026
Merged

cli: engine flags share non-ident positional -> main heuristic with default#341
danieljohnmorris merged 3 commits into
mainfrom
fix/engine-flag-non-ident-heuristic

Conversation

@danieljohnmorris
Copy link
Copy Markdown
Collaborator

Summary

PR #329 propagated half of the default-engine entry-point heuristic to the explicit-engine flags (--run-tree / --run-vm / --run-cranelift): when there's no positional after the source path, auto-pick main. It didn't propagate PR #328's other half: when the first positional doesn't look like a function name (paper.txt, /tmp/x.json, 42, anything with a . or / or leading digit) and main is defined, route to main with the positional as arg #1.

Three rerun7 personas (pdf-analyst, devops-sre, qa-tester) hit the same asymmetry independently:

$ ilo main.ilo paper.txt                # default engine: works
42
$ ilo --run-tree main.ilo paper.txt     # tree: fails
{"code":"ILO-R002","message":"undefined function: paper.txt", ...}
$ ilo --run-vm main.ilo /tmp/x.json     # vm: same
$ ilo --run-cranelift main.ilo paper.txt # cranelift: same

This PR extends resolve_engine_func_name (src/main.rs) to share the same looks_like_subcommand_name check the default-engine path uses. Surgical fix, mirrors a check that's already documented and well-tested elsewhere.

Repro before/after

/tmp/repro.ilo:

helper x:n>n;+x 1
main path:t>n;helper 41

Before:

$ ilo --run-tree /tmp/repro.ilo /tmp/paper.txt
{"code":"ILO-R002","message":"undefined function: /tmp/paper.txt", ...}
$ ilo --run-vm /tmp/repro.ilo /tmp/paper.txt
{"code":"ILO-R002","message":"undefined function: /tmp/paper.txt", ...}
$ ilo --run-cranelift /tmp/repro.ilo /tmp/paper.txt
undefined function: /tmp/paper.txt

After:

$ ilo --run-tree /tmp/repro.ilo /tmp/paper.txt        → 42
$ ilo --run-vm /tmp/repro.ilo /tmp/paper.txt          → 42
$ ilo --run-cranelift /tmp/repro.ilo /tmp/paper.txt   → 42
$ ilo /tmp/repro.ilo /tmp/paper.txt                   → 42  (unchanged)

What's in the diff

  • cli: engine flags route non-ident first positional to main (1cd81db) — the four-line guard in resolve_engine_func_name. Identical predicate to the default-engine branch at src/main.rs ~2838-2857, so future drift between the two paths is easier to spot.
  • tests: cross-engine regression for non-ident positional dispatch (89bed33) — 24 new tests in regression_cli_default.rs mirroring the PR cli: auto-pick main on --run-tree / --run-vm / --run-cranelift #329 block: one helper per scenario, fanned out across --run-tree / --run-vm / --run-cranelift plus a default-engine pin. Covers non-ident positional, path-shaped positional, numeric positional, explicit main keyword + non-ident arg, explicit helper override (must NOT be shadowed by the heuristic), and ident-shaped-unknown-no-main (must still error).
  • examples: pin non-ident positional routing across engines (8b04f63) — examples/engine-flag-non-ident-positional.ilo runs through the engine harness on every backend, so a future regression here fails at cross-engine parity rather than waiting for another persona to file it.

Test plan

  • cargo test --release --features cranelift (full suite green, all 3000+ tests)
  • cargo fmt --check clean
  • cargo clippy --release --features cranelift --tests -- -D warnings clean
  • Manual repro across all four engines confirms 42
  • Examples harness exercises paper.txt, /tmp/x.json, explicit main, and explicit helper on every backend

Follow-ups

PR #329 propagated the no-positional auto-pick-main heuristic from the
default engine (PR #307) to --run-tree / --run-vm / --run-cranelift,
but skipped PR #328's other half: when the first positional is non-
ident-shaped (paper.txt, /tmp/x.json, 42), the default engine routes
to main with the positional as arg #1, while the explicit-engine flags
still treated the positional as a function name and surfaced
ILO-R002: undefined function: paper.txt.

Extend resolve_engine_func_name to share the same check: if
looks_like_subcommand_name(first) is false and main is defined, route
to main with the whole rest slice as call args. Ident-shaped typos
still fall through to the engine and surface the existing
undefined-function diagnostic, so PR #329's typo-detection contract
is preserved verbatim.

Reported by pdf-analyst, devops-sre, and qa-tester independently in
rerun7.
Mirrors the structure of the PR #329 engine-flag-auto-pick-main block:
one helper per scenario, fanned out across --run-tree / --run-vm /
--run-cranelift (+ default-engine pin where useful).

Scenarios covered:
- non-ident positional (paper.txt) routes to main
- path-shaped positional (/tmp/x.json) routes to main (devops-sre repro)
- numeric positional (10, 32) routes to main as multi-arg call
- explicit main keyword + non-ident positional still works
- explicit helper ident overrides the main heuristic
- ident-shaped unknown with no main still errors clearly

24 new tests; the default-engine pin guards against future drift
between default and explicit-engine code paths.
Acts as both an agent-learning artefact (shows the correct shape for
'pass a path argument to main on a multi-fn file' across every engine
flag) and a harness-level regression run through tests/examples_engines.rs
on every backend.
@codecov
Copy link
Copy Markdown

codecov Bot commented May 17, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

@danieljohnmorris danieljohnmorris merged commit d03e6d9 into main May 17, 2026
5 checks passed
@danieljohnmorris danieljohnmorris deleted the fix/engine-flag-non-ident-heuristic branch May 17, 2026 13:25
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.

1 participant