-
Notifications
You must be signed in to change notification settings - Fork 1
Operator
arithmexp
features two kinds of operators — unary, and binary. Below is a list of all operators featured by the library.
Operator | Name |
---|---|
+ |
Binary Addition |
/ |
Binary Division |
== |
Binary Equal |
** |
Binary Exponentiation |
> |
Binary Greater than |
>= |
Binary Greater than or equal to |
=== |
Binary Identical |
< |
Binary Lesser than |
<= |
Binary Lesser than or equal to |
&& |
Binary Logical And |
|| |
Binary Logical Or |
and |
Binary Logical And (lower precedence) |
or |
Binary Logical Or (lower precedence) |
xor |
Binary Logical Xor |
% |
Binary Modulo |
* |
Binary Multiplication |
!= |
Binary Not equal |
!== |
Binary Not identical |
<=> |
Binary Spaceship |
- |
Binary Subtraction |
! |
Unary Logical Not |
- |
Unary Negative |
+ |
Unary Positive |
Operator precedence in arithmexp
is at par with PHP's arithmetic operator precedence. Precedence of binary operators is governed by two attributes — a priority value (an integer), and associativity (left-associative or right-associative). If an operator ~
is left-associative, then x ~ y ~ z
will be computed as (x ~ y) ~ z
. If the operator were right-associative, the expression would be computed as x ~ (y ~ z)
.
While there appears to be no difference in the resulting value due to associativity type in the given expression, this may not always be the case. For example, when multiple operators differing by commutativity are given the same precedence (such as in x - y + z
where +
and -
are given the same precedence and are left-associative), the expression 7 - 6 + 5
would evaluate as (7 - 6) + 5
= 6
instead of 7 - (6 + 5)
= -4
. You may read more about operator associativity here.
Associativity of non-associative operators cannot be implicitly determined. The expression a == b == c
will not be parsed (an exception is thrown), while the expressions a == (b == c)
and (a == b) == c
are valid.
Below is a table of operators in ascending order of precedence.
Associativity | Operators |
---|---|
Right-associative | ** |
N/A |
+ - (unary) |
N/A | ! |
Left-associative |
* / %
|
Left-associative |
+ - (binary) |
Non-Associative |
> >= < <=
|
Non-Associative |
== != === !==
|
Left-associative | && |
Left-associative | || |
Left-associative | and |
Left-associative | xor |
Left-associative | or |
An operator may be registered for a given parser before expressions are parsed by invoking BinaryOperatorRegistry::register()
to register a binary operator, or UnaryOperatorRegistry::register()
to register a unary operator.
$bop_registry = $parser->operator_manager->binary_registry;
$bop_registry->register(new SimpleBinaryOperator(
"..", // <- symbol
"Random Value", // <- name
BinaryOperatorPrecedence::EXPONENTIAL,
RightBinaryOperatorAssignment::instance(),
SimpleFunctionInfo::from(
static fn(int $x, int $y) : int => mt_rand($x, $y), // <- computer
0 // <- function flags
)
));
$uop_registry = $parser->operator_manager->unary_registry;
$uop_registry->register(new SimpleUnaryOperator(
"^", // <- symbol
"Reciprocal", // <- name
SimpleFunctionInfo::from(
static fn(int|float $x) : int|float => 1 / $x, // <- computer
0 // <- function flags
)
));
$parser->parse("3..5")->evaluate(); // may be 3
$parser->parse("3..5")->evaluate(); // may be 4
$parser->parse("3..5")->evaluate(); // may be 5
$parser->parse("^5")->evaluate(); // 0.2
Unary operators use prefix notation (the operator appears before its operand), while binary operators use infix notation (the operator appears between its operands). Operators may be registered as function-like macros (instead of closures as done above) by passing a MacroFunctionInfo
instead of a SimpleFunctionInfo
.
Why do I need to define function flags for an operator?
Function flags are used by various optimization techniques in making informative decisions in reducing computation. For example, the optimizer may resolve(x + y) - (y + x)
to a constant expression0
, eliminating variable resolution completely for the given expression if appropriate function flags are set. Learn more about function flags on the function page.
Try out arithmexp
on the demo site!
1.1. Installation
2.1. Constant
2.2. Function
2.3. Macro
2.4. Operator
2.5. Variable
2.6. Expression Optimization
2.7. Implementation Internals