# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.2.0] - 2026-05-13

### ⚠️ BREAKING CHANGES

- **ParseResult structure changed**: Added explicit error position field
  - Old: `ParseResult(cost: u32, position: usize, result: Arc<Result<...>>)`
  - New: `ParseResult(cost: u32, position: usize, error_pos: usize, result: Arc<Result<...>>)`
  - **Migration**: Change `result.2` to `result.3` to access the parse result
  - The new field at index 2 provides the furthest error position for better diagnostics

### Added

- **Semantic actions support**: New `semantic` module with `parse_with_semantics`, `ReducerTable`, and `SemanticNode`
  - Build typed ASTs from parse trees with bottom-up reducers
  - See module documentation for usage examples
- **Enhanced error reporting**: Track furthest error position during parsing (Pappy `joinErrors` behavior)
  - `FURTHEST_POS` and `FURTHEST_ERROR_POS` thread-local tracking
  - `ERROR_CUTOFF_POS` for limiting error reporting range
- **Embedded Lojban grammar**: `LOJBAN_GRAMMAR` constant with full camxes-style Lojban PEG
- **Better logging**: Uses `log` crate for internal diagnostics (configure with `RUST_LOG`)

### Changed

- Improved error position tracking throughout the parser
- Better memoization with explicit `MemoMap` parameter in `parse_with_memo`
- Updated dependencies to latest versions

### Fixed

- More accurate error positions in parse failures
- Better handling of `%%%END%%%` marker in Lojban parsing

## [0.1.5] - Previous release

See git history for changes in 0.1.x series.

---

## Migration Guide: 0.1.x → 0.2.0

### Update ParseResult access

```rust
// Before (0.1.x)
let ParseResult(cost, pos, result) = parser.parse(input);
match result.as_ref() {
    Ok(nodes) => { /* ... */ }
    Err(err) => { /* ... */ }
}

// After (0.2.0)
let ParseResult(cost, pos, error_pos, result) = parser.parse(input);
match result.as_ref() {
    Ok(nodes) => { /* ... */ }
    Err(err) => { 
        // error_pos now available for better error reporting
        println!("Parse failed at position {}", error_pos);
    }
}
```

### Update tuple destructuring

```rust
// Before
let result = parser.parse(input);
if result.2.is_ok() { /* ... */ }

// After
let result = parser.parse(input);
if result.3.is_ok() { /* ... */ }
```

### Benefits of upgrading

- **Better error messages**: The new error position field tracks the furthest point the parser reached
- **Semantic actions**: Build typed ASTs with the new semantic module
- **Embedded grammars**: Use `LOJBAN_GRAMMAR` for Lojban parsing without external files
- **Improved logging**: Better diagnostics with the `log` crate

[0.2.0]: https://github.com/lojban/tersmu/compare/v0.1.5...v0.2.0
[0.1.5]: https://github.com/lojban/tersmu/releases/tag/v0.1.5
