Commit Graph

301 Commits

Author SHA1 Message Date
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
Brummel 007446a167 Update various types to use their own definitions
This commit refactors several modules to use the defined types from
`ast::types` and `ast::nodes` directly, rather than using fully
qualified paths. This improves code readability and reduces redundancy.

Specifically, the following changes were made:

- In `analyzer.rs`, `crate::ast::types::Identity` and
  `crate::ast::types::Purity` are now used directly.
- In `binder.rs`, `crate::ast::types::NodeIdentity`,
  `crate::ast::types::SourceLocation`,
  `crate::ast::types::RecordLayout`, and `crate::ast::types::Value` are
  now used directly.
- In `macros.rs`, types like `Address`, `VirtualId`, `NodeIdentity`,
  `SourceLocation`, `StaticType`, and `Purity` are now used directly.
- In `optimizer/engine.rs`, `Address<VirtualId>` is now used directly.
- In `type_checker.rs`, `BoundPhase`, `Signature`, `Keyword`, and
  `RecordLayout` are now used directly.
- In `environment.rs`, `CompilerScope`, `LocalInfo`, `CapturePass`,
  `AnalyzedPhase`, `NativeFunction`, and `Closure` are now used
  directly.
- In `nodes.rs`, `RecordLayout`, `Keyword`, `Purity`, and `StaticType`
  are now used directly.
- In `parser.rs`, `SourceLocation` and `NodeIdentity` are now used
  directly.
- In `rtl/math.rs`, `NativeFunction`, `Purity`, `Signature`,
  `StaticType`, `Value`, `RefCell`, and `Rc` are now used directly.
- In `rtl/streams.rs`, `ScalarValue`, `SeriesMember`, `Object`,
  `PipeFn`, `Value`, `VM`, `RingBuffer`, `RecordSeries`, `SeriesView`,
  `build_map_stream`, and `build_pipeline_node` are now used directly.
- In `rtl/type_registry.rs`, `RecordLayout`, `Keyword`, `Purity`,
  `Signature`, `StaticType`, and `Value` are now used directly.
- In `vm.rs`, `RecordSeries`, `SeriesView`, `build_map_stream`,
  `build_pipeline_node`, `StreamNode`, `Object`, and `PipeFn` are now
  used directly.
- In `utils/tester.rs`, `TypedNode` is now used directly.
2026-03-22 18:30:56 +01:00
Brummel 1cbc656554 Refactor: Move compiler node definitions to src/ast/nodes
The `bound_nodes.rs` file has been removed and its contents have been
moved to `src/ast/nodes.rs`. This consolidates all AST node definitions
into a single module, improving organization and maintainability.

The `compiler` modules now import these definitions from
`crate::ast::nodes` instead of `crate::ast::compiler::bound_nodes`.
2026-03-22 17:58:49 +01:00
Brummel 49ad76e7c3 Refactor: Remove integration tests and organize into modules
This commit refactors the test suite by removing the monolithic
`integration_test.rs` file.
The tests have been categorized and moved into dedicated modules within
the `tests/` directory:

- `tests/parser.rs`: Contains tests for parsing various literal values.
- `tests/destructuring.rs`: Houses tests related to destructuring
  syntax.
- `tests/closures.rs`: Includes tests for closure behavior and related
  optimizations.
- `tests/optimizer.rs`: Contains tests specifically targeting optimizer
  logic and regressions.
- `tests/records.rs`: Holds tests for record syntax and associated
  optimizations.
- `tests/rtl.rs`: Contains tests for runtime library operators and
  functions.
- `tests/pipeline.rs`: Tests for pipeline functionality.
- `tests/macros.rs`: Tests for macro expansion and related issues.
- `tests/error_recovery.rs`: Includes tests for compiler error handling
  and recovery mechanisms.
- `tests/examples.rs`: Verifies the execution of example scripts.

This reorganization improves test discoverability and maintainability.
The `lib.rs` file has also been updated to reflect these changes by
removing the reference to the old `integration_test` module.
The `type_checker.rs` file has had some tests removed, as they are now
covered by the more specific tests in `tests/error_recovery.rs`.
2026-03-21 15:56:07 +01:00
Brummel bc287d27dd Add destructuring support to dead-def elimination
Introduce `collect_pattern_addrs` to gather all bound addresses from a
destructuring pattern. This enables the optimizer to remove unused
destructuring definitions, similar to how simple unused definitions are
handled. Added integration tests to verify this behavior and other
optimizer robustness scenarios.
2026-03-21 15:35:28 +01:00
Brummel 6264e21f24 Remove unused BoundKind enum
The `BoundKind` enum was declared but never used. This commit removes it
to clean up the codebase.
2026-03-21 14:16:18 +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 99fef2fc86 Refactor AssignBinding and add GetField node
The `AssignBinding` struct now uses `Option<Address<L>>` to
differentiate between simple assignments and destructuring assignments.
For destructuring, the addresses are managed by the `Identifier` nodes
within the target pattern.

A new `GetField` node kind has been introduced to represent optimized
field access, which is generated during the lowering phase for the
`RuntimePhase`. This change aids in more efficient code generation for
accessing fields.
2026-03-21 12:51:39 +01:00
Brummel 63a474030d Add .claudeignore and bytecode architecture documentation
This commit introduces two new files:
- `.claudeignore`: Specifies files and directories that should be
  ignored by Claude, such as snapshot files and the `target` directory.
- `docs/bytecode-architecture.md`: Documents the architecture for
  bytecode generation, outlining the hybrid execution model, the
  transformation pipeline (Specializer and Lowering), and the role of
  Tail Call Optimization (TCO).
2026-03-21 12:43:53 +01:00
Brummel 72244d9da7 Add generic NodeKind enum
This commit introduces a new `NodeKind` enum that serves as a unified
representation for AST nodes across different compilation phases. It
replaces the separate `SyntaxKind` and `BoundKind` enums, allowing
phase-specific information to be attached through generic type
parameters.

This change simplifies the AST structure and makes it easier to manage
node information consistently throughout the compilation process. The
`NodeKind` enum now holds all possible AST node variants, with
phase-specific data encapsulated within `CompilerPhase` trait
implementations.
2026-03-21 12:43:46 +01:00
Brummel e4be31729e Update benchmark results in examples 2026-03-17 17:33:24 +01:00
Brummel 5ca069d93d Add GEMINI.md 2026-03-15 22:40:45 +01:00
Brummel 19feb26247 Rename GEMINI.md 2026-03-15 22:33:13 +01:00
Michael Schimmel 1a7bb5d3e6 Optimize Clone for BoundKind and VM GetField
This commit reduces unnecessary cloning for fields like `addr`, `kind`,
and `field` within `BoundKind` and `VM::GetField`. This improves
performance by avoiding redundant memory allocations.
2026-03-13 19:55:48 +01:00
Michael Schimmel 0dfcfac7b3 Refactor AST substitution logic
This commit refactors the AST substitution logic to correctly handle
nested expansions and improve the inlining of lambda expressions.

The changes include:
- Extracting the core value from potentially expanded AST nodes before
  checking their kind.
- Ensuring that lambda expressions with empty upvalues are correctly
  substituted.
- Adding support for inlining global get expressions as AST
  substitutions.
- Improving the `UsageInfo` collection to correctly track assigned
  values.
2026-03-13 19:51:56 +01:00
Michael Schimmel e5d82ee2b6 Refactor bound node types for clarity
Introduce generic `CompilerPhase` trait to unify different stages of the
bound AST. Rename `LocalSlot` to `VirtualId` and introduce `StackOffset`
for clearer distinction between compile-time and run-time addressing.
Update type aliases and implementations to reflect these changes.
2026-03-13 19:20:44 +01:00
Michael Schimmel d035da9d91 Refactor VM field access to use Rc clones
The VM's field access logic has been refactored to clone `Rc` pointers
for addresses and field identifiers. This change aims to improve
efficiency by avoiding unnecessary dereferencing and copying of values
when accessing fields within records and objects.

Additionally, the `Value::Object` handling in `BoundKind::GetField` has
been refined to more explicitly manage `RecordSeries` and `StreamNode`
types, ensuring that field access is handled polymorphically and
efficiently without copying underlying data structures.
2026-03-13 18:44:43 +01:00
Michael Schimmel b87a6d7ada Refactor closure instantiation and inlining
This commit makes several changes related to how closures are handled:

- **Dumper:** Removes redundant introspection of closure ASTs, as this
  is no longer relevant.
- **Optimizer:** Updates `try_inline` to accept `ExecNode` for
  parameters and adds a check to ensure the `function_node` is a
  `Lambda` before attempting inlining.
- **Environment:** Simplifies closure creation by passing an `ExecNode`
  for parameters and ensuring the correct `stack_size` is used.
- **VM:** Adjusts `Closure` to store an `ExecNode` for parameters and
  updates `VM::unpack` to accept an `ExecNode`.
2026-03-13 18:00:58 +01:00
Michael Schimmel ef5c2367a7 Remove unused collect_parameter_slots
This function was no longer being called and was removed as part of a
refactoring.
2026-03-13 17:13:06 +01:00
Michael Schimmel 222fe64a1f Refactor stack size calculation
Introduces a `StackAllocator` to manage local slot mapping during
lowering. This allows for efficient calculation of stack sizes for
lambdas and the root node. Tail position marking is now handled more
accurately.
2026-03-13 16:50:57 +01:00
Michael Schimmel 8f3e9cbd72 Refactor global slot registration
Replace manual resizing of global arrays with simple pushes. This
simplifies the logic and removes the need for index calculations within
the registration functions.
2026-03-13 16:42:55 +01:00
Michael Schimmel 5a6cae1866 Refactor TypeContext locals to HashMap
Change the `slots` field in `TypeContext` from a `Vec` to a `HashMap`.
This allows for sparse local variable storage and avoids the need to
pre-allocate for all slots, which is more efficient when not all locals
are used.
2026-03-13 16:37:00 +01:00
Michael Schimmel ba36e2157e Configure Gemini for repomix MCP server
Add configuration for the repomix MCP server to the Gemini settings.json
file. This will allow Gemini to use repomix for code analysis and
understanding.
2026-03-13 14:21:39 +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 7d72a99fa1 refactor: separate parser and compiler AST node structures
Simplified the AST architecture by removing the overly complex Node<K,
  T> structure and replacing it with specialized types for
  each phase:

   - Introduced UntypedNode in nodes.rs for the Parser and Macro system,
     eliminating redundant ty: () initializations.
   - Defined a new generic Node<T> in bound_nodes.rs for all compiler
     stages, where T represents the phase-specific metadata.
   - Updated the Binder to act as the bridge between UntypedNode and
     Node<()>.
   - Simplified type aliases: TypedNode, AnalyzedNode, and ExecNode now
     leverage the streamlined Node<T> structure.
   - Updated Parser, Macros, Type-Checker, Optimizer, and VM to reflect
     the architectural changes.
   - Fixed import chains and resolved needless borrows via clippy.

  This change improves type safety, reduces boilerplate code in the
  parser, and makes the compiler stages more idiomatic and
  readable.
2026-03-13 13:16:03 +01:00
Michael Schimmel bf86c76bb6 Refactor: Use root_purity instead of global_purity
This commit refactors the purity analysis from using a
`HashMap<GlobalIdx, Purity>` to a `Vec<Purity>` indexed by
`GlobalIdx.0`.

This change simplifies the data structure and makes purity lookups more
efficient. The `Binder`'s `globals` field has also been removed as it
was not being used.
2026-03-12 16:57:06 +01:00
Michael Schimmel dcb7685d29 Refactor: Pass global names to Binder
The `Binder` struct now accepts a `Rc<RefCell<HashMap<Symbol,
(GlobalIdx, Identity)>>>` for global names. This allows the binder to
directly access and manage global symbols during the binding process,
simplifying the logic and improving efficiency.

Additionally, `CompilerScope` now implements `Default`, and a type alias
`BindingResult` has been introduced for clarity. The `bind_root`
function signature has been updated to accept the `globals` argument.
2026-03-12 16:21:20 +01:00
Michael Schimmel a220815bd6 Refactor Binder initialization and root binding
The `Binder` and `FunctionCompiler` initialization has been refactored
to accept initial scopes and slot counts. This allows for more flexible
management of the compiler's state, particularly for the root scope.

The `bind_root` function now returns the final scopes and slot count of
the root function compiler, enabling the `Environment` to update its
state with these new bindings.

The global variable handling has been integrated into the scope
management, removing the direct reliance on a shared `HashMap` for
globals. This promotes a more consistent approach to symbol resolution.
2026-03-12 14:40:13 +01:00
Michael Schimmel 08b5bba2c4 Add purity to LocalInfo and initialize in binder
The `LocalInfo` struct now includes a `purity` field to track the purity
of local variables and function arguments. This is initialized to
`Purity::Impure` for local variables and arguments within functions and
when registering native functions. Additionally, the `Environment`
struct is updated to include `root_scopes` and `root_slot_count` to
support parallel mode compilation by populating the root scope with
initial function and native function information.
2026-03-12 14:07:27 +01:00
Michael Schimmel 3780674eb1 Refactor binder to use local scopes
Removes global variables and related logic from the Binder, simplifying
its responsibilities to managing local scopes and function compilers.
This change also streamlines the `define_variable` and `resolve_local`
methods within `FunctionCompiler` and removes unused fields from
`FunctionCompiler` and `Binder`.
2026-03-12 13:50:37 +01:00
Michael Schimmel bc13ce7abf Make LocalInfo and CompilerScope fields public 2026-03-12 12:57:04 +01:00
Michael Schimmel be2bef373f Refactor scope handling and immutability
Introduces `fixed_scope_idx` to `Binder` and `Environment` to track
immutable scopes.
This allows enforcing that definitions (`def`) cannot occur in scopes
that are considered fixed or immutable, such as the global scope or the
initial bootstrap scope.
The `FunctionCompiler` is updated to use `fixed_scope_idx` and `is_root`
to determine scope immutability.
2026-03-12 11:22:40 +01:00
Michael Schimmel bb77caf1af Refactor: Rename TCO module to lowering
The TCO (Tail Call Optimization) module has been renamed to `lowering`.
This change better reflects the module's broader responsibility, which
includes not only TCO but also general AST transformations and
preparation for VM execution.

The `optimize` function has been renamed to `lower` to align with the
module's new name.
2026-03-11 10:49:24 +01:00
Michael Schimmel db26719cad Extract calculate_stack_size to a standalone function
The `calculate_stack_size` method was duplicated in `bound_nodes.rs` and
`tco.rs`. This commit extracts it into a single standalone function in
`tco.rs` to avoid duplication. The stack size is now calculated and
stored in the `ExecNode`'s `ty` field during the TCO optimization phase.
2026-03-11 10:35:18 +01:00
Michael Schimmel 3657f19047 Refactor stack management to use resize
Replaces manual iteration for pushing `Value::Void` with `Vec::resize`
for more efficient stack management. This change improves performance by
reducing redundant operations and simplifies the code.
2026-03-10 20:43:46 +01:00
Michael Schimmel efcb4e3685 feat: Add stack size to runtime metadata
Store the pre-calculated stack size of lambda bodies in the
RuntimeMetadata. This allows the VM to directly access this information
without recalculating it.
2026-03-10 20:25:04 +01:00
Michael Schimmel 8c865681ff Refactor: Implement late stack size calculation
This commit introduces a new mechanism for calculating the required
stack size for closures at bind time, rather than storing it in the AST.
This is achieved by adding a `calculate_stack_size` method to
`BoundNode`.

Key changes include:
- `BoundNode::calculate_stack_size`: Recursively traverses the bound AST
  to find the maximum `LocalSlot` index used.
- Recursion blocker for lambdas: Ensures that nested lambdas are not
  visited during stack size calculation for the outer closure,
  preventing incorrect stack size estimations.
- VM update: The `VM::run` method now accepts and uses the
  pre-calculated stack size for setting up call frames.
- `Closure` struct update: Stores the `stack_size` directly within the
  `Closure` struct.
- Binder and TypeChecker updates: Minor adjustments to accommodate the
  new strategy and error reporting.
- Optimizer enhancements: Constant and pure-lambda propagation for
  `Define` statements within blocks to ensure inlinability.

This refactoring addresses issues related to accurate stack size
management and improves the overall robustness of the binder and VM.
2026-03-10 20:05:32 +01:00
Michael Schimmel cb4d3525c2 Refactor binder to simplify root scope logic
The previous implementation of the binder had a slightly complex way of
handling the root scope. This commit simplifies that logic by directly
checking if the current scope is the root scope and the scope stack has
only one element. This makes the code more readable and maintainable.
2026-03-10 17:25:27 +01:00
Michael Schimmel a78e72d074 Refactor Binder to use new scope structure
This commit refactors the Binder implementation to better align with the
updated scope structure.
Key changes include:

- Introducing `ExprContext` to distinguish between statement and
  expression contexts.
- Modifying `define_variable` to handle both global and local scope
  definitions more robustly.
- Updating `resolve_variable` to correctly handle upvalue captures,
  especially for global addresses.
- Adjusting `bind` and related functions to use the new `ExprContext`.
- Updating the refactoring log to reflect completed phases.
2026-03-10 17:20:47 +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 8339ee413e Doc: Use exhaustive matching in LambdaCollector 2026-03-09 11:49:17 +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 cb4507b2da Refactor AST-Tool evaluation logic
Consolidate AST source code evaluation logic to handle script strings,
file paths, and stdin more uniformly. Introduce a `read_stdin` helper
function.
2026-03-09 10:36:07 +01:00
Michael Schimmel 66171b0802 Fix: Implement ~ and ~@ syntax to prevent parser deadlock
Adds parsing for the `~` (placeholder) and `~@` (splice) syntax.

- `~expr` parses as a placeholder node.
- `~@expr` parses as a splice node.
2026-03-08 13:45:14 +01:00
Michael Schimmel 6f2d9b0e47 Create system.myc 2026-03-08 13:10:00 +01:00