Commit Graph

22 Commits

Author SHA1 Message Date
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
Michael Schimmel eeb6621280 Formatting 2026-02-24 07:27:13 +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 2e8d5284c2 Feat: Enable nested destructuring optimization
This commit introduces optimizations for nested destructuring, allowing
tuples and records to be flattened and matched directly against function
arguments. This significantly improves performance by enabling more
constant folding and reducing intermediate allocations.

The changes include:
- Modifying the `Binder` to correctly count nested parameters.
- Enhancing `flatten_tuple` in the `Optimizer` to handle records and NOP
  nodes.
- Updating `map_params_to_args` to recursively destructure nested
  compound arguments.
- Adding integration tests to verify the correctness of tuple-to-tuple
  and record-to-tuple destructuring optimizations.
2026-02-22 16:34:40 +01:00
Michael Schimmel cb94f20c0b Refactor native function registration and instantiation
Introduces `register_native` for direct registration of `NativeFunction`
and `register_native_fn` for convenience from closures. The
`Environment::run`
method is removed, and its functionality is now handled by
`Environment::instantiate`,
which packages the linked AST into an invokable `NativeFunction`. This
streamlines
the execution path and better separates compilation/linking from runtime
execution.
2026-02-22 11:56:46 +01:00
Michael Schimmel 6605f56756 feat: Add fastrand for PRNG support
Replaces the custom LCG implementation with `fastrand` for improved
random number generation.
This commit introduces the `fastrand` crate to the project for robust
and efficient pseudo-random number generation.
The `Environment` struct now includes a `prng` field to hold the random
number generator.
The built-in `random` function now utilizes this PRNG for generating
floating-point random numbers.
A new `seed!` function is added to allow users to seed the PRNG for
deterministic random sequences.
This change enhances the randomness capabilities of the language, making
it suitable for simulations and other applications requiring good
quality random numbers.
2026-02-22 09:08:16 +01:00
Michael Schimmel 589c13896f Add now() built-in function
This commit introduces the `now()` built-in function, which returns the
current timestamp in milliseconds. It also includes an integration test
to ensure that `now()` is not constant-folded during AST dumping,
verifying its non-deterministic nature.
2026-02-22 08:44:49 +01:00
Michael Schimmel 7c997ca841 Refactor: Replace optimization level with boolean flag
The optimizer now uses a simple boolean flag (`optimization`) instead of
an `optimization_level` (u32). This simplifies the optimizer's logic and
makes it easier to enable or disable optimizations.

The command-line interface and internal testing have been updated to
reflect this change.
2026-02-22 01:50:14 +01:00
Michael Schimmel 0ed52a811d Update benchmark metadata
This commit updates the benchmark metadata in several example files. The
benchmark runs and repeat counts have been slightly adjusted due to
optimizations or minor variations in execution.
2026-02-22 01:37:00 +01:00
Michael Schimmel 56b8e8389b Refactor optimizer with aggressive collapsing
The optimizer has been refactored to separate its phases and introduce
more aggressive collapsing capabilities.

Phase 2 (Cracking) now focuses on stateless transformations, making it
easier to reason about and potentially parallelize.

Phase 2.5 (Aggressive Collapsing) has been introduced, enabling
optimizations like:
- Beta-reduction for lambda literals.
- Cracking and inlining for constant closures.
- Folding intrinsics for constant arithmetic.
- Short-circuiting conditional expressions.

These changes aim to improve performance by reducing redundant
computations and code bloat. The maximum number of optimization passes
has also been increased to 5 to allow for more complex transformations.
2026-02-21 19:42:09 +01:00
Michael Schimmel 26f0ed9531 Refactor example tests into dedicated function
Extracts the logic for running example tests into a new function
`run_functional_tests` in `src/utils/tester.rs`. This function is then
called from `src/integration_test.rs` to simplify the test setup and
improve code organization. The changes also adjust the benchmark
thresholds slightly.
2026-02-21 15:01:36 +01:00
Michael Schimmel 4e812c1afb Add positional_count field to Lambda
This field is used for static optimization, determining if parameters
are purely positional.
2026-02-20 14:40:56 +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 1331aabbe1 Update benchmarks and adjust tests
This commit updates benchmark values in several example files to reflect
minor performance variations. It also includes adjustments to
integration
and unit tests to align with recent changes in the type checking and VM
logic, specifically concerning closures and TCO handling.
2026-02-19 23:54:53 +01:00
Michael Schimmel 07bf59eb47 Add RTL functions for arithmetic and comparisons
This commit introduces a new module `ast::rtl` to house the standard
runtime library functions for the language. It includes implementations
for arithmetic operators (+, -, *, /, //, %), logical operators (and,
or, xor, not), bitwise shifts (<<, >>), and comparison operators (=, <>,
<, >, <=, >=).

Additionally, a `date` function for parsing datetime strings has been
added. This enhances the language's capability to handle basic
mathematical and logical operations.
Add RTL functions for arithmetic and comparisons

This commit introduces the runtime library (RTL) functions for basic
arithmetic operations, logical/bitwise operations, and comparisons. It
also includes a `date` function for parsing datetime strings.
Integration tests have been updated to cover these new functionalities.
2026-02-19 13:47:14 +01:00
Michael Schimmel d93727e198 feat: Add type checking to the compiler
Introduces the `TypeChecker` struct and its associated `TypeContext` for
performing static type analysis on the abstract syntax tree.

This change includes:
- A new `type_checker.rs` module.
- Integration of `TypeChecker` into the `Environment::compile` method.
- Updates to `Environment` to manage global types.
- Renaming `bound_nodes.rs`'s `BoundNode` to `TypedNode` to reflect its
  type-checked nature.
- Refinements in binder and macro expansion to accommodate type
  information.
2026-02-19 12:22:39 +01:00
Michael Schimmel 4673ea78b9 Refactor Binder to use simpler types
The Binder has been refactored to simplify its internal types and reduce
redundancy.
Key changes include:
- Removed StaticType from LocalInfo, as it's not strictly needed for the
  binder.
- Simplified `define` in CompilerScope to not take a StaticType.
- Removed StaticType from upvalues in FunctionCompiler.
- Adjusted global mappings to store only the index, not the type.
- Updated BoundKind to use a generic type parameter `T` for metadata,
  defaulting to `()` for untyped bound nodes.
- Introduced `BoundNode` and `TypedNode` type aliases for clarity.
- Minor adjustments to dumper and VM to accommodate the new generic
  BoundKind.
2026-02-19 12:07:28 +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
Michael Schimmel b0f139f389 feat: Add testing and benchmarking capabilities
This commit introduces a new `tester` module to the `ast` crate,
enabling functional tests and performance benchmarks for MYC scripts.

Functional tests are executed by reading `.myc` files from the
`examples` directory, parsing expected output comments, and comparing
them against the actual script execution results.

Benchmarking involves measuring the execution time of scripts,
calculating median durations, and comparing them against stored
baselines. The commit also adds support for updating these baselines.

The `ast.rs` CLI and the `main.rs` GUI application have been updated to
expose these new testing and benchmarking features. The `Cargo.toml` and
`Cargo.lock` files have been updated to include the `regex` dependency
required for parsing benchmark comments.
2026-02-17 14:47:04 +01:00
Michael Schimmel b1ca16149d Add chrono dependency and example files
This commit introduces the `chrono` dependency to the project, enabling
the use of time-related functionalities. Additionally, it adds several
example files (`closure.myc`, `fib.myc`, `hof.myc`) to showcase the
language's features like closures, recursion, and higher-order
functions.

The `Cargo.lock` and `Cargo.toml` files have been updated to reflect the
new dependency. The `integration_test.rs` file now includes a test to
run all `.myc` files found in the `examples` directory, ensuring their
correctness. The `main.rs` file has also been updated to load and
display these examples in the UI.
2026-02-17 14:21:31 +01:00
Michael Schimmel d55422272b Refactor: Use Rc/RefCell for shared mutable state
This commit replaces `Arc<Mutex<T>>` with `Rc<RefCell<T>>` for managing
shared mutable state within the AST and VM. This change is primarily an
internal refactoring to leverage Rust's standard library more
effectively for single-threaded scenarios, improving performance by
avoiding the overhead of mutexes.

The following types and their usage have been updated:
- `Environment.global_names` and `Environment.global_values`
- `Binder.globals`
- `bound_nodes::BoundKind::Lambda.body` (now `Rc<Node>`)
- `ast::types::NodeIdentity` (now `Rc<NodeIdentity>`)
- `ast::types::Value::List`, `Value::Record`, `Value::Function`,
  `Value::Object`, `Value::Cell`
- `ast::nodes::Scope` and `ast::nodes::Context`
- `ast::vm::Closure.function_node` and `Closure.upvalues`
- `ast::vm::VM.globals`

This change does not alter the external behavior of the library but
streamlines internal data management.
2026-02-17 13:00:25 +01:00
Michael Schimmel ce166f39e3 Introduce Value::Cell for mutable upvalues, allowing closures to
modify captured variables.
Implement `capture_upvalue` and `get_value`/`set_value` methods in the
`VM` to handle these mutable upvalues.

Refactor number parsing to support integers and floats

Separate the `TokenKind::Number` into `TokenKind::Integer` and
`TokenKind::Float`.
Update the lexer to distinguish between integer and float literals.
Update the parser to correctly map these new token kinds to their
respective `Value` types.

Add integration tests for parsing integers and floats, and for closure
modification of captured variables.
2026-02-17 12:35:39 +01:00