# ecma-syntax-cat
ECMAScript abstract syntax tree as comp-cat-rs-idiomatic Rust types. ESTree-shaped, ES2024-complete, no panics, no `Rc`/`Arc`/`RefCell`, no interior mutability, no `unsafe`.
This is the foundation crate of a multi-crate comp-cat-rs reformulation of a JavaScript engine targeting Tauri integration. Five preceding falsification spikes ([lambda-cat](https://crates.io/crates/lambda-cat), [lambda-ref-cat](https://crates.io/crates/lambda-ref-cat), [lambda-obj-cat](https://crates.io/crates/lambda-obj-cat), [lambda-throw-cat](https://crates.io/crates/lambda-throw-cat), [lambda-async-cat](https://crates.io/crates/lambda-async-cat)) confirmed the idioms scale to every JS-distinctive runtime concern; this crate is the construction-phase artifact that defines the AST contract downstream crates build against.
## Shape
- Every AST node carries source-span information via [`Spanned<T>`].
- Recursive positions use `Box<T>` for indirection; collections use `Vec<T>`.
- Variants follow ESTree naming, shortened to their core noun when used as enum variants.
- Operators are factored into separate enums (`BinaryOperator`, `LogicalOperator`, `UnaryOperator`, `UpdateOperator`, `AssignmentOperator`) rather than expanded into the expression variants.
## Coverage
ES2024 surface: literals (number, string, boolean, null, BigInt, regex, template), identifiers, all expression and statement forms, classes (including private fields, static blocks, getters/setters), modules (import/export), async/await, generators, destructuring, optional chaining, nullish coalescing, dynamic import, meta-property.
Excluded: TypeScript syntax, JSX, stage-3 proposals (decorators, pipeline operator) that have not yet finalized.
## Usage
```rust
# fn main() -> Result<(), ecma_syntax_cat::error::Error> {
use ecma_syntax_cat::expression::{Expression, ExpressionKind};
use ecma_syntax_cat::identifier::Identifier;
use ecma_syntax_cat::literal::Literal;
use ecma_syntax_cat::operator::BinaryOperator;
use ecma_syntax_cat::span::Span;
let span = Span::synthetic();
let x = Expression::new(
ExpressionKind::Identifier(Identifier::new("x")?),
span,
);
let one = Expression::new(
ExpressionKind::Literal(Literal::number(1.0)),
span,
);
let plus = Expression::new(
ExpressionKind::Binary {
operator: BinaryOperator::Add,
left: Box::new(x),
right: Box::new(one),
},
span,
);
println!("{plus}");
# Ok(())
# }
```
## Building
```sh
cargo build
cargo test
RUSTFLAGS="-D warnings" cargo clippy --all-targets
```
## License
Licensed under either of [Apache License, Version 2.0](LICENSE-APACHE) or [MIT license](LICENSE-MIT) at your option.
[`Spanned<T>`]: https://docs.rs/ecma-syntax-cat/latest/ecma_syntax_cat/span/struct.Spanned.html