Files
RustAst/docs/binder-refactoring-log.md
T
Michael Schimmel a78e72d074 Refactor Binder to use new scope structure
This commit refactors the Binder implementation to better align with the
updated scope structure.
Key changes include:

- Introducing `ExprContext` to distinguish between statement and
  expression contexts.
- Modifying `define_variable` to handle both global and local scope
  definitions more robustly.
- Updating `resolve_variable` to correctly handle upvalue captures,
  especially for global addresses.
- Adjusting `bind` and related functions to use the new `ExprContext`.
- Updating the refactoring log to reflect completed phases.
2026-03-10 17:20:47 +01:00

53 lines
2.7 KiB
Markdown

# Development Log: Binder Refactoring & Block Scoping
## Status Quo
- Myc currently uses a flat scope per function.
- `def` is treated as a side-effect expression that "leaks" into the function scope regardless of nesting (e.g., inside `if` or `do`).
- This leads to uninitialized variables at runtime if the definition is skipped by control flow.
## Goal
Implement strict **Block Scoping** and distinguish between **Statements** and **Expressions** to eliminate undefined variable states.
### Rules
1. **Block Scoping:** Every `(do ...)` and `if` branch creates a new lexical scope.
2. **Statements vs. Expressions:**
- `def` is a **Statement**.
- Statements have no return value (Void).
- Statements **cannot** be used as expressions (e.g., as arguments, RHS of assignments, or conditions).
- Statements **cannot** be the last element of a block (since the block's value is determined by its last expression).
3. **No Shadowing:** Redefining a symbol within the **same** scope level is an error. Shadowing from outer scopes is allowed (standard lexical scoping).
4. **Self-Reference:** A variable is only available in its scope **after** its definition is complete (RHS of `def` sees outer scope).
## Implementation Plan
### Phase 1: Binder Infrastructure (Completed)
1. [x] Update `CompilerScope` to support hierarchical nesting via a stack in `FunctionCompiler`.
2. [x] Implement `push_scope` and `pop_scope` in `Binder`.
3. [x] Refactor `resolve_variable` to traverse the scope stack (inner-to-outer).
4. [x] Update `define_variable` to enforce "No Shadowing" at the current scope level.
### Phase 2: Statement/Expression Validation (Completed)
1. [x] Introduce a mechanism to track "Context" (Expression vs. Statement) during binding.
2. [x] Validate that `def` is only used in statement positions.
3. [x] Enforce that the last node in a `BoundKind::Block` is an expression.
### Phase 3: VM Compatibility
1. [ ] Ensure the VM handles "Void" results from statements correctly.
2. [ ] (Optional) Optimize stack allocation based on scope depth.
---
## Log Entries
### 2024-05-22: Initialization
- Analyzed `design-flaw.myc`.
- Defined the "Statement" concept to solve the uninitialized variable problem.
- Initialized this log.
### Phase 1 & 2 Completed
- Introduced scope stack into `FunctionCompiler`.
- Introduced `ExprContext` (`Expression` / `Statement`) in the `Binder`.
- `def` now acts strictly as a statement.
- Variables defined inside nested scopes (e.g. inside `if` or `do`) do not leak into outer local scopes anymore.
- Outstanding behavior to discuss: `def` inside nested scopes at the *root* level still leaks into globals.