Fix REPL - #113
Open
tln wants to merge 4 commits into
Open
Conversation
The REPL starts by evaluating an in-memory chunk named `main`. That uri was
passed to the CLI's file resolver, which called realpath on it and failed, so
the REPL exited immediately with:
CompileError: Import path does not exist: `main`
An entry chunk has no importing chunk, so it can be in-memory and resolve to
itself. Only entry chunks are treated this way, leaving `use main` from a
script resolving to a file as before.
REPL.new() bound the new REPL to a local and returned it. Returning a local
copies it into the return slot and then runs the block's destructors on the
local, so `VM.@deinit` freed the VM that the returned copy still points at.
The next eval crashed in Compiler.clearReports on a dangling pointer.
This works around the problem rather than fixing it. Any record owning a type
with a destructor hands the caller freed memory when returned this way:
type Holder:
vm cy.VM
fn make() -> Holder:
h := Holder{ vm = cy.VM() }
return h
h := make()
r := h.vm.eval('print(1)') -- crash
Returning the literal directly is fine, so it is specifically binding to a
named local and returning it. There is no move tracking to skip destructing a
returned local, so REPL.new now returns the record literal, and the init eval
moved to a separate `init` that runs in the caller's scope.
The compiler is reused across evals, and persist_main re-declares the previous main's top level syms in the new main chunk. Two things carried over wrongly. The skip list named `@main_init` and `@main_deinit`, which no longer exist; the hidden funcs are `@program_init` and `@program_deinit`. So they were carried over and collided with the ones reserved for the new main, and reporting that duplicate panicked in Sym.declNode on a `.use_alias`. Every line after the first failed. `main` was also treated as the entry point of every line. Each REPL line is compiled as its own program, so declaring `fn main()` on a line ran it, and it then stayed the entry point for the rest of the session: later lines re-ran it and were rejected with "Body statement is not allowed when main function is declared". A carried over `main` arrives as a use alias, which the unchecked cast to `.func` panicked on. `main` is not special in a session that continues across evals; it is an ordinary function that can be called by name. `main_func` is also reset per compile, since it was previously only ever assigned.
Each case is a list of input lines and the exact output the REPL prints for them. The driver runs the same read/eval_print loop as `cy.repl`, minus the intro banner, which carries a build specific version string. Covers the regressions fixed in this branch: `main` is an ordinary function rather than an entry point, so declaring it runs nothing and it stays callable by name; and a line that fails to compile does not stop the following lines from evaluating. Cases feed whole statements per entry rather than driving `read`'s multi-line buffering, since `input_buffer` currently leaks the concatenated string.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Running the repl from commit c853fcc did not invoke the cyber-written repl
code. In addition a few other fixes were needed to make the REPL work.
A few basic tests were added for the REPL.
Defining
fn main()in a REPL session no longer runs it. Previously it wastreated as an entry point.
Still broken
read()leaks the concatenatedinput_buffer.path (
value_desc) is currently unreachable.Built and tested with zig 0.15.2;
zig build testpasses.