63 lines
2.3 KiB
Markdown
63 lines
2.3 KiB
Markdown
|
|
# Phase 288.1 P1: REPL Session Persistence + Auto-Display (instruction sheet)
|
||
|
|
|
||
|
|
## Objective
|
||
|
|
|
||
|
|
- Make REPL variables persist across input lines (`x = 1` then `print(x)` works).
|
||
|
|
- Add minimal expression auto-display and `_` last-value binding (REPL-only).
|
||
|
|
- Keep file mode semantics unchanged; quick smokes must remain green.
|
||
|
|
|
||
|
|
SSOT:
|
||
|
|
- `docs/reference/language/repl.md`
|
||
|
|
|
||
|
|
## Constraints (non-negotiable)
|
||
|
|
|
||
|
|
- No new env vars.
|
||
|
|
- No file-mode behavior changes.
|
||
|
|
- Keep REPL-specific state and logic isolated (Box-first).
|
||
|
|
|
||
|
|
## Design (recommended)
|
||
|
|
|
||
|
|
Do **not** persist `ValueId` across evaluations. Persist runtime values (VMValue/handle) in `ReplSessionBox`, and bridge them via a REPL-only rewrite step.
|
||
|
|
|
||
|
|
### Bridge approach: REPL-only AST rewrite
|
||
|
|
|
||
|
|
In REPL mode, rewrite variable reads/writes that are not declared in the current input line into calls against a REPL session object:
|
||
|
|
|
||
|
|
- Read `x` → `__repl.get("x")`
|
||
|
|
- Assignment `x = expr` → `__repl.set("x", expr)`
|
||
|
|
- `_` is treated as a normal name in the session (written by auto-display).
|
||
|
|
|
||
|
|
This keeps the parser unchanged and avoids contaminating the normal MIR builder scope model.
|
||
|
|
|
||
|
|
### Session API (REPL-only)
|
||
|
|
|
||
|
|
Provide a minimal host object `__repl` with:
|
||
|
|
|
||
|
|
- `get(name: String) -> Any` (Fail-Fast if missing)
|
||
|
|
- `set(name: String, value: Any) -> void`
|
||
|
|
- `reset() -> void`
|
||
|
|
|
||
|
|
Implementation options:
|
||
|
|
|
||
|
|
- Rust VM only (initially): inject `__repl` as a built-in box/object available only in `--repl`.
|
||
|
|
- LLVM parity is not required for Phase 288.1; REPL is a dev tool.
|
||
|
|
|
||
|
|
## Step-by-step
|
||
|
|
|
||
|
|
1) Add a REPL-only `__repl` host object and VM handlers for `get/set/reset`.
|
||
|
|
2) Implement AST rewrite in the REPL runner before compilation:
|
||
|
|
- Collect “declared names” in the current line (`local name`, function params, etc.).
|
||
|
|
- Rewrite remaining identifier reads/writes to `__repl.get/set`.
|
||
|
|
3) Implement auto-display:
|
||
|
|
- If the input is a pure expression, `print(result)` (or equivalent) in REPL only.
|
||
|
|
- Store result into session name `_` (skip if `void`).
|
||
|
|
4) Add conformance checks (manual is OK if no test harness exists yet):
|
||
|
|
- `x = 1` (silent)
|
||
|
|
- `print(x)` prints `1`
|
||
|
|
- `y` (read) is NameError
|
||
|
|
- `1 + 1` prints `2` and `_` becomes `2`
|
||
|
|
- `.reset` clears variables (`print(x)` errors)
|
||
|
|
5) Run regression gate:
|
||
|
|
- `./tools/smokes/v2/run.sh --profile quick` must stay `0 FAILED`.
|
||
|
|
|