Skip to content

Interpret letrec-values#78

Merged
pmatos merged 2 commits into
mainfrom
issue-8
Jul 1, 2026
Merged

Interpret letrec-values#78
pmatos merged 2 commits into
mainfrom
issue-8

Conversation

@pmatos

@pmatos pmatos commented Jul 1, 2026

Copy link
Copy Markdown
Owner

Summary

  • Teach the interpreter to evaluate letrec-values, whose bindings are in scope for both the binding expressions and the body (enabling recursion and mutual recursion), unlike let-values whose expressions evaluate in the enclosing scope.
  • letrec-values reuses the existing LetValues AST node and parseLetValues, distinguished by a new Rec flag; the parser accepts the already-lexed letrec-values keyword.
  • The interpreter pushes a fresh environment and fills it in left to right, keeping it live on the stack while the binding expressions and body evaluate, so clauses can refer to earlier and later bindings the way top-level recursive definitions already do.
  • Free-variable analysis now also walks the binding expressions (previously only the body), shadowing the bound identifiers for letrec-values but not for let-values, so closures enclosing either form capture the correct variables.

Fixes #8

Test plan

  • ctest --preset debug — 14 unit tests pass (adds a letrec-values lexing test)
  • nora-lit test/integration — 52 integration tests pass (adds 4 letrec-values .rkt tests: sequential binding, closure over a later binding, mutual reference, multiple-values clause)
  • clang-format --dry-run --Werror on changed files — clean
  • Debug build is warning-clean (warnings-as-errors)

letrec-values shares the let-values node and parser, distinguished by a Rec flag; its bindings are kept live on the environment stack while their expressions and the body evaluate, so clauses can refer to earlier and later bindings for (mutual) recursion. Free-variable analysis now also walks binding expressions, shadowing them for letrec but not for let.
@pmatos pmatos mentioned this pull request Jul 1, 2026
@codecov

codecov Bot commented Jul 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 81.96721% with 11 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.41%. Comparing base (1ca9b29) to head (9cbd29c).

Files with missing lines Patch % Lines
src/Interpreter.cpp 71.42% 10 Missing ⚠️
src/AST.cpp 50.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #78      +/-   ##
==========================================
+ Coverage   73.19%   74.41%   +1.22%     
==========================================
  Files          24       24              
  Lines        2108     2146      +38     
  Branches      290      299       +9     
==========================================
+ Hits         1543     1597      +54     
+ Misses        565      549      -16     
Flag Coverage Δ
integration 74.41% <81.96%> (+1.22%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@claude

claude Bot commented Jul 1, 2026

Copy link
Copy Markdown

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

Cover the AnalysisFreeVars change with closures that enclose a let-values and a letrec-values whose binding expression captures a free variable, exercising the previously untested binding-expression traversal flagged by codecov on PR #78.
@pmatos

pmatos commented Jul 1, 2026

Copy link
Copy Markdown
Owner Author

Regarding the Codecov patch-coverage report: the meaningful gap was the new AnalysisFreeVars::visit(LetValues) binding-expression traversal (6 lines, 0%), which no test exercised because none nested a let/letrec-values inside a closure.

Fixed in 9cbd29c.

  • Changed: added two integration tests — test/integration/letrec-values4.rkt and test/integration/let-values4.rkt — each a closure enclosing a letrec-values / let-values whose binding expression captures a free variable from the surrounding lambda. These drive free-variable analysis over the binding expressions for both the letrec and let branches.
  • Validation: cmake --build --preset debug (warning-clean), ctest --preset debug, and nora-lit test/integration (now 54/54) all green.

The remaining uncovered lines are left intentionally: the bindClause error branches in src/Interpreter.cpp require malformed programs that aren't expressible with the current runtime (only +/-/* are registered, no predicates), and the AST.cpp line is the debug-only LLVM_DUMP_METHOD dump() label. Both Codecov checks were already passing (non-blocking).

@pmatos pmatos merged commit 0a9c2e7 into main Jul 1, 2026
20 checks passed
@pmatos pmatos deleted the issue-8 branch July 1, 2026 20:26
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.

Interpret letrec-values

1 participant