Files
RustAst/docs/record_optimizations_plan.md
T
Michael Schimmel bf74795e01 Refactor: Implement Record Layouts and Optimized Field Access
Introduces a new `RecordLayout` system for efficient and type-safe
record handling.

Key changes:
- `RecordLayout` struct with `O(1)` field lookup using FMap
  optimization.
- Field accessors (`.name`) are now first-class callable values.
- Parser recognizes dot-prefixed identifiers as field accessors.
- Binder and TypeChecker handle field accessors.
- Optimizer transforms field accessor calls into specialized `GetField`
  nodes.
- VM executes `GetField` efficiently by directly accessing record
  values.
- Adds a new `records.myc` example showcasing record features.
- Improves comparison logic for records to use pointer equality for
  layout.
2026-02-26 21:38:20 +01:00

56 lines
2.7 KiB
Markdown

# Plan: Record Layout & Optimized Field Access
This document outlines the implementation plan for porting Delphi's `TKeywordMappingRegistry` optimizations to the Rust-based Myc AST compiler and integrating first-class field accessors.
## 1. Core Data Structures (`src/ast/types.rs`)
### RecordLayout (The Schema)
- **Concept:** Replaces `IKeywordMapping<IStaticType>`.
- **Interning:** Managed via a global `OnceLock<Mutex<HashMap<..., Arc<RecordLayout>>>>`.
- **FMap Optimization:**
- Stores `fields: Vec<(Keyword, StaticType)>`.
- Maintains a lookup array `Vec<i32>` mapping `Keyword.idx - first_key` to the index in the fields array.
- Provides `index_of(Keyword) -> Option<usize>` with **O(1)** complexity.
- **Thread Safety:** Uses `Arc` for global sharing across script threads.
### Value & StaticType Updates
- `Value::Record` points to an `Arc<RecordLayout>` and a flat `Rc<Vec<Value>>`.
- `Value::FieldAccessor(Keyword)` added as a first-class callable value (e.g., `.name`).
- `StaticType::Record` now holds `Arc<RecordLayout>`.
## 2. Compiler Pipeline
### Parser (`src/ast/parser.rs`)
- Identifiers starting with `.` (e.g., `.age`) are parsed as `UntypedKind::FieldAccessor(Keyword)`.
- This ensures interning happens immediately; strings are never used for field access in subsequent phases.
### Binder (`src/ast/compiler/binder.rs`)
- Maps `UntypedKind::FieldAccessor` to `BoundKind::FieldAccessor`.
### TypeChecker (`src/ast/compiler/type_checker.rs`)
- **Analysis Only:** When encountering `Call { callee: FieldAccessor, args: [rec] }`:
- Validates that `rec` is a Record.
- Uses `RecordLayout::index_of` to find the field's type.
- Sets the call's return type accordingly.
- **Crucial:** Does NOT modify the AST structure. It remains a `Call`.
### Optimizer (`src/ast/compiler/optimizer/engine.rs`)
- **Transformation:** Recognizes the `Call { callee: FieldAccessor, ... }` pattern.
- Transforms it into a specialized `BoundKind::GetField { rec, field: Keyword }` node.
## 3. Execution (`src/ast/vm.rs`)
### Optimized Path (`GetField`)
- The VM executes `GetField` by:
1. Evaluating the record.
2. Calling `layout.index_of(field)` (O(1)).
3. Fetching the value from the flat array.
### Functional Path (`FieldAccessor`)
- If `.field` is passed as a value (e.g., `(map .name users)`), the VM treats the `FieldAccessor` value as a standard function that takes one argument and performs the lookup.
## 4. Benefits
- **Type Identity:** `Arc::ptr_eq` allows instant type comparison.
- **Performance:** Field access in loops is O(1) without hash lookups.
- **Safety:** The TypeChecker remains a pure analysis phase as per design requirements.