diff --git a/doc/15-language-reference.md b/doc/15-language-reference.md index 17fab5fd8..4fe62affd 100644 --- a/doc/15-language-reference.md +++ b/doc/15-language-reference.md @@ -147,36 +147,40 @@ strings and numbers. ### Operators -The following operators are supported in expressions: +The following operators are supported in expressions. The operators are by descending precedence. -Operator | Examples (Result) | Description ----------|-----------------------------------------------|-------------------------------- -! | !"Hello" (false), !false (true) | Logical negation of the operand -~ | ~true (false) | Bitwise negation of the operand -+ | 1 + 3 (4), "hello " + "world" ("hello world") | Adds two numbers; concatenates strings -+ | +3 | Unary plus -- | 3 - 1 (2) | Subtracts two numbers -- | -3 | Unary minus -* | 5m * 10 (3000) | Multiplies two numbers -/ | 5m / 5 (60) | Divides two numbers -% | 17 % 12 (5) | Remainder after division -^ | 17 ^ 12 (29) | Bitwise XOR -& | 7 & 3 (3) | Binary AND -| | 2 | 3 (3) | Binary OR -&& | true && false (false), 3 && 7 (7), 0 && 7 (0) | Logical AND -|| | true || false (true), 0 || 7 (7)| Logical OR -< | 3 < 5 (true) | Less than -> | 3 > 5 (false) | Greater than -<= | 3 <= 3 (true) | Less than or equal ->= | 3 >= 3 (true) | Greater than or equal -<< | 4 << 8 (1024) | Left shift ->> | 1024 >> 4 (64) | Right shift -== | "hello" == "hello" (true), 3 == 5 (false) | Equal to -!= | "hello" != "world" (true), 3 != 3 (false) | Not equal to -in | "foo" in [ "foo", "bar" ] (true) | Element contained in array -!in | "foo" !in [ "bar", "baz" ] (true) | Element not contained in array -() | (3 + 3) * 5 | Groups sub-expressions -() | Math.random() | Calls a function +Operator | Precedence | Examples (Result) | Description +---------|------------|-----------------------------------------------|-------------------------------- +() | 1 | (3 + 3) * 5 | Groups sub-expressions +() | 1 | Math.random() | Calls a function +[] | 1 | a[3] | Array subscript +. | 1 | a.b | Element access +! | 2 | !"Hello" (false), !false (true) | Logical negation of the operand +~ | 2 | ~true (false) | Bitwise negation of the operand ++ | 2 | +3 | Unary plus +- | 2 | -3 | Unary minus +* | 3 | 5m * 10 (3000) | Multiplies two numbers +/ | 3 | 5m / 5 (60) | Divides two numbers +% | 3 | 17 % 12 (5) | Remainder after division ++ | 4 | 1 + 3 (4), "hello " + "world" ("hello world") | Adds two numbers; concatenates strings +- | 4 | 3 - 1 (2) | Subtracts two numbers +<< | 5 | 4 << 8 (1024) | Left shift +>> | 5 | 1024 >> 4 (64) | Right shift +< | 6 | 3 < 5 (true) | Less than +> | 6 | 3 > 5 (false) | Greater than +<= | 6 | 3 <= 3 (true) | Less than or equal +>= | 6 | 3 >= 3 (true) | Greater than or equal +in | 7 | "foo" in [ "foo", "bar" ] (true) | Element contained in array +!in | 7 | "foo" !in [ "bar", "baz" ] (true) | Element not contained in array +== | 8 | "hello" == "hello" (true), 3 == 5 (false) | Equal to +!= | 8 | "hello" != "world" (true), 3 != 3 (false) | Not equal to +& | 9 | 7 & 3 (3) | Binary AND +^ | 10 | 17 ^ 12 (29) | Bitwise XOR +| | 11 | 2 | 3 (3) | Binary OR +&& | 13 | true && false (false), 3 && 7 (7), 0 && 7 (0) | Logical AND +|| | 14 | true || false (true), 0 || 7 (7)| Logical OR += | 12 | a = 3 | Assignment +=> | 15 | x => x * x (function with arg x) | Lambda, for loop ### Function Calls diff --git a/lib/config/config_parser.yy b/lib/config/config_parser.yy index 83a2e5514..357bf40fc 100644 --- a/lib/config/config_parser.yy +++ b/lib/config/config_parser.yy @@ -210,20 +210,20 @@ static void MakeRBinaryOp(Expression** result, Expression *left, Expression *rig %right T_FOLLOWS %right T_INCLUDE T_INCLUDE_RECURSIVE T_OBJECT T_TEMPLATE T_APPLY T_IMPORT T_ASSIGN T_IGNORE T_WHERE %right T_FUNCTION T_FOR +%left T_SET T_SET_ADD T_SET_SUBTRACT T_SET_MULTIPLY T_SET_DIVIDE T_SET_MODULO T_SET_XOR T_SET_BINARY_AND T_SET_BINARY_OR %left T_LOGICAL_OR %left T_LOGICAL_AND %left T_RETURN %left T_IDENTIFIER -%left T_SET T_SET_ADD T_SET_SUBTRACT T_SET_MULTIPLY T_SET_DIVIDE T_SET_MODULO T_SET_XOR T_SET_BINARY_AND T_SET_BINARY_OR -%nonassoc T_EQUAL T_NOT_EQUAL -%nonassoc T_LESS_THAN T_LESS_THAN_OR_EQUAL T_GREATER_THAN T_GREATER_THAN_OR_EQUAL %left T_BINARY_OR -%left T_XOR T_MODULO +%left T_XOR %left T_BINARY_AND +%nonassoc T_EQUAL T_NOT_EQUAL %left T_IN T_NOT_IN +%nonassoc T_LESS_THAN T_LESS_THAN_OR_EQUAL T_GREATER_THAN T_GREATER_THAN_OR_EQUAL %left T_SHIFT_LEFT T_SHIFT_RIGHT %left T_PLUS T_MINUS -%left T_MULTIPLY T_DIVIDE_OP +%left T_MULTIPLY T_DIVIDE_OP T_MODULO %left UNARY_MINUS UNARY_PLUS %right '!' '~' %left '.' '(' '[' diff --git a/test/config-ops.cpp b/test/config-ops.cpp index b812c34bd..f9686d62c 100644 --- a/test/config-ops.cpp +++ b/test/config-ops.cpp @@ -268,15 +268,15 @@ BOOST_AUTO_TEST_CASE(advanced) BOOST_CHECK(expr->Evaluate(frame)); delete expr; - expr = ConfigCompiler::CompileText("", "7 | 8 == 15"); + expr = ConfigCompiler::CompileText("", "(7 | 8) == 15"); BOOST_CHECK(expr->Evaluate(frame)); delete expr; - expr = ConfigCompiler::CompileText("", "7 ^ 8 == 15"); + expr = ConfigCompiler::CompileText("", "(7 ^ 8) == 15"); BOOST_CHECK(expr->Evaluate(frame)); delete expr; - expr = ConfigCompiler::CompileText("", "7 & 15 == 7"); + expr = ConfigCompiler::CompileText("", "(7 & 15) == 7"); BOOST_CHECK(expr->Evaluate(frame)); delete expr; @@ -288,15 +288,15 @@ BOOST_AUTO_TEST_CASE(advanced) BOOST_CHECK(expr->Evaluate(frame)); delete expr; - expr = ConfigCompiler::CompileText("", "7 | 8 > 14"); + expr = ConfigCompiler::CompileText("", "(7 | 8) > 14"); BOOST_CHECK(expr->Evaluate(frame)); delete expr; - expr = ConfigCompiler::CompileText("", "7 ^ 8 > 14"); + expr = ConfigCompiler::CompileText("", "(7 ^ 8) > 14"); BOOST_CHECK(expr->Evaluate(frame)); delete expr; - expr = ConfigCompiler::CompileText("", "7 & 15 > 6"); + expr = ConfigCompiler::CompileText("", "(7 & 15) > 6"); BOOST_CHECK(expr->Evaluate(frame)); delete expr;