This commit introduces a new mechanism for calculating the required
stack size for closures at bind time, rather than storing it in the AST.
This is achieved by adding a `calculate_stack_size` method to
`BoundNode`.
Key changes include:
- `BoundNode::calculate_stack_size`: Recursively traverses the bound AST
to find the maximum `LocalSlot` index used.
- Recursion blocker for lambdas: Ensures that nested lambdas are not
visited during stack size calculation for the outer closure,
preventing incorrect stack size estimations.
- VM update: The `VM::run` method now accepts and uses the
pre-calculated stack size for setting up call frames.
- `Closure` struct update: Stores the `stack_size` directly within the
`Closure` struct.
- Binder and TypeChecker updates: Minor adjustments to accommodate the
new strategy and error reporting.
- Optimizer enhancements: Constant and pure-lambda propagation for
`Define` statements within blocks to ensure inlinability.
This refactoring addresses issues related to accurate stack size
management and improves the overall robustness of the binder and VM.
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.
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.