Commit Graph

59 Commits

Author SHA1 Message Date
Brummel 10a7fcb576 Refactor: Replace Object with StreamStorage for streams
The `Object` trait is too generic and has been causing confusion. This
commit introduces `StreamStorage` as a dedicated trait for reactive
stream types.

This change involves:

- Renaming `Object` to `StreamStorage` in relevant places.
- Updating the `Value::Object` enum variant to `Value::Stream`.
- Modifying how streams are handled in the compiler, VM, and tests to
  use the new `StreamStorage` trait.
- Adjusting example scripts and tests to reflect the change in type
  representation.
- The `StreamNode` struct now explicitly holds its `element_type`.
2026-03-29 18:01:46 +02:00
Brummel 84abbd9721 Add Forall type for polymorphism
Introduce `StaticType::Forall` to represent universally quantified
types. This enables Hindley-Milner's let-polymorphism, allowing
functions to be generalized and reused with different concrete types.

- **Generalization at `def`:** Function values are now generalized using
  `self.generalize` when they are defined, wrapping their type in
  `Forall`. This occurs at `def` boundaries.
- **Instantiation at use:** Function types are instantiated with fresh
  type variables at each call site using `self.instantiate`. This
  ensures that different uses of the same polymorphic function do not
  interfere with each other's type inference.
- **Value restriction:** Only function-typed definitions are
  generalized. Mutable state like series and scalars remain monomorphic
  to prevent unexpected behavior.
- **Type context awareness:** The `generalize` function considers the
  current type context to avoid quantifying type variables that are
  still in use elsewhere.
  Feat: Add Forall type for polymorphism

Introduces the `Forall` type to support polymorphic functions and enable
let-polymorphism.

- `Forall(vars, body)`: Represents a universally quantified type where
  `vars` are the type variables bound by this quantification, and `body`
  is the type itself.
- `TypeChecker::generalize`: Wraps a type in `Forall` when a `def`
  boundary is encountered for function-typed values. This ensures that
  each use site of a polymorphic function gets its own instantiation.
- `TypeChecker::instantiate`: Replaces the type variables within a
  `Forall` type with fresh ones. This is performed at each call site of
  a polymorphic function.
- Updates `TypeChecker::unify` and `TypeChecker::apply_subst` to
  correctly handle `Forall` types, ensuring that bound variables within
  a `Forall` are not affected by global substitutions and that `Forall`
  types are instantiated before unification.
- Adds a new example script `examples/Propa.myc` to demonstrate basic
  usage.
- Includes a regression test
  `test_let_poly_non_series_callable_no_false_positive` to ensure that
  passing non-series callables to generic functions does not lead to
  type errors.
- Introduces `TypeChecker::bind_var` to handle lazy propagation of
  index-call constraints, crucial for correctly typing series lookups
  like `(s 0)`.
2026-03-28 22:49:44 +01:00
Brummel d7d1aef8ed Refactor type checker for series and overloads
Introduce `unify_matched_overload` to handle type variable propagation
for overloaded functions. This ensures that when an overload is chosen,
its concrete parameter types are unified with the actual argument types.
This is crucial for resolving type variables nested within closures
called through overloaded functions.

Additionally, this commit:
- Allows `series` to infer schema type from `push` calls, simplifying
  its signature.
- Adds a fallback to `ValueSeries` in `rtl::series` if schema injection
  fails.
- Updates `StaticType::TypeVar` to return `Any` when accessed,
  simplifying field access logic.
- Adjusts tests to reflect the simplified `series` signature.
2026-03-28 14:03:48 +01:00
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 e595e747d4 Add type inference infrastructure
Introduces a `TypeChecker` struct with logic for Hindley-Milner type
inference.
This includes:
- `var_counter` for generating unique type variable IDs.
- `subst` for the global substitution map.
- `fresh_var` to create new type variables.
- `apply_subst` to resolve type variables recursively.
- `occurs` to check for cycles during unification.
- `unify` to merge types and extend the substitution.

The `StaticType` enum is extended with a `TypeVar(u32)` variant to
represent unresolved type variables.
The `Display` and `is_assignable_from` implementations for `StaticType`
are updated to handle `TypeVar`.
2026-03-28 13:08:15 +01:00
Brummel e757b453a4 feat: Add AST emitter and comment support
Introduces a new AST emitter module responsible for serializing AST
nodes back into Myc source code. This emitter preserves leading comments
and whitespace, enabling a round-trip guarantee for the parser and
emitter.

The documentation in `docs/BNF.md` has been updated to reflect the new
syntax rules for comments, including single-line comments (`;`) and
documentation comments (`;;`). The rules clarify that comments must be
whole lines and that inline comments are disallowed.

The lexer and AST node structures have been updated to accommodate
`CommentLine` variants, allowing for different types of comments
(regular, documentation, and blank lines) to be stored and processed.

A new test suite `tests/comment_roundtrip.rs` has been added to verify
the round-trip property of the parser and emitter across all example
`.myc` files. This test ensures that parsing source code, emitting it,
and then parsing the emitted code again results in the same output
string.

The `ast.rs` binary now includes a `--emit` flag that uses the new
emitter to output the parsed source code, facilitating debugging and
testing of the emitter itself.
2026-03-25 19:15:40 +01:00
Brummel b436e09840 Add documentation infrastructure for RTL symbols
Introduces `RtlDocEntry` and `RtlRegistration` structs to store and
manage documentation for native functions and constants. The
`Environment` struct is updated to include a registry for these
documentation entries.

The `register_native_fn` and `register_constant` methods now return an
`RtlRegistration` builder, allowing for optional chaining of `.doc()`,
`.description()`, and `.examples()` methods before the registration is
finalized when the builder is dropped.

Macros `rtl_fn!` and `rtl_const!` are introduced to simplify the
registration process with documentation.

The MCP server is extended with `get_rtl_docs` and `get_symbol_doc`
tools to expose this documentation externally.

Specific RTL functions and constants (e.g., `+`, `-`, `*`, `/`, `NaN`,
`true`, `false`, `date`, `now`, math functions, `series`, `push`, `len`,
`create-random-ohlc`, `create-ticker`, `pipe`) have been updated to
include their respective documentation using the new infrastructure.

The `Signature` and `StaticType` types have gained `to_doc_string`
methods for generating human-readable documentation strings.
2026-03-25 15:02:19 +01:00
Brummel 6042415dfc Refactor series types and value enum
This commit refactors the way series are represented and handled within
the AST.
Key changes include:

- Introducing `SeriesStorage` and `PushableStorage` traits to provide a
  more
  unified and type-safe interface for series data.
- Renaming `Object` trait and its methods to clarify that it's for RTL
  extensions
  other than series (like Streams).
- Updating the `Value` enum to have a distinct `Series` variant,
  separating it
  from `Object`.
- Adjusting various parts of the `VM` and `register` functions to work
  with the
  new series traits and `Value::Series` variant.

This change aims to improve the type system's clarity and safety when
dealing with
series data, aligning with Rust's best practices for trait design.
2026-03-23 16:05:58 +01:00
Brummel a5c3f3da04 feat: Add bidirectional type inference for lambdas
This commit introduces bidirectional type inference, enabling the
compiler to infer lambda parameter types based on the context of their
usage. This is particularly useful for functions like `pipe`, where a
lambda's signature can be deduced from the types of the streams it
operates on.

Key changes include:

- **`extract_lambda_param_hints` function:** This new helper function in
  `type_checker.rs` is responsible for extracting expected parameter
  types for a lambda based on the callee's signature and already known
  argument types.
- **`check_lambda_with_param_hints` function:** This function allows
  type-checking a lambda node using provided parameter type hints,
  preserving upvalue types from the enclosing scope.
- **Call expression type checking:** The `check_call` function now
  phases its argument type checking. Non-lambda arguments are typed
  first, and then lambda arguments are typed using hints derived from
  `extract_lambda_param_hints`.
- **`pipe_arg_hint_resolver`:** This new resolver for the `pipe`
  function's `PolymorphicFn` type allows it to provide specific type
  hints for its lambda argument based on the types of its stream inputs
  (single stream, vector of streams, or tuple of streams).
- **`StaticType::PolymorphicFn` update:** The `PolymorphicFn` enum
  variant has been extended to include `resolve_arg_hints`, enabling
  functions to provide lambda parameter hints during bidirectional type
  inference.
- **New tests:** Added tests to verify the correct inference of lambda
  parameters for `pipe` with vector and tuple inputs, ensuring that
  inner stream types are correctly propagated. Also, a test to confirm
  `pipe` with an optional return still produces `Stream(Float)`.
2026-03-23 10:51:06 +01:00
Brummel 1875cfdc9b Remove unused pipe node definitions
The `Pipe` node and its associated logic have been removed from the AST.
This commit cleans up the code by removing all references to this
defunct node in the analyzer, binder, captures, dumper, lowering,
macros, optimizer, and type checker. The parser no longer recognizes the
`pipe` keyword.
2026-03-23 10:22:12 +01:00
Brummel 09ae98728f Refactor Value enum for Quote node
Replaces `Value::Object(Rc<dyn Object>)` for SyntaxNodes with a
dedicated `Value::Quote(Rc<SyntaxNode>)`. This provides better type
safety and clarity when dealing with AST nodes as values.
Refactor Value enum for Quote node

This commit introduces a new `Value::Quote` variant to represent quoted
AST nodes directly, replacing the generic `Value::Object` for this
purpose.

This change simplifies the handling of quoted nodes by:
- Directly storing an `Rc<SyntaxNode>` instead of relying on dynamic
  downcasting from `Rc<dyn Object>`.
- Streamlining macro expansion logic by removing the need to check for
  `SyntaxNode` within `Value::Object`.
- Improving type safety and explicitness in the `Value` enum.
2026-03-22 20:53:30 +01:00
Brummel ae1d94e507 Refactor PushableSeries trait
Introduce a new trait `PushableSeries` to distinguish objects that can
have values pushed into them from those that are only readable series.
This clarifies the API and allows for more precise type checking.

The `Object` trait no longer has a default `push_value` implementation.
Instead, `PushableSeries` now provides this functionality.
`SeriesMember` has also been updated to require `PushableSeries` for
RecordSeries field buffers.
2026-03-22 19:45:50 +01:00
Brummel 843ee7dfed Refactor: Use Value::Closure enum variant
Previously, compiled closures were stored as `Value::Object` and then
downcasted. This commit introduces a dedicated `Value::Closure` enum
variant to represent compiled closures. This improves type safety and
simplifies handling of closures throughout the compiler and VM.

This change involves:
- Updating type definitions to use `Value::Closure`.
- Adjusting downcasting logic to directly access the `Closure` struct.
- Modifying `run_with_args` and `run_with_args_observed` to expect
  `Value::Closure` for tail-call targets.
- Refining the handling of closures in the `Optimizer` and `Inliner` for
  better type clarity.
2026-03-22 19:41:23 +01:00
Brummel 37d7ed3e75 Remove unused TailCallRequest variant
The `TailCallRequest` enum variant and its associated logic have been
removed. Instead, the VM now uses an `Option<(Rc<dyn Object>,
Vec<Value>)>` field named `tail_call` to manage tail-call requests. This
change simplifies the `Value` enum and centralizes tail-call handling
within the `VM` struct.
2026-03-22 19:20:18 +01:00
Brummel f6c963cb41 Add into_rc_any and push_value to Object
This commit introduces the `into_rc_any` and `push_value` methods to the
`Object` trait.

The `into_rc_any` method allows for efficient, zero-cost downcasting of
`Rc<Self>` to `Rc<dyn Any>`. This is a crucial step for enabling more
flexible dynamic dispatch and type manipulation within the VM.

The `push_value` method is implemented for series types (`ScalarSeries`,
`ValueSeries`, `RecordSeries`) to allow pushing values directly onto
them. This simplifies the `push` intrinsic function, removing the need
for manual downcasting within its implementation. The default
implementation for non-series objects panics, enforcing that only
mutable series support this operation.

Additionally, `ScalarValue` now includes a `from_value` method to
facilitate converting `Value` back into concrete scalar types. This
improves type safety and reduces boilerplate code when handling scalar
conversions.
2026-03-22 19:04:32 +01:00
Brummel db443df932 Implement Display for SharedValueSeries
The `Value::Object` variant in `ast/types.rs` has been updated to
provide a more specific display format for `SharedValueSeries`.
Previously, it would generically display the object's type name. This
change allows it to directly show the length of the `SharedValueSeries`
buffer, which is more informative.
2026-03-22 18:40:23 +01:00
Michael Schimmel 84226f6a16 Refactor: Replace UntypedNode with SyntaxNode
This commit replaces the `UntypedNode` enum with the more accurately
named `SyntaxNode`. This change is primarily for clarity and better
reflects the role of these nodes as representing the structure of the
source code prior to semantic analysis.

The corresponding enum `UntypedKind` has also been renamed to
`SyntaxKind` to maintain consistency.

No functional changes are introduced by this refactoring; it is purely a
renaming and organizational update.
2026-03-13 14:21:28 +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 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 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 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 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 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 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 b74ddcfd61 Introduce unified Series trait
This commit introduces the `Series` trait to provide a unified interface
for accessing indexed data across different series types (RecordSeries,
SeriesView, and future SharedSeries). This simplifies the VM's indexer
logic and lays the groundwork for the dual series architecture.
2026-03-01 21:24:42 +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 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 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 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 4905b08548 Add 'again' keyword for recursive calls
The `again` keyword is introduced to facilitate explicit recursive
function calls.
It is restricted to tail-call positions to prevent dead code and ensure
TCO
optimization. Type checking is enhanced to validate argument types
against
function parameters.
2026-02-23 20:33:50 +01:00
Michael Schimmel a726b79d8a Refactor Purity enum and NativeFunction struct
Move `Purity` enum definition from `optimizer.rs` to `types.rs` and
create a `NativeFunction` struct to hold the function and its purity.
Update `Value::Function` to store `Rc<NativeFunction>` and
`Value::make_function`
helper to simplify creation.

This change allows tracking the purity of native functions, which is
useful
for optimization and static analysis.
2026-02-22 10:50:37 +01:00
Michael Schimmel df06c51205 Add math and random functions
Register `abs`, `min`, `max`, and `random` functions to the environment.
This also includes adding `PartialOrd` implementation for `Value` to
support comparisons for `min` and `max`.
2026-02-22 08:49:14 +01:00
Michael Schimmel 329b885c4b Formatting 2026-02-22 02:35:06 +01:00
Michael Schimmel f980d9befc Add PartialEq to BoundKind and Value
Implement PartialEq for BoundKind to allow for structural equality
checks during optimization. This enables the optimizer to terminate
early when a node no longer changes.

Also, implement PartialEq for Value to facilitate comparisons between
different Value variants.
2026-02-21 20:01:58 +01:00
Michael Schimmel dc81b7d616 Refactor Tuple and Record to share ValueList
Introduce `ValueList` type alias for `Rc<Vec<Value>>` to reduce
boilerplate and improve readability.
Add `as_slice()` method to `Value` to provide a unified way to access
the underlying values of Tuples and Records.
Update `flatten_value` and `unpack` in `VM` to utilize the new
`as_slice()` method, simplifying logic and improving consistency.
2026-02-21 15:16:04 +01:00
Michael Schimmel 212afd76df Refactor: Rename map to record
This commit renames `Map` to `Record` and updates all related AST nodes,
binders, type checkers, and runtime values to reflect this change. This
is a semantic change to better align with common programming language
terminology.
2026-02-21 14:51:34 +01:00
Michael Schimmel 87259584ee Refactor Record and List to use TupleData
The `Value::List` and `Value::Record` variants have been consolidated
into a single `Value::Tuple` variant. This new variant uses a
`TupleData` struct to store values and an optional `Rc<Vec<Keyword>>`
for keys, allowing it to represent both ordered lists/tuples and
key-value records.

This change simplifies the internal representation and improves
performance by allowing schema sharing for records. It also includes
updates to the compiler, runtime, and tests to reflect the new
structure.
2026-02-20 16:13:38 +01:00
Michael Schimmel ca2c85a8a4 Refactor map and record representation
Replaces the use of `BTreeMap` and `HashMap` for maps and records with
`Vec<(Keyword, Value)>` and `Vec<(Keyword, StaticType)>`. This
simplifies the data structure and allows for ordered iteration, which is
important for serialization and comparison.

Also updates the `unpack` function in `vm.rs` to handle records as well
as lists when destructuring.
2026-02-20 15:10:07 +01:00
Michael Schimmel e2279f214b Refactor lambda binding and parameter handling
Introduce `BoundKind::Parameter` to represent function parameters.
Modify `Binder` to correctly handle parameters within lambda
definitions, ensuring they are only defined within function scopes.
Update `LambdaCollector` to register the body of lambdas as templates
for global definitions.
Adjust `Dumper` to accurately represent lambda parameters.
Update `Specializer` and `TCO` to handle the new `BoundKind::Parameter`.
Refactor `Call` and `TailCall` to use a single `args` node, often a
tuple.
Adjust type signatures in RTL to use `StaticType::Tuple` for function
parameters.
2026-02-20 12:14:22 +01:00
Michael Schimmel 4f849ebd34 Refactor type inference for collections
The type inference for collections (tuples, vectors, matrices, and
records) has been significantly refactored.

This includes:
- Introducing distinct `StaticType` variants for `Tuple`, `Vector`, and
  `Matrix`.
- Implementing more robust type checking for these collections, allowing
  for homogeneous and heterogeneous structures.
- Enhancing the `is_assignable_from` method to handle type compatibility
  between these collection types.
- Updating `Value::static_type()` to correctly infer the types of
  literal collections.
- Improving the type inference for map literals to create `Record`
  types.
- Adding comprehensive unit tests for tuple, vector, matrix, and record
  type inference.
2026-02-20 10:19:29 +01:00
Michael Schimmel a5957f524b Add DateTime type and operations
This commit introduces the `DateTime` type to the language, enabling
users to work with dates and times. It includes:

- A new `DateTime` variant in the `Value` and `StaticType` enums.
- A `date` function for parsing date strings into `DateTime` values.
- Overloads for `+` and `-` operators to support `DateTime` arithmetic.
- Comparison operators (`>`, `<`) for `DateTime` values.
- Corresponding unit tests for `DateTime` operations.
- Updates to the `gemini.md` documentation to reflect the new
  functionality.
  Add DateTime type and operations

Introduce a new `DateTime` type to the language, allowing for date and
time manipulation. This includes:

*   Parsing dates and datetimes from strings.
*   Performing arithmetic operations (addition and subtraction) between
    `DateTime` and `Int` (representing milliseconds) and between two
    `DateTime` values (resulting in an `Int` duration).
*   Enabling comparison operations (`>`, `<`) between `DateTime` values.
2026-02-19 13:27:44 +01:00
Michael Schimmel 49db73800a Refactor type checking for functions and operators
This commit refactors the type checking logic for functions and
operators to improve type safety and expressiveness.

Key changes include:

- Introduced `StaticType::FunctionOverloads` to represent functions with
  multiple possible signatures, enabling better handling of operator
  overloading.
- Updated the `TypeChecker` to correctly infer function types and
  resolve calls with overloaded functions.
- Modified the `Environment` to register standard library functions with
  specific `FunctionOverloads` signatures, replacing the previous
  `StaticType::Any` approach.
- Enhanced the `StaticType::resolve_call` method to intelligently match
  argument types against expected parameters, including handling of
  overloaded functions.
- Added new tests to verify the correctness of type inference for lambda
  returns and operator overloading.
2026-02-19 13:10:28 +01:00
Michael Schimmel b6d1d41c8b Replace lazy_static with OnceLock
This commit replaces the `lazy_static` crate with `std::sync::OnceLock`.
This removes an external dependency and utilizes a standard library
feature for lazy initialization.

Additionally, a benchmark regression test has been added to
`src/ast/tester.rs`.
2026-02-18 16:00:21 +01:00
Michael Schimmel 3630cb3c6c Refactor trace log display and handling
Truncate trace logs to improve GUI performance and prevent excessive
display. This change also introduces line length limits for individual
log entries, adding "..." for truncated lines. The display logic for
trace logs has been updated to use `egui::ScrollArea` for better user
experience.
2026-02-18 13:08:38 +01:00
Michael Schimmel 98deb8f3fe Refactor VM evaluation to use macro
The `eval` and `eval_observed` methods in the `VM` struct were very
similar, with the primary difference being the call to the `VMObserver`
trait. This commit refactors these methods into a single macro,
`dispatch_eval!`, which reduces code duplication and improves
maintainability.

The `Value::TailCallRequest` variant was also updated to use `Box` for
its contents, which helps keep the `Value` enum size consistent.

Finally, the benchmarks in the `examples` directory have been updated to
reflect minor performance changes resulting from these code
modifications.
2026-02-18 02:01:27 +01:00
Michael Schimmel faada16723 Add debug mode and VM tracing
Introduce a `debug_mode` flag to the `Environment` and a new `run_debug`
method. This method uses a `TracingObserver` to log the VM's execution
flow, including node evaluation and scope state changes. This allows for
detailed inspection of script execution.

The `BoundKind` enum now also includes a `display_name` method for
better log readability.
2026-02-18 00:56:29 +01:00