plgr repl impl #8
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "repl"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
so farto plgr repl implReview — plgr REPL impl
Solid scaffold. The design split (program-edits-recompile vs queries-rerun) is implemented faithfully, the wire-contract handling in
run.rsis correct, history persistence via the newvim-lineStoreis clean, and the rule-3 invariant (nosolve/clause-walk symbol) holds at the source level. The simple gates work. Issues below, ordered by impact.Real bugs
1. Multi-line queries silently truncate at the first Enter.
app.rs:130-141submit()dispatches as soon as the linestarts_with("?-"), regardless of whether it ends in.. So:gets dispatched after the first line with goal
foo(X),, which the query parser rejects. The clause-accumulation logic exists right there — it just isn't reached for queries. Same bug affects:-directives entered across lines (a leading:short-circuits to dispatch). Fix: only dispatch immediately when the line ends in.(or is a meta-command, which is single-line by spec). Let queries/directives flow through thependingaccumulator like clauses already do.2.
save_historycan wipe valid history.app.rs:104-114writes the store unconditionally on exit. Ifload_historyfailed silently (permission flake, transient I/O error, etc.), the store is empty, and we then overwrite a real history file with nothing. Guard the save: skip if the store is empty AND no entries were pushed this session, or only overwrite if load succeeded.Design checkpoints not met
3. Completion ignores session predicates (
docs/design/REPL.mdcheckpoint 7).app.rs:122callscompletion::candidates(&prefix, &[])with an empty extras slice. The function already accepts session names — just threadself.sessionpredicate heads through. Today, Tab on a session-definedparentonly completes if it happens to match a builtin/stdlib name.4. Rule-3 CI guard is missing (
docs/design/REPL.mdcheckpoint 6). The design explicitly calls for a CI assertion thatplg-replcontains nosolve/clause-walk symbol. Today it's true by inspection but nothing pins it.justfileinstallsplgrbut adds no gate.5.
:loadcollapses a multi-clause file into one buffer entry.app.rs:240-253load_file()callsadd_clause(text.trim()), sosession.clausesends up with one giant string.:listthen renders one blob and predicate ordering blurs across:loadcalls. The TODO comment acknowledges this; the design's "ordered session source buffer (clauses + directives)" is what should be implemented. Split the file into clauses before pushing.Minor
6.
engine.rsshells toplgcinstead of linkingplg-compiler(the design target). Labelled scaffold and$PLGCis supported — fine for now, but the error path only catches spawn-fail; missing-from-PATH surfaces a system-y errno string. A one-line "install withjust install" hint would smooth the first-run experience.7. UI prompt differs from design.
docs/design/REPL.mdsays "?-prompt" for the terminal-native transcript;app.rs:24uses"plg> ". The doc comment justifies the change (neutral so it accepts both clauses and queries) — fine, but design doc and impl should agree.8.
:editis stubbed.app.rs:236logs "not wired yet". Either remove from the design surface until implemented or stub out the$EDITORpath.What's good
run.rscorrectly handles the wire contract — exit-1-with-stdout →Ok, exit-2/3 →Failedwith stderr. Stdin nulled, timeout viaPLG_REPL_TIMEOUT, 50 ms poll.Compiledholds itsTempDirso the binary lives exactly as long as it's the current one — drop semantics are right.capitalization_hintis a nice touch for beginners.input.rsadapter is small and clearly scoped to whatvim-line's contract leaves to the host; the reservedHistorySearch/Accept/Cancelactions are correctly forward-compatible no-ops.Suggested order
Fix 1 (multi-line queries) and 2 (history save) before merge — both are silent-data-loss class. 3, 4, 5 can land as follow-ups; they're scope completion against the design doc, not regressions.
1. Multi-line queries/directives no longer truncate (app.rs submit). The immediate-dispatch condition is now "is a meta-command (: but not :-) or ends in ."; ?- queries and :- directives flow through the pending accumulator until their terminating ., just like clauses. Single-line ?- fact(X). and :list still dispatch instantly. 2. save_history won't clobber a real file (app.rs). Guarded with if self.store.is_empty() { return; } — a failed load_history (transient read error) leaves the store empty, and we now refuse to overwrite the on-disk history with nothing. 3. Rule-3 CI guard (main.rs, two #[cfg(test)] tests): one asserts plg-repl doesn't depend on plg-runtime (no solver to interpret with), the other scans src/ for any fn solve definition. The invariant is now pinned by cargo test, not just inspection. (Had to make the source-scan match line-start fn declarations so it didn't trip over its own assertion string — caught and fixed.) 4. Doc reconciled (REPL.md). The presentation-model section now states the landed terminal-style transcript and documents the deliberate neutral plg> prompt with its rationale, instead of the stale ?- /bordered-panes description. Left as tracked follow-ups, per my recommendation: #3 session-predicate completion and #5 :load clause-splitting — both real design-checkpoint completion, larger than a quick fix. The review's #6 (engine PATH hint) was already covered, and #8 (:edit stub) stays parked and unadvertised.