Conversation
Exposes the AST without evaluating it — wanted for tooling (linters, analyzers, source-rewriters) that need to read a Lisp file's forms without running them. The function already existed; this only changes visibility, plus a doc comment covering the filename-table side effect (re-parsing the same path is idempotent).
`compile_fn_let_star` short-circuited the whole form when the body compiled to zero instructions — which happens whenever the let's result is discarded and the body is a literal or a binding lookup. The early return threw away `result`, which already held the binding-init computations and their `BeginScope`s, so any side-effecting init in `(let ((x (mutate))) t)` silently disappeared. Drop the shortcut. The body is appended (empty is fine — values pushed by the inits are consumed by `BeginScope`, the trailing `EndScope`s leave the stack balanced) and the inits run. Add four regression tests covering both `let` and `let*`, body that ignores the binding, and sequential lets in one progn.
`(progn)`, `(let ((x 5)))`, and `(let* ((x 5)))` are well-formed in Emacs and evaluate to nil. Tulisp's bytecode `compile_progn` returned an empty instruction sequence regardless of `keep_result`, so a caller wanting a value (e.g. inside `(princ …)`) found nothing on the VM stack and panicked with `attempt to subtract with overflow`. The tree-walker `impl_let` rejected empty body outright with a TypeMismatch. Push nil from `compile_progn` when the form list is empty and a result is wanted, and drop the `body.consp()` check in `impl_let` — its `eval_progn` already returns nil on an empty form list. Adds four regression cases covering progn, let, let*, and an empty progn nested in a position that consumes a value.
The recorded location for a Rust-side defun is the source line of
the ctx.defun() call (via #[track_caller]). For multi-line
registrations like
ctx.defun(
"set-voltage-per-phase",
move |...| { ... },
);
the recorded line is just ` ctx.defun(` -- the name lives one
line later. tags_table previously used that line as the etags
preamble, so emacs's tag-find couldn't locate the name on the
recorded line and fell back to a forward search through the file,
landing on the wrong occurrence (often a call site rather than the
registration).
Walk forward up to 8 lines looking for one that contains the name
literal. If found, use it as the preamble (and adjust the line
number / byte offset accordingly). Single-line registrations and
.lisp source's `(defun NAME ...)` forms hit the fast path on the
recorded line itself, so they're unaffected.
The follow-load-files arm of the parser called `inner.cadr()?.as_string()?`
on every `(load X)` it saw — propagating an error up if X was a
variable / expression rather than a literal path. That error
aborted the parse of the enclosing form, so any defun whose body
contained `(load some-var)` got dropped from the tags table along
with every defun that came after it in the file.
Concretely, sim/common.lisp's load-overrides has
(let ((path (overrides-path)))
(when (file-exists-p path)
(load path)))
— and that single dynamic load form was killing tags for both
load-overrides itself and scenario-end-after that followed it.
Gate the recursive descent on `as_string` succeeding via let-chain;
fall through silently if not. We can't statically know the path
of a dynamic load anyway, so skipping is the right behaviour.
The string-literal case still gets followed.
Cleans up three rustfmt drifts that were sitting on main: a use-list sort in src/bytecode/interpreter.rs, a stray blank line at the end of src/lists.rs, and a function signature in src/plist.rs that fits on one line at the current width.
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.
Also expose parse_file + etags polish