Skip to content
AxolotlBucketLabsPublic
forked from Muqsit/arithmexp

About

GPL-3.0 fork of Muqsit arithmexp with DevTools-compatible diagnostics for Axolotl-PM virions

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

 
 

Repository files navigation

arithmexp

GPL-3.0 fork of Muqsit arithmexp with DevTools-compatible diagnostics for Axolotl-PM virions

CI Latest release License Discord

Compatibility

  • The virion manifest supports API 4.21.1 and API 5.0.0.
  • Composer requires PHP 8.1 or newer.
  • The CI workflow runs PHPUnit and PHPStan at level max. The DevTools workflow builds a virion PHAR with PHP 8.4.

Fork 1.1.1 compatibility note

The fork's pending source revision removes unsafe rewrites of 0 / x, x / x, x ** y / x ** z, zero multiplied by an expression, exponentiation with variable operands, % 1 with a variable left operand, subtraction of identical variable expressions, reordering a negative left operand in addition, multiplication by one, addition with zero, subtraction by zero, division by one, unary plus, and NaN combined with a variable expression. These expressions now retain operand evaluation order or arithmetic conversion. A zero denominator raises DivisionByZeroError at evaluation time, as it does with the unoptimized parser. Several changes also preserve non-finite results or arithmetic result types in their affected cases. Earlier fork source could fold these expressions to a value and hide an error or change the result.

The default parser no longer registers ReorderExpressionOptimizer. A commutative operator does not guarantee that regrouping floating-point operands preserves the result. For example, x + y + z with x = 1e16, y = -1e16 and z = 1 now evaluates to 1 in both default and unoptimized parsers. The optimizer class remains available for explicit registration, but callers that opt in must validate its effects for their expressions. Division strength reduction also no longer cancels numeric factors across separate products, because that can change overflow and rounding. Other algebraic rewrites still need an error-preservation audit, so this release does not establish full equivalence between optimized and unoptimized evaluation.

Subtraction with a negative left operand now keeps its original grouping. Rewriting (-1) - x as a negated sum promoted the result from an integer to a float when x was PHP_INT_MAX.

Addition and subtraction with a negative right operand also keep their original operators. Rewriting x + (-y) as x - y, or x - (-y) as x + y, changed the result type and value when y was PHP_INT_MIN.

Nested min() and max() calls also retain their argument order and grouping. Flattening them changed results when an argument was NaN, because PHP's comparison behavior for NaN depends on evaluation order.

sqrt() now calls PHP's square-root function directly. Rewriting it as exponentiation changed the sign of negative zero.

The pending parser changes reject empty parentheses used as operands and argument separators consumed as operator operands with a ParseException. These malformed expressions previously could hang or expose an internal RuntimeException. Zero-argument calls such as pi() remain valid.

Tip

Try out arithmexp parser on the demo site!

Installation

The Composer package name remains muqsit/arithmexp, so composer require muqsit/arithmexp resolves the upstream package rather than this fork. Use this repository as a local virion source when you need the AxolotlBucketLabs maintenance branch.

Place the checkout in virions/arithmexp/ and declare it in the consuming plugin's devtools.yml:

virions:
  - name: arithmexp
    version: ^1.1.1

See CHANGELOG.md for the tested consumer, behavior changes and rollback steps.

Evaluating a mathematical expression

To evaluate a mathematical expression, create a Parser and invoke Parser::parse() with an expression string to obtain a reusable Expression object. Expression::evaluate() returns the value of the expression.

$parser = Parser::createDefault();
$expression = $parser->parse("2 + 3");
var_dump($expression->evaluate()); // int(5)

$expression = $parser->parse("mt_rand()");
var_dump($expression->evaluate()); // int(1370501507)
var_dump($expression->evaluate()); // int(1522981420)

Variables may be substituted at evaluation-time by passing an array<string, int|float|bool> value to Expression::evaluate().

$expression = $parser->parse("x + y");
var_dump($expression->evaluate(["x" => 2, "y" => 3])); // int(5)
var_dump($expression->evaluate(["x" => 1.5, "y" => 1.5])); // float(3)

$expression = $parser->parse("a > b or c");
var_dump($expression->evaluate(["a" => 1, "b" => 2, "c" => true])); // bool(true)

The return value type of the evaluation follows PHP's arithmetic rules. int + int returns an int value, while float + int|float returns a float value. bool + bool returns an int value, while int || int returns a bool value.

Note

See CHANGELOG.md for fork-specific behavior changes and compatibility notes.

About

GPL-3.0 fork of Muqsit arithmexp with DevTools-compatible diagnostics for Axolotl-PM virions

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages