Commit Graph

160 Commits

Author SHA1 Message Date
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 f88992da61 Add Stream support for field accessors
The type checker now correctly handles unwrapping `Stream(T)` types for
lambda arguments.
A new `build_map_stream` function has been added to `rtl/streams.rs` to
facilitate field access on streams.
The `create-random-ohlc` function now returns a `Stream` instead of a
`Series`.
Examples have been updated to reflect these changes and demonstrate
stream usage.
2026-03-07 20:47:05 +01:00
Michael Schimmel f797ac37bf Refactor: Simplify type checking context
The type checker's fallback logic for non-lambda nodes was unnecessarily
complex. This commit simplifies it by directly checking the node within
a new, basic type context.

Additionally, the environment now explicitly wraps non-lambda AST nodes
in a lambda before type checking, ensuring consistent handling. This
aligns the type checking process for all top-level expressions.
2026-03-06 23:19:52 +01:00
Michael Schimmel 8fa2ca4cb5 Fix: Reindex address in Set bound kind 2026-03-06 17:02:43 +01:00
Michael Schimmel dfc963ef13 Fix: Remove unnecessary Rc::new from LambdaCollector
The `LambdaCollector` was cloning nodes and wrapping them in `Rc`.
However, the `registry` itself is already holding `Rc` clones of the
nodes. This commit removes the redundant `Rc::new` to simplify the code.

This change also addresses a performance regression observed in
benchmarks due to unnecessary atomic overhead from `Arc` in the
`Keyword` type.
2026-03-06 14:18:51 +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 6ebf31e2a0 Refactor specializer to not fold scalars
The specializer now correctly identifies when a compiled value is a
scalar and avoids folding it into a constant node. Instead, it updates
the callee to the specialized version if it's an object. This ensures
that scalar folding does not interfere with the program's execution.
2026-03-05 14:35:29 +01:00
Michael Schimmel 831525b402 Add series, SMA, and WMA indicators
Introduce new indicators for Simple Moving Average (SMA) and Weighted
Moving Average (WMA), along with their Hull Moving Average (HMA)
derivative.

Also refactors series implementation to use `RefCell` for interior
mutability and adds `SeriesMember` trait for better dynamic series
access. Updates `soa_series.myc` example to reflect new series creation
and push syntax.
2026-03-05 14:07:42 +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 78c36cf08d Refactor MacroRegistry to use Rc<MacroMap>
This change introduces Rc<MacroMap> to allow for copy-on-write semantics
when defining macros in nested scopes. When a macro is defined in a
scope that is already shared, the MacroMap is cloned before
modification, ensuring that changes to one scope do not affect others
that share the same map.
2026-03-03 15:55:55 +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 5bc69c267b Refactor Binder to use Diagnostics
The Binder and its helper functions have been updated to accept and
propagate a `Diagnostics` struct. This allows for better error reporting
during the binding phase, enabling the compiler to continue processing
even after encountering errors and collect all issues before halting.

The `BoundKind::Error` node and `StaticType::Error` are introduced as
"poison" nodes/types. These nodes indicate that an error occurred during
compilation, preventing further valid processing of that specific AST
fragment but allowing the compiler to continue with other parts of the
code.

The `Parser` has also been updated to return a `Diagnostics` struct,
enabling it to report errors during the initial parsing stage while
still attempting to build a partial AST. This adheres to the same error
recovery strategy.
2026-03-02 23:12:51 +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 2457eec1bf feat: Implement Pipeline support
Adds support for pipelines, allowing streams to be chained together and
transformed.
This includes new types for `PipeStream` and `SourceAdapter`, along with
modifications
to the `Environment` to manage pipeline execution. A new example
`pipeline.myc`
demonstrates its usage.
2026-03-02 00:32:07 +01:00
Michael Schimmel 807903efbb Add Optional type for filter pipes
Introduces `StaticType::Optional` to represent values that can be either
of a specific type `T` or `Void`. This is crucial for handling
situations in filter pipes where an expression might not always produce
a value.

The type checker now correctly deduces and propagates this `Optional`
type, and the pipeline operator (`pipe`) is updated to unwrap
`Optional(T)` results, yielding `T`. This ensures that the type system
accurately reflects the potential absence of values in intermediate
pipeline steps.

Also includes a minor rename in the tuple-struct example from `pipe` to
`p` for clarity, and registers the `streams` module.
2026-03-01 23:19:00 +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 7126668934 Add prelude and while macro
This commit introduces a new prelude file that defines the `while` macro
and registers it during environment bootstrapping. The `again` macro has
been updated to accept multiple arguments for its recursive call, and
several examples have been adjusted to reflect this change.
Additionally, the `MacroRegistry` in the compiler is now cloneable and
can be moved out of the `MacroExpander`.
2026-02-28 12:41:19 +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 2ad2eb5d43 Remove unused record destructuring tests
These tests were for record destructuring, which has been removed.
The code for record destructuring was also removed from the type checker
and types modules.
2026-02-26 10:58:46 +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 cf87bbeac5 Refactor tuple argument handling in inliner
Remove redundant tuple flattening logic in `map_params_to_args`. The
existing logic for iterating through tuple elements already correctly
handles nested tuples and records by recursively calling
`map_params_to_args`.
2026-02-25 21:19:12 +01:00
Michael Schimmel 42ad8455b0 Refactor tuple flattening in Specializer 2026-02-25 21:09:38 +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
Michael Schimmel d3d1497c02 Refactor: Move optimizer related types to dedicated module
This commit reorganizes the optimizer code by creating a new `optimizer`
module. The `Optimizer` struct and its related logic remain in
`optimizer/optimizer.rs`, while `SubstitutionMap` and `UsageInfo` are
moved to `optimizer/substitution_map.rs`.

This change improves code organization and makes it easier to manage the
optimizer's components.
2026-02-25 19:47:33 +01:00
Michael Schimmel c64902726b Refactor address types to use newtype wrappers
This commit introduces newtype wrappers for `LocalSlot`, `UpvalueIdx`,
and `GlobalIdx` to improve type safety and clarity. These wrappers
replace direct use of `u32` for indices, making the code more robust and
easier to understand.

The changes include:
- Defining `LocalSlot`, `UpvalueIdx`, and `GlobalIdx` structs.
- Implementing `Display` for these new types to provide user-friendly
  output.
- Updating the `Address` enum to use these new types.
- Modifying various compiler components (analyzer, binder, optimizer,
  type checker, environment, VM) to use the new types.
- Adjusting tests to accommodate the changes.
2026-02-25 18:24:26 +01:00
Michael Schimmel 11f6115fc1 Handle macro expansion in lambda collection
Recursively traverse through `BoundKind::Expansion` nodes when
collecting lambdas to ensure that macros correctly expanded into lambdas
are registered. This also updates assignments to global variables to
correctly track lambdas that have been assigned after macro expansion.

Added a new integration test to verify that macro-wrapped function calls
are correctly inlined and optimized, and that unused definitions are
removed by dead code elimination.
2026-02-25 13:47:50 +01:00
Michael Schimmel 3ff7ba9d59 Refactor NodeIdentity to use unique IDs
The `NodeIdentity` struct has been refactored to use a unique `id` field
generated by an atomic counter. This ensures that each `NodeIdentity`
instance is distinct, even if it has the same `SourceLocation`. The
`location` field is now optional, allowing for anonymous nodes.

This change improves the reliability of identity comparisons and
provides a more robust way to manage AST node identities.
2026-02-25 13:43:57 +01:00
Michael Schimmel 7436edc9b5 Forgot to add captures.rs 2026-02-25 12:19:44 +01:00
Michael Schimmel 0371c21523 Refactor: Remove explicit upvalue analysis pass
The `UpvalueAnalyzer` pass is no longer necessary as the binder now
directly tracks captures. This commit removes the `UpvalueAnalyzer`
struct and associated logic from `src/ast/compiler/upvalues.rs`.

The `Binder::bind_root` function now returns the `captures` map, which
is then processed by a new `CapturePass` in `src/ast/environment.rs`
before type checking. This consolidates capture logic within the binder
and its subsequent processing steps.
2026-02-25 12:15:59 +01:00
Michael Schimmel 82daf03522 Refactor function compiler scope handling
Introduce a `ScopeKind` enum to distinguish between root and local
scopes.
This allows the `FunctionCompiler` to correctly handle global variable
declarations in the root scope and local variables in other scopes.
The `define_variable` method is introduced to encapsulate this logic.
2026-02-25 11:19:08 +01:00
Michael Schimmel d109cb2018 Refactor type checking for globals
Introduces a `global_types` field to `TypeContext` and updates the
`TypeChecker` to pass it down. This allows type checking to correctly
infer and set types for global variables, removing the previous
hardcoded `StaticType::Any` for global addresses.
2026-02-25 11:14:19 +01:00
Michael Schimmel 6034216524 Refactor AST inlining and global purity checks
Rename `ast_locals` to `ast_substitutions` for clarity.
Update `is_inlinable_value` to accept `Address` and check global purity
separately.
Simplify inlining logic in `optimize_node`.
2026-02-25 11:09:22 +01:00
Michael Schimmel 283cdf61a4 Refactor UsageInfo and SubstitutionMap
This commit refactors the `UsageInfo` struct to use a single
`HashSet<Address>` for both used and assigned addresses, simplifying the
logic. It also updates the `SubstitutionMap` to use a similar approach
for tracking assigned values.

Key changes include:
- `UsageInfo` now has `used` and `assigned` fields of type
  `HashSet<Address>`.
- `SubstitutionMap`'s `add_local`, `add_global`, `add_upvalue`,
  `remove_local`, `remove_global`, and `remove_upvalue` methods have
  been replaced with a generic `add_value` and `remove_value` that
  operate on `Address`.
- The `Optimizer`'s `collect_pattern_usage` and `visit_node` methods
  have been updated to use the new `UsageInfo` and `SubstitutionMap`
  APIs.
- `Get` and `Set` nodes now use `sub.map_address` to transform addresses
  based on the current substitution.
2026-02-25 10:57:58 +01:00
Michael Schimmel c256a8a992 Refactor: Use generic Define bound kind
This commit consolidates `DefLocal` and `DefGlobal` into a single
`Define` bound kind. This simplifies the AST and makes it more
consistent.

It also introduces `DeclarationKind` to differentiate between variable
and parameter definitions.
2026-02-25 10:45:36 +01:00
Michael Schimmel f995aaf81b Formatting 2026-02-25 09:59:23 +01:00
Michael Schimmel e07acc0208 Refactor optimizer to track upvalue usage
The `UsageInfo` struct has been updated to include tracking for
`used_upvalues` and `assigned_upvalues`. The `collect_usage` function
has been modified to handle these new fields when encountering
`Address::Upvalue`.

The `map_params_to_args` function now takes `body_usage` as an argument
to ensure that parameters assigned to or used in the body are correctly
substituted. A new helper function, `collect_parameter_slots_set`, has
been added to gather all parameter slots within a pattern.

The inlining logic in `Optimizer::inline_call` has been enhanced to
prevent inlining if a parameter is used or assigned in the function body
but cannot be substituted. This addresses a bug where aggressive
inlining could lead to incorrect code generation when parameters were
reassigned.

A new integration test, `test_closure_reassignment_optimization_bug`,
has been added to specifically target and verify the fix for this
inlining issue.
2026-02-24 12:53:06 +01:00
Michael Schimmel 2c652e0140 feat: Improve destructuring and function call type checking
Refine the type checker to correctly handle destructuring of various
collection types (tuples, vectors, matrices, lists, records).

Additionally, prevent implicit type coercion for function arguments,
ensuring that only tuples are passed to functions expecting tuple
arguments. This avoids unexpected behavior where vectors or matrices
might be treated as tuples.

Add a new example file demonstrating pattern matching and destructuring
rules.
2026-02-24 11:37:31 +01:00
Michael Schimmel 683d0f4dbe Simplify tuple flattening and destructuring
The `flatten_tuple` function was unnecessarily recursive. It can now
simply return the elements of the tuple directly. The VM's destructuring
logic has been updated to handle nested destructuring more efficiently.
A new integration test case for multi-level destructuring has been
added.
2026-02-24 10:10:47 +01:00
Michael Schimmel 6810d5fa9f Formatting 2026-02-24 08:51:51 +01:00
Michael Schimmel 51d83562de Refactor Destructure to handle assignments
Renames `DefDestructure` to `Destructure` to better reflect its use in
both definitions and assignments.
Introduces `bind_assign_pattern` to handle assignment destructuring in
the binder.
Adds `test_assign_destructuring` to verify assignment destructuring
functionality.
2026-02-24 08:51:24 +01:00
Michael Schimmel 2b0e7f49d7 Formatting 2026-02-24 08:41:18 +01:00
Michael Schimmel 252b725677 Add support for destructuring def
This commit introduces the `DefDestructure` bound kind and modifies the
binder, analyzer, type checker, and VM to support destructuring in `def`
statements. This allows for pattern matching on the right-hand side of a
`def` to bind multiple variables.

The parser has been updated to accept patterns in `def` statements. The
binder now handles `UntypedKind::Def` with a `target` pattern, rather
than a simple `name`. This enables destructuring.

The `Gemini.md` documentation has been updated to include a new rule for
incremental development.
2026-02-24 08:40:45 +01:00