arithmexp

A powerful mathematical expression parser and evaluator for PHP featuring variable substitution, user-defined constants, functions, deterministic functions, macros, operators, and compiler optimizations.

GPL-3.0 License

Downloads
56
Stars
24
Committers
4

Bot releases are visible (Hide)

arithmexp - v1.0.1

Published by Muqsit 3 months ago

  • Fix spaceship operator (<=>) cannot be stringified (73fe866fa26cf8605073d56363e2ec0074d9769d)
arithmexp - v1.0.0

Published by Muqsit 3 months ago

arithmexp - v0.1.30 Latest Release

Published by Muqsit over 1 year ago

  • Minimum supported PHP version is now 8.1 (06d1e867d659ceb890f27f5cd73ffe3654f44b5c, 4d21517d266c1fec45caa1150c5fb2c9f35f054e, 143bc8337210b42860fd08adbb5a3b3c0409e9d9, c76216cca53ea2e31e134d10cdbae98d58deb75e, 04eabbf2fe9e7c8854516c5cb74b2e979bff85ab, 7b2e105b15b470328100c1b732aeb9b3cd1269cd, 2ffe7da852ffbe0e67d45d008821bc53fc5a03cb, a1b8dda610862e5531495727c69d50e6201f8d06, 48d80dcb74708f7eb1e51f9597b3851037f623ad)
  • arithmexp now supports virion v3 spec (1255bc581ec2db34f86710c00b96697c4806ecc8)
  • arithmexp now supports PocketMine-MP v5.0.0 (1255bc581ec2db34f86710c00b96697c4806ecc8, https://github.com/Muqsit/arithmexp/commit/62c7d51e00c8f4e725e6fa2a574f303ab31419e0#commitcomment-116175135)
arithmexp - v0.1.29

Published by Muqsit almost 2 years ago

  • Fixed unary positive operation resulting in negation since v0.1.28 (80ceccfd92c6575b419297874cf6d0606b1406a7)
  • Further optimized expression evaluation (6d0c7998d2003eec6d3b540b80630ce44ac8ae1b)
  • Implemented modulo operator strength reduction for identity property ((a % n) % n => a % n) (bca7b1719618c4fd316cb5bc380069ea4616a747, 98535479ae9a4b6e74dbe448d33ab74bf77b8657)
  • Removed functions rand() and getrandmax() (these functions exist in PHP only for backward compatibility) (ce8dfb3dc46e2cc7ee30a13febb7e802994301d9)
  • mt_rand() now accepts zero parameters (in addition to accepting two parameters) (8194bf3c279e4699df95457996dc482e6bc9a9bd, f73be6140e42007a4ed9fe7d423dfc113ebab758)
  • Implemented mode constants for round() (HALF_UP, HALF_DOWN, HALF_EVEN, HALF_ODD) (c21ce74f35dde4b3af8fe383cf9d48fa68198882, 90c0f5df57f4c53ccd39514898541d1926ece790)
  • Renamed FunctionRegistry::register() to FunctionRegistry::registerFunction() (ad076413b326ded9bd3a5f43ff83544d941aa9f5)
  • Renamed ConstantRegistry::register() to ConstantRegistry::registerLabel() (1b0d2d575c0a636476eb85ccbce7fd029e6b289a)
  • Moved FunctionRegistry::registerMacro() to MacroRegistry::registerFunction() (0d0889fdcaefb5d1e443c8aee1b492dcaa087f75)
  • Implemented object-like macros that can be registered by calling MacroRegistry::registerObject() (34e5ad71836b74a686130acfd2a720abcce01679)
arithmexp - v0.1.28

Published by Muqsit almost 2 years ago

  • Improved performance of evaluating operator tokens (de91e05748623ed2923ab2c3a5b70a1dc4054d4d, 998ec6a8ac09e7104fcb76436f602d1facda7817, 5b40d3cfe95e8967b72910bdf43021c0bcacb720, 4acfe1d2160fe172d448b260d6397ca0ff08c5cf, 3a7790930cb1ed904fa78344d73efae5e061130a)
arithmexp - v0.1.27

Published by Muqsit almost 2 years ago

  • Implemented function-like macros (see the wiki) (b1fc5c3d706653d949b977ae9c812790bd528449)
arithmexp - v0.1.26

Published by Muqsit almost 2 years ago

  • Introduced Parser::getOperatorManager() (4ff725f3b958a2372668729195193438880b73e1)
    • Replaced Parser::getBinaryOperatorRegistry() with Parser::getOperatorManager()->getBinaryRegistry()
    • Replaced Parser::getUnaryOperatorRegistry() with Parser::getOperatorManager()->getUnaryRegistry()
  • Fixed a few cases where optimizers did not account for INF and NAN (#16) (1ef49eb44e1a0723e42a771cc680f2afc15396f6, db1df91b986e023dfdba1bf002da0b2410ddaefa, 03440abd8d9cede1a22ce6cf90991a293934a6ed, b9dd31e9bb23faace4203493b85f6dc7c5f9aaca, 3c9b8a081c947c136204a18685f27cf58e6d9fe7, 14442caf91dcfe540c595ac3be06af554d7b2c77, 082ccf3bfde0aff653fb0819bf3b9728a309d538)
  • Fixed operator precedence of unary operators being greater than exponentiation (#17) (4ff725f3b958a2372668729195193438880b73e1)
  • Fixed division by zero with zero 0 / 0 returning int(0) with optimizations (167297038be3529e90d554abe6027fbbf6be18ef)
  • Function properties (commutativity and determinism) are governed by function flags instead of boolean properties (3e348456d66092051cc8066ccd7028b9baaaf579)
    • See newer examples on the wiki on registering custom binary operators, unary operators, and functions
  • Implemented idempotent functions (bd0860973098224497d2dc731f8eeef3f8f6f4a2)
arithmexp - v0.1.25

Published by Muqsit almost 2 years ago

  • Fixed a bug that allowed using square brackets and curly brackets to enclose function call argument list (aa716293eaafdf20eec9577cba441265dc6aea1c)
  • Errored subexpressions are no longer highlighted if the subexpression is the expression itself (65290a666f2e3a9e9a7c6f533faf1e81aa60684d)
  • Improved performance of operator strength reduction by precomputing numeric literals within operands (32cf8f42b1dd3bf56b1107062bf776f2e87b0b22)
arithmexp - v0.1.24

Published by Muqsit about 2 years ago

  • Added support for various forms of brackets (square brackets [] and curly brackets {} are now considered as valid in expressions) (#13, thanks @NhanAZ!)
arithmexp - v0.1.23

Published by Muqsit about 2 years ago

  • Registered functions for a parser can now be accessed via FunctionRegistry::register() (d003841c373b003f3fa2c2e15f25dad23e321460)
  • Improved operator strength reduction performance over addition with negative operands (2bf277e4799a8e09b677449d9be2f02345647bda, ff81320defe4e49a15b2913425aae07f4d9a185c)
  • Improved operator strength reduction performance over subtraction with negative operands (da2168549de8bde9741f5093e7616a5e6f021a6b, ff81320defe4e49a15b2913425aae07f4d9a185c)
  • Fixed a critical bug where operator strength reduction over subtraction with lvalue=0 resulted in rvalue instead of -rvalue (#11, 4f4aaea17a350385b2637fed9d5eaf645f2de745, 029e47001543ab3928ad19662d2b0de90fcb03a4) (thanks @sylvrs!)
arithmexp - v0.1.22

Published by Muqsit about 2 years ago

  • Implemented quotient rule of exponents (a ** m / a ** n = a ** (m - n)`) in strength reduction optimization (757e7b05ea6cf2e4fa5517f293db92a32f485cdc)
  • Fixed a bug in the optimizer that caused function calls in expressions to be optimized by name (889145820f06279865e97d1041473e2c1ca7e49c)
  • Fixed a bug in the optimizer that failed to parse expressions containing nested function calls with zero parameters (such as min(pi())) (4d334144960ca02c92aaa0c82ce8a04c774f93e6)
arithmexp - v0.1.21

Published by Muqsit about 2 years ago

  • Expression::getVariables() has been renamed to Expression::findVariables()
  • Fixed a bug where exponentiation of 2 with itself resulted expression executing indefinitely
arithmexp - v0.1.20

Published by Muqsit about 2 years ago

  • Fixed a bug causing operator strength reduction to not work on function calls with >2 arguments
  • Use of same unary operator consecutively is now valid (#10, thanks @NhanAZ!)
  • Operator strength reduction now optimizes unary positive and unary negative operations
arithmexp - v0.1.19

Published by Muqsit about 2 years ago

  • Improved strength reduction over division operations
  • Added a "commutative" property to functions
  • min and max no longer throw an error when only 1 parameter is supplied
  • Parser now attempts to catch division-by-zero during parsing
arithmexp - v0.1.18

Published by Muqsit about 2 years ago

  • Fixed a bug causing non-deterministic function calls from being optimized away during parsing
  • Argument underflow in function calls now throws a ParseException during parsing
  • Added more constants (see List of pre defined constants) (#5, thanks @NhanAZ!)
arithmexp - v0.1.17

Published by Muqsit about 2 years ago

  • BinaryOperators can now be checked for commutativity through BinaryOperator::isCommutative()
  • Improved Operator Strength Reduction optimization by accounting for commutativity of binary operations (#8, thanks @sylvrs!)
arithmexp - v0.1.16

Published by Muqsit about 2 years ago

  • OSR now optimizes expressions such as x - x to 0
  • OSR now optimizes 1 ** x to 1
  • Fixed parse errors arising from OSR not correctly building token tree
  • Removed Parser::parseRawExpression()
    • Parser::createUnoptimized()->parse() may be used instead
arithmexp - v0.1.15

Published by Muqsit about 2 years ago

arithmexp - v0.1.14

Published by Muqsit about 2 years ago

  • Fix function call with undefined optional argument without trailing commas incorrectly throwing a RuntimeException during parsing
arithmexp - v0.1.13

Published by Muqsit about 2 years ago

  • ParseException now highlights the problematic substring within the expression along with displaying the exception message
    • Before
      Fatal error: Uncaught muqsit\arithmexp\ParseException: Cannot resolve function call at "mt_rand(3, 4, 5)" (34:50) in "x + min(mt_rand(1, 3), mt_rand(2, mt_rand(3, 4, 5)), 7) * y": Too many parameters supplied to function call: Expected 2 parameters, got 3 parameters
      
    • After
      Fatal error: Uncaught muqsit\arithmexp\ParseException: Cannot resolve function call at "mt_rand(3, 4, 5)" (34:50) in "x + min(mt_rand(1, 3), mt_rand(2, mt_rand(3, 4, 5)), 7) * y": Too many parameters supplied to function call: Expected 2 parameters, got 3 parameters
       | x + min(mt_rand(1, 3), mt_rand(2, mt_rand(3, 4, 5)), 7) * y
       |                                   ^^^^^^^^^^^^^^^^ 
      
  • Stack traces of errors arising from the parser are now more concise
    • Before
      muqsit@*********:~/arithmexp/tests$ php test3.php "x + min(mt_rand(1, 3), mt_rand(2, mt_rand(3, 4, 5)), 7) * y"
      
      Fatal error: Uncaught muqsit\arithmexp\ParseException: Cannot resolve function call at "mt_rand(3, 4, 5)" (34:50) in "x + min(mt_rand(1, 3), mt_rand(2, mt_rand(3, 4, 5)), 7) * y": Too many parameters supplied to function call: Expected 2 parameters, got 3 parameters
       | x + min(mt_rand(1, 3), mt_rand(2, mt_rand(3, 4, 5)), 7) * y
       |                                   ^^^^^^^^^^^^^^^^ in /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/ParseException.php:32
      Stack trace:
      #0 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/ParseException.php(144): muqsit\arithmexp\ParseException::generateWithHighlightedSubstring(Object(muqsit\arithmexp\ParseException))
      #1 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/Parser.php(352): muqsit\arithmexp\ParseException::unresolvableFcallTooManyParams('x + min(mt_rand...', Object(muqsit\arithmexp\token\FunctionCallToken), Object(muqsit\arithmexp\function\FunctionInfo), 3)
      #2 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/Parser.php(283): muqsit\arithmexp\Parser->transformFunctionCallTokens('x + min(mt_rand...', Array)
      #3 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/Parser.php(283): muqsit\arithmexp\Parser->transformFunctionCallTokens('x + min(mt_rand...', Array)
      #4 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/Parser.php(283): muqsit\arithmexp\Parser->transformFunctionCallTokens('x + min(mt_rand...', Array)
      #5 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/Parser.php(283): muqsit\arithmexp\Parser->transformFunctionCallTokens('x + min(mt_rand...', Array)
      #6 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/Parser.php(283): muqsit\arithmexp\Parser->transformFunctionCallTokens('x + min(mt_rand...', Array)
      #7 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/Parser.php(283): muqsit\arithmexp\Parser->transformFunctionCallTokens('x + min(mt_rand...', Array)
      #8 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/Parser.php(283): muqsit\arithmexp\Parser->transformFunctionCallTokens('x + min(mt_rand...', Array)
      #9 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/Parser.php(143): muqsit\arithmexp\Parser->transformFunctionCallTokens('x + min(mt_rand...', Array)
      #10 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/Parser.php(97): muqsit\arithmexp\Parser->processTokens('x + min(mt_rand...', Array)
      #11 /home/muqsit/arithmexp/tests/test3.php(13): muqsit\arithmexp\Parser->parseExpression('x + min(mt_rand...')
      #12 {main}
        thrown in /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/ParseException.php on line 32
      
    • After
      muqsit@*********:~/arithmexp/tests$ php test3.php "x + min(mt_rand(1, 3), mt_rand(2, mt_rand(3, 4, 5)), 7) * y"
      
      Fatal error: Uncaught muqsit\arithmexp\ParseException: Cannot resolve function call at "mt_rand(3, 4, 5)" (34:50) in "x + min(mt_rand(1, 3), mt_rand(2, mt_rand(3, 4, 5)), 7) * y": Too many parameters supplied to function call: Expected 2 parameters, got 3 parameters
       | x + min(mt_rand(1, 3), mt_rand(2, mt_rand(3, 4, 5)), 7) * y
       |                                   ^^^^^^^^^^^^^^^^ in /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/ParseException.php:32
      Stack trace:
      #0 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/ParseException.php(144): muqsit\arithmexp\ParseException::generateWithHighlightedSubstring(Object(muqsit\arithmexp\ParseException))
      #1 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/Parser.php(337): muqsit\arithmexp\ParseException::unresolvableFcallTooManyParams('x + min(mt_rand...', Object(muqsit\arithmexp\token\FunctionCallToken), Object(muqsit\arithmexp\function\FunctionInfo), 3)
      #2 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/Parser.php(143): muqsit\arithmexp\Parser->transformFunctionCallTokens('x + min(mt_rand...', Array)
      #3 /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/Parser.php(97): muqsit\arithmexp\Parser->processTokens('x + min(mt_rand...', Array)
      #4 /home/muqsit/arithmexp/tests/test3.php(13): muqsit\arithmexp\Parser->parseExpression('x + min(mt_rand...')
      #5 {main}
        thrown in /home/muqsit/arithmexp/tests/vendor/muqsit/arithmexp/src/muqsit/arithmexp/ParseException.php on line 32