Commit Graph

81 Commits

Author SHA1 Message Date
Brummel d2cba2d55d Refactor: Simplify series creation and infer element type
The `series` constructor now only accepts the `lookback` limit. The
element type is inferred by the type checker and implicitly added as a
schema argument during compilation. This simplifies the API and
centralizes type inference.

This change also includes:
- Updates to example scripts (`HMA.myc`, `sma.myc`, `soa_series.myc`) to
  reflect the new `series` signature.
- Modifications to the `TypeChecker` to handle the inferred schema
  injection.
- An addition of a regression test for type inference through nested
  closures with `series`.
- Removal of `#[allow(dead_code)]` from several `TypeChecker` methods as
  they are now used.
- Update to `rtl/prelude.myc` macro `cache`.
- Update to `rtl/series/mod.rs` to reflect new signature.
- Update to `ast/types.rs` to allow `series` to be indexed with an
  integer to retrieve its element type.
2026-03-28 13:47:15 +01:00
Brummel 6d0882dd4a Remove example design-flaw.myc
This example demonstrated a known language limitation regarding
conditional `def` statements and has been removed.
2026-03-26 15:10:19 +01:00
Brummel 16af3ae9fc Refactor Examples to use assert_eq
This commit updates all example files to use `assert_eq!` for verifying
output, replacing the previous `Output:` comments. This change makes the
examples more robust and self-testing.

The benchmark results in some examples have also been slightly adjusted,
reflecting minor performance variations after the refactoring.

Additionally, a runtime panic handling mechanism has been introduced in
the VM for function calls, which improves error reporting for unexpected
panics.
2026-03-26 15:07:48 +01:00
Brummel c0125216b4 Add HMA example script
This commit introduces a new example script, `HMA.myc`, which
demonstrates the implementation and usage of the Hull Moving Average
(HMA) indicator.

The script includes factory functions for Simple Moving Average
(`make-sma`), Weighted Moving Average (`make-wma`), and the Hull Moving
Average itself (`make-hma`). It also includes a small example loop to
initialize and print HMA values.
2026-03-26 12:00:27 +01:00
Brummel ee89d2330d feat: Add comments to AST nodes
This commit introduces support for comments within the AST nodes.
Comments are now parsed by the lexer and stored within the `Token`
struct.
These comments are then propagated through various compiler phases,
including
the `Node` struct, ensuring they are preserved in the Abstract Syntax
Tree.
This change enhances the AST's ability to retain source code
information,
which can be valuable for debugging and analysis.
2026-03-25 18:36:53 +01:00
Brummel e65402364d Refactor: Use new NodeKind and clean up Binder definitions
The Binder and related types have been refactored to use the new
`NodeKind` enum instead of the previous `BoundKind`. This commit updates
all references to use the new structure, ensuring consistency across the
compiler's AST representation.

Key changes include:

- Replacing `BoundKind` with `NodeKind` in the Binder's `bind` and
  `visit` methods.
- Updating pattern matching and field access to reflect the new enum
  variants (e.g., `NodeKind::Def` instead of `BoundKind::Define`).
- Adjusting identifier bindings to use the new `IdentifierBinding` enum.
- Reflecting changes in `DefBinding`, `AssignBinding`, and
  `LambdaBinding` structures.
- Ensuring all newly created nodes use `NodeKind` and the appropriate
  metadata.
2026-03-21 14:12:14 +01:00
Brummel e4be31729e Update benchmark results in examples 2026-03-17 17:33:24 +01:00
Michael Schimmel 3b063dc2c9 Add block scoping and statement/expression distinction
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.
2026-03-10 17:03:46 +01:00
Michael Schimmel 961168f3b6 Refactor analyzer to return impurity
The `Analyzer` is now responsible for determining the purity of `Define`
bindings. Previously, this responsibility was left to the caller.

Added a new example `design-flaw.myc` to test this change.
Updated `soa_series.myc` due to the purity change.
2026-03-10 16:13:39 +01:00
Michael Schimmel 348b1686f2 Refactor soa_series example to use a constant for ticks 2026-03-10 15:34:10 +01:00
Michael Schimmel 11fc1e0e48 Add 'again' macro for recursive expansion
The 'again' macro is a new addition to the macro system, allowing for
recursive macro expansion. This commit introduces the necessary AST
nodes, macro expansion logic, and an integration test to ensure its
functionality. The `soa_series.myc` example has also been updated to
demonstrate its usage.
2026-03-09 11:22:32 +01:00
Michael Schimmel fa23a4c125 Refactor UntypedKind::Parameter to Identifier
The `Parameter` kind in `UntypedKind` was only used for identifiers that
were being declared or referenced. This commit renames it to
`Identifier` and updates all the necessary code to reflect this change.
This simplifies the AST and makes it more consistent.

Additionally, a new macro `repeat` has been added to
`src/ast/system.myc`.
2026-03-09 11:08:30 +01:00
Michael Schimmel 4dfdc75545 Refactor: Introduce system library
- Add `rtl/system.myc` as the system library, containing core utilities
  like `while` and `cache`.
- Remove the duplicate `prelude.myc` from `src/ast/rtl/`.
- Modify `Environment::collect_dependencies` to implicitly add `#use
  system` when necessary.
- Update `Environment::with_cwd` to also add the `rtl` subdirectory to
  search paths.
- Add `target/` to `.geminiignore` to exclude build artifacts.
- Adjust example `sma.myc` to use the new `cache` macro and reduce
  sample data size.
- Update `rtl/sma.myc` to correctly initialize the `history` series with
  its `length`.
- Add `preload_dependencies` calls to `dump_ast` and `run_script` for
  proper module loading.
2026-03-08 12:09:32 +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 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 84ef3f9aed feat: Enhance #use directive for directories and cwd
The `#use` directive now supports referencing entire directories,
automatically including all `.myc` files within them. Additionally,
environments are now initialized with the current working directory as a
default search path, simplifying module resolution.
2026-03-06 21:07:27 +01:00
Michael Schimmel a59367ba61 Implement #use directive for dependency management
Introduces the `#use` preprocessor directive, allowing Myc scripts to
explicitly declare dependencies on other Myc libraries. This change
moves dependency management from a command-line argument to an in-script
declaration, ensuring scripts are self-contained and can correctly
resolve macros and other symbols.

Key features include:
- Declarations at the beginning of a file, evaluated before parsing.
- Support for relative paths and a new `->` separator.
- Automatic resolution of dependencies from specified search paths.
- Idempotent loading to prevent duplicate parsing and evaluation.
- No AST pollution; dependency management is a compile-time concern.

The compiler's lexer has been updated to recognize `#` as a comment
character, and the environment now manages search paths and loaded
modules. This lays the groundwork for more complex library structures
and improved code organization.
2026-03-06 20:43:45 +01:00
Michael Schimmel d4ca9c4620 Refactor SMA implementation to lib/sma.myc
Move the SMA implementation from examples/err.myc and examples/sma.myc
to a new dedicated file in lib/. This change also cleans up unused code
and improves the SMA logic.
2026-03-06 17:22:42 +01:00
Michael Schimmel 7b6f6e52bd Fix: Improve series type handling and coercions
This commit enhances the series type handling in `src/ast/rtl/series.rs`
by introducing helper methods `as_float` and `as_int` in
`src/ast/types.rs` to manage type conversions more robustly.

It also updates the function overload resolution in `src/ast/types.rs`
to prioritize exact parameter matches before falling back to implicit
coercions.

Finally, the example `err.myc` has been updated to reflect a more
accurate implementation of a Simple Moving Average (SMA) calculation.
2026-03-06 16:31:50 +01:00
Michael Schimmel 13dc6beb52 Refactor tail call resolution logic
The tail call resolution logic was duplicated in `Environment::call` and
`VM::run`. This commit extracts the tail call resolution logic into a
single method `VM::resolve_tail_calls` and uses it in both places.

Additionally, this commit adds support for series indexing as a form of
tail call, allowing for direct access to series elements through the
`series(index)` syntax. This is useful for back-referencing in
time-series data.

A new example `err.myc` is added to demonstrate basic series usage and
error handling.
2026-03-06 12:35:00 +01:00
Michael Schimmel b9d88f019e Remove unused err.myc example
Update benchmark output for soa_series.myc.
Also, fix the tester to not panic when a baseline is missing, and
instead just report it as missing.
2026-03-06 12:07:39 +01:00
Michael Schimmel 32a1f21463 Add language specification document
This commit introduces the BNF for the Myc language, along with its core
semantics, data types, and evaluation logic. It also details the macro
system and provides an overview of the standard library. This document
serves as a foundational context for LLMs to understand and generate Myc
code.
2026-03-06 11:35:18 +01:00
Michael Schimmel 9ba4f795d1 Change series field type from :msg to :text
Update example to use :text for string fields in series. This aligns
with the new :text type support in the series implementation.
2026-03-05 15:07:31 +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 d1b8d03604 Update benchmark and repeat counts
This commit updates the benchmark and repeat counts for various example
files. These changes reflect potential performance improvements or
variations observed during testing.
2026-03-03 18:55:31 +01:00
Michael Schimmel a18642fd7b Update example output comments
Add `Output` comments to the example files to reflect the actual output
of the programs. This helps with verifying correctness and understanding
example behavior.
2026-03-02 23:46:44 +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 a4af142719 Refactor random number generation to factory
- Use a `make-random` factory to create isolated random number
  generators.
- Remove the global `prng` from the `Environment`.
- Ensure `make-random` can be called with or without a seed.
2026-03-02 14:01:36 +01:00
Michael Schimmel f3459baf43 Add create-ticker function
Implements the `create-ticker` function, which allows for the creation
of a ticker stream based on a provided condition closure. This function
is crucial for synchronizing pipeline execution based on specific events
or conditions.
2026-03-02 13:15:56 +01:00
Michael Schimmel 86a6db28d8 Update pipeline.myc 2026-03-02 00:32:15 +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 46b546446f Add RecordSeries::get_record and support for (my_ticks 0)
This commit introduces the `get_record` method to `RecordSeries`,
allowing for the dynamic reconstruction of a full record from its
constituent fields at a given index. This enables idiomatic access to
series data using indexing like `(my_ticks 0)`.

The `push-series` function has also been updated to correctly handle the
structure of records when pushing data into a `RecordSeries`.
2026-03-01 18:44:46 +01:00
Michael Schimmel b612df6e10 Add Series RTL and SeriesView
Introduces a new RTL module for handling series data, enabling efficient
storage and retrieval of time-series data in a Struct-of-Arrays (SoA)
format.

Includes `SeriesView`, a zero-copy wrapper that provides a fast,
read-only interface to individual columns within a `RecordSeries`,
optimizing performance for data access in the VM.

Registers new native functions `create-series` and `push-series` for
managing series data.
2026-02-28 21:47:14 +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 096f166153 Update benchmark numbers
These changes update the benchmark numbers and repeat counts in the
example files. The benchmark results have slightly varied, and these
updates reflect the most recent measurements.
2026-02-28 16:02:38 +01:00
Michael Schimmel 2cc47c557b Update benchmark results
This commit updates the benchmark results for various examples. The
benchmark times and repeat counts have been adjusted to reflect current
performance characteristics.
2026-02-28 14:27:54 +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 83324a1892 feat: Document AST node structure across compiler stages
Add a new Markdown document detailing the AST node structure as it
evolves through the compiler's different stages. This includes a diagram
illustrating the data flow and relationships between the generic
`Node<K, T>` structure and its specialized forms (`UntypedNode`,
`BoundNode`, `TypedNode`, `AnalyzedNode`). The document explains the
`kind` and `ty` payloads for each stage and their significance.

Also removes a deleted file related to a previous optimization plan and
adds new files for future optimization plans.
2026-02-27 08:58:38 +01:00
Michael Schimmel e104e7f59b Add benchmark data to object_records.myc 2026-02-26 21:59:09 +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 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 b12b85f54a Create optimizer_collision_repro.myc 2026-02-25 13:44:08 +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 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