Releases: riddler/predicator-ex
Releases · riddler/predicator-ex
v3.5.0
[3.5.0] - 2025-09-09
Added
Adds milliseconds support to duration system
- New 'ms' unit support in lexer, parser, and evaluator
- Duration.to_milliseconds/1 function for high-precision calculations
- Pattern matching guards for automatic precision selection
- Smart DateTime arithmetic (millisecond vs second precision)
- Comprehensive test coverage with 89 new tests
- Refactors evaluator to use Duration module functions (DRY)
Examples
- 500ms ago, 2s750ms from now
- #2024-01-15T10:30:00.000Z# + 1s500ms
- Automatic precision: ms > 0 triggers millisecond precision
v3.4.0
[3.4.0] - 2025-09-09
Added
Durations and relative date/time arithmetic
- New duration literals and relative date expressions (e.g.,
3d ago,2w from now,next 1mo,last 1y) - Date and DateTime arithmetic using durations (e.g.,
#2024-01-10# + 5d,#2024-01-15T10:30:00Z# - 2h) - Grammar additions:
durationandrelative_dateproductions - Full pipeline support (lexer, parser, compiler, evaluator, string visitor) with tests
Examples
Predicator.evaluate("created_at > 3d ago", %{"created_at" => ~U[2024-01-20 00:00:00Z]})
Predicator.evaluate("due_at < 2w from now", %{"due_at" => Date.add(Date.utc_today(), 10)})
Predicator.evaluate("#2024-01-10# + 5d = #2024-01-15#", %{})
Predicator.evaluate("#2024-01-15T10:30:00Z# - 2h < #2024-01-15T10:30:00Z#", %{})Documentation
- Updated EBNF grammar in docs
- Added AGENTS.md with model-agnostic agent guidance;
CLAUDE.mdnow references the same content
v3.3.0
v3.2.0
[3.2.0] - 2025-08-31
Added
Strict Equality Operators
- New Operators: Added
===(strict equality) and!==(strict inequality) operators - Type-Safe Comparisons: Strict operators compare both value and type, unlike loose equality
- Round-Trip Preservation: Operators maintain their exact form during parse/decompile cycles
- Complete Pipeline Support: Full lexer, parser, evaluator, and visitor implementation
- Comprehensive Testing: 23 tests covering all aspects of strict equality functionality
Examples
# Strict equality - same type and value required
Predicator.evaluate("5 === 5", %{}) # {:ok, true}
Predicator.evaluate("5 === '5'", %{}) # {:ok, false} - different types
# Strict inequality - true when type or value differs
Predicator.evaluate("5 !== '5'", %{}) # {:ok, true} - different types
Predicator.evaluate("1 !== true", %{}) # {:ok, true} - different types
# Operator distinction preserved
Predicator.parse("x = y") |> elem(1) |> Predicator.decompile() # "x = y"
Predicator.parse("x == y") |> elem(1) |> Predicator.decompile() # "x == y"
Predicator.parse("x === y") |> elem(1) |> Predicator.decompile() # "x === y"Technical Implementation
- Lexer: Added
:strict_equaland:strict_netoken types with proper precedence - Parser: Extended comparison grammar to support strict operators
- Evaluator: Added
STRICT_EQandSTRICT_NEinstruction handlers - StringVisitor: Added decompilation support for round-trip accuracy
- Type Safety: Works with all data types including
:undefinedvalues
v3.1.0
[3.1.0] - 2025-08-30
Added
JavaScript-Style Object Literals (Complete Implementation)
- Object Literal Syntax: Full support for JavaScript-style object notation with
{key: value}syntax - Multiple Key Types: Both identifier keys (
name: "John") and string keys ("first name": "John") - Nested Objects: Unlimited nesting depth for complex data structures
- All Value Types: Objects support all Predicator value types (strings, numbers, booleans, dates, lists, expressions)
- Object Comparisons: Full equality and inequality operations between objects
- Integration: Seamless compatibility with all existing features (functions, operators, property access)
Object Literal Examples
# Basic object creation
Predicator.evaluate("{}", %{}) # {:ok, %{}}
Predicator.evaluate("{name: \"John\", age: 30}", %{}) # {:ok, %{"name" => "John", "age" => 30}}
# Variable references and expressions
Predicator.evaluate("{user: name, total: price + tax}", %{"name" => "Alice", "price" => 100, "tax" => 10})
# {:ok, %{"user" => "Alice", "total" => 110}}
# Nested objects
Predicator.evaluate("{user: {name: \"Bob\", role: \"admin\"}, active: true}", %{})
# {:ok, %{"user" => %{"name" => "Bob", "role" => "admin"}, "active" => true}}
# String keys for complex property names
Predicator.evaluate("{\"first name\": \"John\", \"last-name\": \"Doe\"}", %{})
# {:ok, %{"first name" => "John", "last-name" => "Doe"}}
# Object comparisons
Predicator.evaluate("{score: 85} == user_data", %{"user_data" => %{"score" => 85}})
# {:ok, true}Complete Pipeline Support
- Lexer: Added
{,},:token recognition - Parser: Full object grammar with proper precedence and error handling
- Instructions: Stack-based
object_newandobject_setinstruction execution - Evaluator: Efficient object construction and comparison operations
- String Visitor: Bidirectional transformation support (AST ↔ string representation)
- Type System: Enhanced type matching for object equality comparisons
Integration Features
- Function Integration: Objects work as function parameters and return values
- Property Access: Objects integrate with dot notation (
obj.property) and bracket access (obj["key"]) - Boolean Logic: Objects support all logical operations (AND, OR, NOT)
- Arithmetic: Object properties can contain arithmetic expressions and results
- Date Support: Objects can contain date/datetime literals and date function results
- Custom Functions: Objects work seamlessly with user-defined functions
Quality and Testing
- 886 Total Tests: Comprehensive test coverage including edge cases and integration scenarios
- 91.8% Coverage: High test coverage across all components
- Parser Error Handling: Robust error recovery for malformed object syntax
- Performance Tested: Validated with large objects and repeated evaluations
- Production Ready: Full quality assurance (formatting, linting, type checking)