3b063dc2c9
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.
2.2 KiB
2.2 KiB
Development Log: Binder Refactoring & Block Scoping
Status Quo
- Myc currently uses a flat scope per function.
defis treated as a side-effect expression that "leaks" into the function scope regardless of nesting (e.g., insideifordo).- 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
- Block Scoping: Every
(do ...)andifbranch creates a new lexical scope. - Statements vs. Expressions:
defis 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).
- No Shadowing: Redefining a symbol within the same scope level is an error. Shadowing from outer scopes is allowed (standard lexical scoping).
- Self-Reference: A variable is only available in its scope after its definition is complete (RHS of
defsees outer scope).
Implementation Plan
Phase 1: Binder Infrastructure (In Progress)
- Update
CompilerScopeto support hierarchical nesting via a stack inFunctionCompiler. - Implement
push_scopeandpop_scopeinBinder. - Refactor
resolve_variableto traverse the scope stack (inner-to-outer). - Update
define_variableto enforce "No Shadowing" at the current scope level.
Phase 2: Statement/Expression Validation
- Introduce a mechanism to track "Context" (Expression vs. Statement) during binding.
- Validate that
defis only used in statement positions. - Enforce that the last node in a
BoundKind::Blockis an expression.
Phase 3: VM Compatibility
- Ensure the VM handles "Void" results from statements correctly.
- (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.