Add block scoping and statement/expression distinction
Implement strict block scoping and distinguish between statements and expressions. This change introduces hierarchical scopes for functions and blocks, enforces that `def` is a statement with no return value, and prevents statements from appearing in expression positions or as the last element of a block. A new example `design-flaw.myc` is added to demonstrate the uninitialized variable issue solved by these changes.
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
# 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 (In Progress)
|
||||
1. [ ] Update `CompilerScope` to support hierarchical nesting via a stack in `FunctionCompiler`.
|
||||
2. [ ] Implement `push_scope` and `pop_scope` in `Binder`.
|
||||
3. [ ] Refactor `resolve_variable` to traverse the scope stack (inner-to-outer).
|
||||
4. [ ] Update `define_variable` to enforce "No Shadowing" at the current scope level.
|
||||
|
||||
### Phase 2: Statement/Expression Validation
|
||||
1. [ ] Introduce a mechanism to track "Context" (Expression vs. Statement) during binding.
|
||||
2. [ ] Validate that `def` is only used in statement positions.
|
||||
3. [ ] 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.
|
||||
Reference in New Issue
Block a user