Commit Graph

19 Commits

Author SHA1 Message Date
Michael Schimmel 260669cba1 Perf: Restore core optimizations and stabilize VM execution
This commit restores and enhances several high-performance features that
were
previously lost, while fixing critical bugs in scope management.

Performance Optimizations:
- Zero-Copy TCO: Refactored TailCallRequest to use (Rc, usize), moving
  arguments
  directly on the VM stack via drain/resize instead of heap-allocating
  Vecs.
- Slice-based Calls: Native functions and field accessors now operate
  directly
  on stack slices, significantly reducing memory churn.
- SoA Push Fast-Path: Restored specialized 'push' intrinsic for
  RecordSeries.
  Matches layouts via Arc::ptr_eq to distribute values directly into
  columns
  without keyword lookups.

Architectural Improvements:
- Static Stack Frames (max_slots): The Binder now calculates the maximum

  required slots per lambda. The VM pre-resizes the stack frame,
  preventing
  collisions between local variables and temporary call arguments.
- Macro Hygiene: Fixed a bug where macro-internal variables could
  overwrite
  outer call arguments due to stack overlap.
- Trait Refactoring: Unified series operations via a polymorphic
  'push_value'
  on the Series trait, with a generic implementation for
  ScalarSeries<T>.

Code Quality:
- Resolved all 'cargo clippy' warnings (collapsible ifs, redundant
  borrows, etc).
- Restored 100% test pass rate (64/64 tests).
- Verified stability of all examples and benchmarks.
2026-03-10 13:06:56 +01:00
Michael Schimmel beb693a068 Refactor: Implement block scoping and statement separation
This commit introduces fundamental changes to Myc's language structure
to enhance type safety and scoping clarity.

Key changes include:
- Introducing local scopes for `do` blocks.
- Separating statements (`def`, `assign`) from expressions, where
  statements now have no return value and are only allowed within
  blocks.
- A block now consists of multiple statements followed by a single final
  expression.
- Stricter validation rules are enforced, such as disallowing
  redefinition of local symbols in the same scope while allowing
  shadowing of outer symbols.
- Compiler errors are generated for statements used in expression
  contexts.

The implementation involved modifications to the AST, parser, binder
(scope-stack), and various compiler passes, along with VM runtime
optimizations.
2026-03-09 16:38:44 +01:00
Michael Schimmel 595bcf09e5 Update examples to use StreamNode and Series with lookback
The `PipelineNode` has been refactored into `StreamNode`. This commit
updates the example files to reflect this change and also updates the
`series` constructor to accept a lookback parameter.

The `PipelineNode` was an artifact of a previous implementation and is
no longer needed. The `StreamNode` is the appropriate type for
representing the output of a pipe operation.

The `series` function now requires a `lookback` argument to specify the
maximum number of items to store. This makes the behavior of series more
explicit and prevents accidental unbounded memory growth.
2026-03-07 23:48:09 +01:00
Michael Schimmel d08fab4f73 Refactor inlining logic into try_inline function
This commit extracts the logic for inlining function calls into a new
private
method, `try_inline`. This improves code organization and reduces
duplication in the `Optimizer`'s `visit_node` method.

The extracted method handles the preparation of substitutions and the
recursive visiting of the inlined node. It also ensures that the
substitution map state is correctly synchronized back to the calling
context.
2026-03-07 21:10:48 +01:00
Michael Schimmel 1342c7ca8e Fix optimizer slot clash during inlining and correct closure reduction
order

   - Add new_for_inlining to SubstitutionMap to preserve the next_slot
     counter, preventing local slot collisions when merging
     scopes.
   - Update Inliner to request fresh slots for parameters during beta
     reduction instead of forcing identity mappings.
   - Fix execution order in Optimizer::visit_node for closure inlining
     to run prepare_beta_reduction before visiting the function
     body, preventing corrupted upvalue captures.
   - Fix CLI --no-opt flag to correctly disable the optimizer in the ast
     binary.
   - Add integration test to prevent future slot clash regressions.
2026-03-06 11:58:28 +01:00
Michael Schimmel 8c4db9a5ba Refactor function signatures to use slices 2026-03-03 18:13:20 +01:00
Michael Schimmel 7c38dee243 Refactor AST nodes to use Rc
This commit refactors various AST node types to use `Rc` (Reference
Counting) instead of `Box`. This change is primarily driven by the need
for shared ownership and more efficient handling of potentially
recursive or shared data structures within the AST.

The main benefits of this change include:

- **Reduced cloning:** `Rc` allows multiple parts of the AST to refer to
  the same node without needing to clone the entire node. This is
  particularly beneficial for optimization passes where nodes might be
  visited multiple times.
- **Enabling sharing:** It makes it easier to represent scenarios where
  a single AST node might be a child of multiple parent nodes.
- **Performance improvements:** By avoiding unnecessary deep copies of
  AST nodes, this change can lead to performance gains, especially
  during complex compilation phases.
2026-03-03 16:07:42 +01:00
Michael Schimmel 078b520c37 Add type aliases for registries
Introduces `GlobalFunctionRegistry` and `GlobalAnalyzedRegistry` type
aliases to clarify the usage of `HashMap`s for storing global functions
and their analyzed versions. This change also refactors the
`LambdaCollector` and `Optimizer` to use these new aliases, improving
code readability and maintainability.
2026-03-03 15:51:47 +01:00
Michael Schimmel 2eb7a2e136 Formatting 2026-03-02 23:13:36 +01:00
Michael Schimmel f7cb6655af feat: Specialize pipeline types for performance
Introduces type specialization for reactive pipeline nodes and their
data buffers. This eliminates the overhead of generic `Value` enums and
`SharedValueSeries` when dealing with known scalar or record types.

The architecture shifts buffer instantiation from the VM to the runtime
(RTL), leveraging type information from the AST. A new `out_type` field
is added to `BoundKind::Pipe` to store the static type of the pipeline's
output, determined by the type checker.

This enables the creation of specialized `RingBuffer<T>` and
`SharedRecordSeries` (for Struct-of-Arrays layout) when the output type
is known, significantly improving memory usage and processing speed for
time-series data, especially in financial analysis.
2026-03-02 22:03:24 +01:00
Michael Schimmel 50f33b2c30 Feat: Add Pipe Node
Introduces a new `Pipe` node to the Abstract Syntax Tree (AST).
This node represents a functional composition pattern, allowing
for chaining of operations.

The changes include:
- Defining the `Pipe` variant in `BoundKind` and `UntypedKind`.
- Implementing parsing logic for the `pipe` keyword.
- Adding handling for the `Pipe` node in various compiler passes
  (analyzer, binder, captures, dumper, macros, optimizer, TCO,
  type checker).
- Including a placeholder implementation for `Pipe` execution in the
  VM.
- Updating integration tests to use the new `pipe` syntax.
2026-03-01 21:52:10 +01:00
Michael Schimmel eab3e02199 Refactor Record's internal representation
This commit refactors the internal representation of `BoundKind::Record`
to store a `RecordLayout` and a `Vec` of values, rather than a `Vec` of
key-value pairs. This change simplifies the representation and improves
efficiency by decoupling the record's structure from its specific values
during compilation and analysis.

The `RecordLayout` now defines the structure of the record, and the
values are stored in a separate vector, ordered according to the layout.
This allows for better optimization and type checking, as the record's
shape is explicitly defined and immutable once created.
2026-02-28 16:47:23 +01:00
Michael Schimmel 3f5d2620ec Refactor: Use new_inner for substitution maps
The `SubstitutionMap::new_inner()` method provides a more robust way to
create nested substitution maps, ensuring that only global substitutions
are inherited. This prevents potential issues with overlapping local and
upvalue addresses in nested scopes, such as during lambda inlining.

This change also includes:
- A new `try_fold_record` method in `folder.rs` to optimize record
  literals into constant values.
- Updates to `inliner.rs` to recognize `Value::Record` for inlining.
- Various test cases to verify record optimization and constant folding.
2026-02-28 16:01:56 +01:00
Michael Schimmel 512193febc Add object-oriented records example 2026-02-26 21:54:26 +01:00
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
Michael Schimmel 81c805f07e Refactor optimizer utilities
Removes unused `flatten_tuple` function from optimizer utilities. The
functionality was moved to the `Folder` struct, making it more
contextually appropriate. This change streamlines the utility module and
improves code organization.
2026-02-25 21:26:12 +01:00
Michael Schimmel 04f2203900 Refactor: Move utils to separate module
Moves `PathTracker` and `UsageInfo` to the `utils` module to improve
code organization.
2026-02-25 20:35:12 +01:00
Michael Schimmel cad0c03973 Refactor: Move inlining logic to Inliner struct
Introduces the `Inliner` struct to encapsulate logic related to value
and function inlining. This improves code organization and readability
within the optimizer engine.

Key changes include:
- Moving `is_inlinable_value` to the `Inliner` struct.
- Extracting beta-reduction preparation logic into
  `Inliner::prepare_beta_reduction`.
- Moving parameter slot collection to
  `Inliner::collect_parameter_slots`.
- Introducing `flatten_tuple` to a new `utils` module, used by both
  `Folder` and `Inliner`.
2026-02-25 20:07:37 +01:00
Michael Schimmel 7f64e7e6ea Refactor Optimizer to use Folder
Extract common AST manipulation and folding logic into a new Folder
struct. This improves code organization and reusability. The Optimizer
now delegates these tasks to the Folder.
2026-02-25 19:57:00 +01:00