ExprLib — Pine Script library

20260729_rev01 · COMPARED WITH 20260604_rev01

Full text changes — 20260604_rev01 to 20260729_rev01

1ExprLib is a library for parsing and evaluating string expressions. It allows scripts to expose configurable logic by letting users define custom conditions and calculations based on available data.
2
3**█  KEY FEATURES**
4
5• Rich expression support:
6    • Built-in constants (e.g., \`10\`, \`2.5\`, \`5e-2\`, \`true\`, \`false\`, \`na\`)
7    • Custom constants
8    • Variables
9    • Arithmetic operators: \`+\`, \`-\`, \`\*\`, \`/\`, \`%\`
10    • Comparison operators: \`>\`, \`<\`, \`>=\`, \`<=\`, \`==\`, \`!=\`
11    • Logical operators: \`AND\`, \`OR\`, \`NOT\` (with aliases)
12    • Ternary operator: \`condition ? if\_true : if\_false\`
13    • Parentheses: \`(\`, \`)\`
14    • Built-in functions: \`na()\`, \`nz()\`, \`max()\`, \`pow()\`, \`sqrt()\`, \`random()\`, and more!
15• Graceful error handling during parsing and evaluation
16• Optimized for evaluation performance (RPN-based approach)
17
18**█  NOTE**
19
20Since the library description cannot be changed or removed after publication, some information here may be outdated. However, you can always get the latest version of the documentation at the bottom of the source code.
21
22**█  QUICK START**
23
24An example of an indicator that colors areas on a chart where the expression evaluates to \`true\`:
25
26//@version=6 indicator("Quick Start", overlay = true) import A1trdX/ExprLib/1 as ExprLib // --------------- // INPUTS // --------------- // Let the user customize the expression inputExpressionStr = input.text\_area("trend\_up AND (rsi < 50 OR close < open)", "Expression") // ------------------- // CALCULATION // ------------------- // Prepare some data to use in the expression. rsi = ta.rsi(close, 14) ema = ta.ema(close, 200) isTrendUp = close > ema isTrendDown = close < ema // Step 0: Prepare the parser and evaluator. var parser = ExprLib.createExpressionParser() var evaluator = ExprLib.createExpressionEvaluator() // Step 1: Parse the expression string. var expression = parser.parse(inputExpressionStr) // Step 2 (Recommended): Verify whether the expression was parsed without errors. if not parser.isParsed // You can define your own logic to handle errors runtime.error("Failed to parse expression: " + parser.error.message) // Step 3: Assign values to variables. Both numbers and booleans are supported. expression.setVariable("open", open) expression.setVariable("close", close) expression.setVariable("rsi", rsi) expression.setVariable("trend\_up", isTrendUp) expression.setVariable("trend\_down", isTrendDown) // Step 4: Evaluate the expression. bool result = evaluator.evaluateToBool(expression) // Step 4 (Alternative): If you expect a numeric result, use \`evaluate()\` instead. // float result = evaluator.evaluate(expression) // Step 5 (Recommended): Verify whether the expression was evaluated without errors. if not evaluator.isEvaluated // You can define your own logic to handle errors runtime.error("Failed to evaluate expression: " + evaluator.error.message) // ---------------- // GRAPHICS // ---------------- // Highlight bars where the expression returns \`true\` bgcolor(result ? color.new(color.green, 90) : na)
27
28**█  EXPRESSION SYNTAX REFERENCE**
29
30**❱❱  Components**
31
32An expression can include:
33• Constants
34• Variables
35• Operators
36• Functions
37• Parentheses
38• Spaces, tabs, or newlines
39
40**❱❱  Data Types**
41
42Constants and variables can have the following data types:
43• Numeric (\`int\`, \`float\`)
44• Boolean (\`bool\`)
45• Undefined (\`na\`)
46
47**❱❱  Identifiers**
48
49Identifiers are names used to refer to named constants, variables, and functions.
50
51Identifier naming rules:
52• Must start with a letter (\`a-z\`, \`A-Z\`) or underscore (\`\_\`).
53• May contain letters (\`a-z\`, \`A-Z\`), digits (\`0-9\`), and underscores (\`\_\`).
54
55Identifiers cannot contain spaces or other characters.
56
57Identifiers are case-sensitive.
58
59**❱❱  Constants**
60
61**Numeric Constants**
62
63Examples:
64
65+-----------+--------------+ | Constant | Plain Value | +-----------+--------------+ | 12 | 12.00 | | 0.05 | 0.05 | | .05 | 0.05 | | 5e-2 | 0.05 | | 5E-2 | 0.05 | | 1.2e4 | 12000.00 | +-----------+--------------+
66
67**Named Constants**
68
69Available built-in named constants:
70
71+----------+-------------------------------------+-------------------------+ | Name | Description | Pine Script Equivalent | +----------+-------------------------------------+-------------------------+ | \`true\` | Boolean TRUE | \`true\` | | \`false\` | Boolean FALSE | \`false\` | | \`na\` | Undefined value | \`na\` | | \`pi\` | Pi (~3.14159) | \`math.pi\` | | \`e\` | Euler's number (~2.71828) | \`math.e\` | | \`phi\` | Golden ratio (~1.61803) | \`math.phi\` | | \`rphi\` | Golden ratio conjugate (~0.61803) | \`math.rphi\` | +----------+-------------------------------------+-------------------------+
72
73It is possible to add custom constants.
74
75**❱❱  Variables**
76
77It is possible to add variables, just like custom constants, except that variable values can be changed before each evaluation.
78
79**❱❱  Operators**
80
81The following operators are supported:
82
83+--------------+-------------+-------------------------+-------------+------------------+-------------+ | Type | Operator | Name | Aliases | Example #1 | Example #2 | +--------------+-------------+-------------------------+-------------+------------------+-------------+ | Arithmetic | \`+\` | Add | | \`a + b\` | | | Arithmetic | \`-\` | Subtract | | \`a - b\` | | | Arithmetic | \`\*\` | Multiply | | \`a \* b\` | | | Arithmetic | \`/\` | Divide | | \`a / b\` | | | Arithmetic | \`%\` | Modulo | | \`a % b\` | | | Comparison | \`>\` | Greater than | | \`a > b\` | | | Comparison | \`<\` | Less than | | \`a < b\` | | | Comparison | \`>=\` | Greater than or equal | | \`a >= b\` | | | Comparison | \`<=\` | Less than or equal | | \`a <= b\` | | | Comparison | \`==\` | Equal | | \`a == b\` | | | Comparison | \`!=\` | Not equal | | \`a != b\` | | | Logical | \`AND\` | Logical AND | \`&&\`, \`&\` | \`a AND b\` | \`a && b\` | | Logical | \`OR\` | Logical OR | \`||\`, \`|\` | \`a OR b\` | \`a || b\` | | Logical | \`NOT\` | Logical NOT | \`!\` | \`NOT x\` | \`!x\` | | Conditional | \`?:\` | Ternary | | \`cond ? x : y\` | | | Unary | Unary \`+\` | Unary plus | | \`+x\` | | | Unary | Unary \`-\` | Unary minus | | \`-x\` | | +--------------+-------------+-------------------------+-------------+------------------+-------------+
84
85Logical operator names are case-insensitive.
86
87Operator precedence:
88
89+------------+-----------------------------+ | Precedence | Operators | +------------+-----------------------------+ | 8 | Unary \`-\`, Unary \`+\`, \`NOT\` | | 7 | \`\*\`, \`/\`, \`%\` | | 6 | \`+\`, \`-\` | | 5 | \`>\`, \`<\`, \`>=\`, \`<=\` | | 4 | \`==\`, \`!=\` | | 3 | \`AND\` | | 2 | \`OR\` | | 1 | \`?:\` | +------------+-----------------------------+
90
91Operator associativity:
92• Unary \`+\`, Unary \`-\`, \`NOT\`, and ternary are right-associative
93• Other operators are left-associative
94
95**❱❱  Parentheses**
96
97Parentheses are used to group sub-expressions and override the default operator precedence.
98
99Example:
100
101((a + b) \* c + 1) \* d
102
103**❱❱  Functions**
104
105Functions are called by an identifier followed immediately by parentheses: \`func(arg1, arg2)\`.
106
107Arguments are separated by commas. Each argument can be any valid expression, including another function call.
108
109Available built-in functions:
110
111+-------------------------------+----------+------------------------------------------------------------------------+ | Function | Args | Description | +-------------------------------+----------+------------------------------------------------------------------------+ | \`na(x)\` | 1 | Returns \`true\` when \`x\` is \`na\`, \`false\` otherwise. | | \`nz(x, fallback)\` | 2 | Returns \`x\` when it is not \`na\`, \`fallback\` otherwise. | | \`max(x1, x2, ...)\` | 2..999 | Returns the largest argument. | | \`min(x1, x2, ...)\` | 2..999 | Returns the smallest argument. | | \`pow(base, exponent)\` | 2 | Returns \`base\` raised to \`exponent\`. | | \`sqrt(x)\` | 1 | Returns the square root of \`x\`. | | \`clamp(x, min, max)\` | 3 | Restricts \`x\` to the \`\[min, max\]\` range. | | \`abs(x)\` | 1 | Returns the absolute value of \`x\`. | | \`ceil(x)\` | 1 | Rounds \`x\` up to the nearest integer. | | \`floor(x)\` | 1 | Rounds \`x\` down to the nearest integer. | | \`round(x)\` | 1 | Rounds \`x\` to the nearest integer. | | \`round\_to\_mintick(x)\` | 1 | Rounds \`x\` to the symbol's minimum tick precision. | | \`log(x)\` | 1 | Returns the natural logarithm of \`x\`. | | \`log10(x)\` | 1 | Returns the base-10 logarithm of \`x\`. | | \`sign(x)\` | 1 | Returns the sign of \`x\`: \`1\`, \`0\`, or \`-1\`. | | \`cos(x)\` | 1 | Returns the cosine of \`x\` in radians. | | \`sin(x)\` | 1 | Returns the sine of \`x\` in radians. | | \`tan(x)\` | 1 | Returns the tangent of \`x\` in radians. | | \`acos(x)\` | 1 | Returns the arccosine of \`x\` in radians. | | \`asin(x)\` | 1 | Returns the arcsine of \`x\` in radians. | | \`atan(x)\` | 1 | Returns the arctangent of \`x\` in radians. | | \`deg(x)\` | 1 | Converts radians to degrees. | | \`rad(x)\` | 1 | Converts degrees to radians. | | \`random(min, max, seed)\` | 0..3 | Returns a random float. Bounds default to 0 and 1. Seed is optional. | | \`random\_int(min, max, seed)\` | 2..3 | Returns a random integer. Seed is optional. | | \`random\_bool(seed)\` | 0..1 | Returns a random boolean value. Seed is optional. | +-------------------------------+----------+------------------------------------------------------------------------+
112
113The number of arguments can be either fixed or variable.
114
115For example, the \`max(x1, x2, ...)\` function supports 2 to 999 arguments, so the following calls to this function are valid:
116
117max(x1, x2) max(x1, x2, x3) max(x1, x2, x3, x4, x5)
118
119Other functions may have optional arguments. For example, the following calls to the \`random(min, max, seed)\` function are valid:
120
121random() // Random float from 0 to 1 random(0.5) // Random float from 0.5 to 1 random(0.5, 2) // Random float from 0.5 to 2 random(0.5, 2, 777) // Random float from 0.5 to 2 with a specific seed
122
123**❱❱  Whitespace**
124
125Spaces, tabs, and line breaks are ignored between symbols. For example, an expression can be formatted across multiple lines:
126
127price > ema\_slow AND ema\_fast > ema\_slow AND (bb\_lo\_up OR rsi\_lo\_up)
128
129**█  PARSING**
130
131**❱❱  Workflow**
132
133Before evaluating an expression, it must be parsed. To do this:
134• Create a parser in advance using the \`createExpressionParser()\` function.
135• Call the \`parse()\` method, passing the expression string as an argument.
136
137Example:
138
139var parser = ExprLib.createExpressionParser() var expr1 = parser.parse("a + 2") var expr2 = parser.parse("a + b \* c")
140
141**❱❱  Error Handling**
142
143A user may enter an invalid expression. In this case, the parser will return \`na\` instead of a valid expression object. The parser stores the result of the last parse. You can use that result to retrieve the status and error information.
144
145Parser and error field structures:
146
147type ExpressionParser bool isParsed // \`true\` if the last parse completed successfully, \`false\` otherwise. ParseError error // Error from the last parse attempt. If the last parse was successful, then this field is \`na\`. type ParseError string message // Error message. int index // Character index where the parser detected the error.
148
149For example, suppose we want to display an error message on the chart if one of the expressions is invalid:
150
151//@version=6 indicator("Parser Error Handling") import A1trdX/ExprLib/1 as ExprLib inputExpr1 = input.text\_area("a + 2", "Expression 1") inputExpr2 = input.text\_area("a + b \* c /", "Expression 2") displayErrorMessage(string errorMessage) => var table errorMessageTable = na if na(errorMessageTable) errorMessageTable := table.new(position.top\_right, 1, 1) errorMessageTable.cell(0, 0, errorMessage, bgcolor = color.red, text\_color = color.white, text\_halign = text.align\_left, text\_formatting = text.format\_bold) checkParsed(ExprLib.ExpressionParser parser, string prefix) => if not parser.isParsed displayErrorMessage(prefix + parser.error.message) var parser = ExprLib.createExpressionParser() var expr1 = parser.parse(inputExpr1) checkParsed(parser, "Failed to parse expression #1:\\n") var expr2 = parser.parse(inputExpr2) checkParsed(parser, "Failed to parse expression #2:\\n")
152
153A blank expression (e.g., "") is allowed and will evaluate to \`na\` (or \`false\` when returning a boolean value).
154
155**❱❱  Custom Constants**
156
157You can add your own named constants during the parsing stage. To do this:
158• Create a constant pool in advance using the \`createConstantPool()\` function.
159• Set constants and their values using the \`set()\` method.
160• Pass the constant pool to the \`parse()\` method.
161
162Example:
163
164var constantPool = ExprLib.createConstantPool() if barstate.isfirst constantPool.set("one", 1) constantPool.set("two", 2) constantPool.set("three\_p\_one", 3.1) constantPool.set("yes", true) constantPool.set("no", false) var parser = ExprLib.createExpressionParser() var expr = parser.parse("one + two", constantPool)
165
166The \`set()\` method returns the same constant pool object, so you can chain calls together. This is more convenient and more elegant:
167
168var constantPool = ExprLib.createConstantPool() .set("one", 1) .set("two", 2) .set("three\_p\_one", 3.1) .set("yes", true) .set("no", false) // Note that the indentation is 7 spaces (not a multiple of 4) var parser = ExprLib.createExpressionParser() var expr = parser.parse("one + two", constantPool)
169
170You can also override built-in constants:
171
172var constantPool = ExprLib.createConstantPool() .set("true", false) .set("false", -1) .set("na", 0.0)
173
174**█  EVALUATION**
175
176**❱❱  Type Coercion**
177
178An expression can consist of values of different data types. ExprLib does not have strict data type checking. Instead, all values are converted to \`float\` and then back if necessary.
179
180Converting \`bool\` to \`float\`:
181• \`true\` -> \`1.0\`
182• \`false\` -> \`0.0\`
183
184Converting \`float\` to \`bool\`:
185• \`0.0\` or \`na\` -> \`false\`
186• Any other value -> \`true\`
187
188Thus, expressions that incorrectly combine different data types are allowed. For example, \`true + 2\` will return \`3.0\`. Strict typing requires additional memory as well as additional computational resources during evaluation, which is a critical concern. Therefore, it was decided not to implement it.
189
190As in Pine Script, most operations with an \`na\` operand results in \`na\` or \`false\`, but logical operations first convert \`na\` to \`false\`, so their result follows boolean logic. For example:
191• \`3 - na\` returns \`na\`
192• \`3 > na\` returns \`false\`
193• \`3 <= na\` also returns \`false\`
194• \`na AND true\` returns \`false\`
195• \`na OR true\` returns \`true\`
196• \`NOT na\` returns \`true\`
197
198**❱❱  Workflow**
199
200To evaluate an expression:
201• Create an evaluator in advance using the \`createExpressionEvaluator()\` function.
202• Set variables and their values in the expression using the \`setVariable()\` method.
203• Call the \`evaluate()\` or \`evaluateToBool()\` method, passing the expression as an argument.
204
205The \`evaluate()\` and \`evaluateToBool()\` methods differ in their return types. The former returns a \`float\` result, while the latter returns a \`bool\` result. The method to call depends on the expected result type.
206
207Example:
208
209// Parsed expressions: // - expr1 <= "(H - L) / 2 + L" // - expr2 <= "rsi\_oversold AND close > open" // Initialize evaluator var evaluator = ExprLib.createExpressionEvaluator() // Set variables and evaluate the first expression expr1.setVariable("H", high) expr1.setVariable("L", low) float result1 = evaluator.evaluate(expr1) // Set variables and evaluate the second expression rsi = ta.rsi(close, 14) expr2.setVariable("open", open) expr2.setVariable("close", close) expr2.setVariable("rsi\_oversold", rsi < 30) expr2.setVariable("rsi\_overbought", rsi > 70) bool result2 = evaluator.evaluateToBool(expr2)
210
211**❱❱  Variables**
212
213If an expression contains an identifier that is neither a function nor a constant, and this identifier has not been assigned a variable value, then this identifier is considered a constant with the value \`na\` (or \`false\` in boolean operations).
214
215The \`setVariable()\` method overrides existing constants (both built-in and custom). For example, by default, the identifier \`e\` is used as the constant Euler's number (~2.71828). However, you can make \`e\` your own variable:
216
217// Parsed expressions: // - expr <= "e + 1" expr.setVariable("e", 5) // Now \`e\` is equal to \`5\` instead of \`2.7182818284590452\` result = evaluator.evaluate(expr) // \`6.0\`
218
219The \`setVariable()\` method does not need to be called on each bar if the variable's value does not change. The expression always stores and uses the last value set.
220
221You can clear all previously set variables using the \`clearVariables()\` method. This can be useful if you have many variables and want to reset them all and set values for only a small subset.
222
223**❱❱  Error Handling**
224
225In some cases (for example, when dividing by zero), evaluation results in an error. In this case, \`evaluate()\` will return \`na\`, and \`evaluateToBool()\` will return \`false\`. Like the parser, the evaluator stores the result of the last evaluation.
226
227Evaluator and error field structures:
228
229type ExpressionEvaluator bool isEvaluated // \`true\` if the last evaluation completed successfully, \`false\` otherwise. EvaluationError error // Error from the last evaluation attempt. If the last evaluation was successful, then this field is \`na\`. type EvaluationError EvaluationErrorReason reason // Error reason. string message // Error message. enum EvaluationErrorReason DIVISION\_BY\_ZERO
230
231Example:
232
233//@version=6 indicator("Evaluator Error Handling") import A1trdX/ExprLib/1 as ExprLib inputExpr1 = input.text\_area("a + 2", "Expression 1") inputExpr2 = input.text\_area("a + b / c", "Expression 2") displayErrorMessage(string errorMessage) => var table errorMessageTable = na if na(errorMessageTable) errorMessageTable := table.new(position.top\_right, 1, 1) errorMessageTable.cell(0, 0, errorMessage, bgcolor = color.red, text\_color = color.white, text\_halign = text.align\_left, text\_formatting = text.format\_bold) // Parse checkParsed(ExprLib.ExpressionParser parser, string prefix) => if not parser.isParsed displayErrorMessage(prefix + parser.error.message) var parser = ExprLib.createExpressionParser() var expr1 = parser.parse(inputExpr1) checkParsed(parser, "Failed to parse expression #1:\\n") var expr2 = parser.parse(inputExpr2) checkParsed(parser, "Failed to parse expression #2:\\n") // Evaluate checkEvaluated(ExprLib.ExpressionEvaluator evaluator, string prefix) => if not evaluator.isEvaluated displayErrorMessage(prefix + evaluator.error.message) var evaluator = ExprLib.createExpressionEvaluator() expr1.setVariable("a", open) expr1.setVariable("b", close) expr1.setVariable("c", 0) result1 = evaluator.evaluate(expr1) checkEvaluated(evaluator, "Failed to evaluate expression #1:\\n") expr2.setVariable("a", open) expr2.setVariable("b", close) expr2.setVariable("c", 0) result2 = evaluator.evaluate(expr2) checkEvaluated(evaluator, "Failed to evaluate expression #2:\\n")
234
235Currently, the only possible cause of this error is division by zero. You can disable this error and have the evaluator interpret the result of division by zero as \`na\`. To do this, disable the corresponding flag in the evaluator:
236
237evaluator.setFailOnDivisionByZero(false)
238
239Thus, an expression like \`na(5 / 0) ? 1 : 2\` will return \`1\` instead of an error.
240
241**█  BEST PRACTICES**
242
243• Reuse \`ExpressionParser\` and \`ExpressionEvaluator\` objects whenever possible.
244• Parse expressions only once, and evaluate them as needed. Parsing is slow. Evaluation is fast.
245• If certain variable values change rarely, call \`setVariable()\` only when necessary.
246• Try to avoid excessive numbers of variables whose values change frequently. This can impact performance even if they're not used in the expression.
247
248**█  API REFERENCE**
249
250**❱❱  Expression Parser**
251
252**ExpressionParser**
253  Expression parser.
254  Fields:
255    **isParsed (series bool)**: \`true\` if the last parse completed successfully, \`false\` otherwise.
256    **error (ParseError)**: Error from the last parse attempt. If the last parse was successful, then this field is \`na\`.
257
258**createExpressionParser()**
259  Creates an expression parser.
260  Returns: Expression parser.
261
262**method parse(parser, exprStr, constantPool)**
263  Parses an expression.
264  Namespace types: ExpressionParser
265  Parameters:
266    **parser (ExpressionParser)**: Expression parser.
267    **exprStr (string)**: Expression string. Can be empty, blank, or 'na'. That way expression is valid and will return \`na\` on evaluation.
268    **constantPool (ExpressionConstantPool)**: (Optional) Named constants.
269  Returns: Parsed expression. If an error occurs during parsing, then the returned expression will be \`na\`.
270You can check validity and error details accessing parser's \`isParsed\` and \`error\` fields.
271
272**❱❱  Expression**
273
274**Expression**
275  Parsed expression.
276
277**method setVariable(expr, identifier, value)**
278  Assigns a numeric value to a variable.
279  Namespace types: Expression
280  Parameters:
281    **expr (Expression)**: Expression.
282    **identifier (string)**: Variable name.
283    **value (float)**: Value.
284  Returns: This expression.
285
286**method setVariable(expr, identifier, value)**
287  Assigns a boolean value to a variable.
288  Namespace types: Expression
289  Parameters:
290    **expr (Expression)**: Expression.
291    **identifier (string)**: Variable name.
292    **value (bool)**: Value.
293  Returns: This expression.
294
295**method clearVariables(expr)**
296  Clears all variable values.
297  Namespace types: Expression
298  Parameters:
299    **expr (Expression)**: Expression.
300  Returns: This expression.
301
302**❱❱  Constant Pool**
303
304**ExpressionConstantPool**
305  Expression constant pool.
306
307**createConstantPool()**
308  Creates an expression constant pool.
309  Returns: Expression constant pool.
310
311**method set(pool, identifier, value)**
312  Assigns a numeric constant value.
313  Namespace types: ExpressionConstantPool
314  Parameters:
315    **pool (ExpressionConstantPool)**: Expression constant pool.
316    **identifier (string)**: Constant name.
317    **value (float)**: Value.
318  Returns: This expression constant pool.
319
320**method set(pool, identifier, value)**
321  Assigns a boolean constant value.
322  Namespace types: ExpressionConstantPool
323  Parameters:
324    **pool (ExpressionConstantPool)**: Expression constant pool.
325    **identifier (string)**: Constant name.
326    **value (bool)**: Value.
327  Returns: This expression constant pool.
328
329**method clear(pool)**
330  Clears all constants.
331  Namespace types: ExpressionConstantPool
332  Parameters:
333    **pool (ExpressionConstantPool)**: Expression constant pool.
334  Returns: This expression constant pool.
335
336**❱❱  Expression Evaluator**
337
338**ExpressionEvaluator**
339  Expression evaluator.
340  Fields:
341    **isEvaluated (series bool)**: \`true\` if the last evaluation completed successfully, \`false\` otherwise.
342    **error (EvaluationError)**: Error from the last evaluation attempt. If the last evaluation was successful, then this field is \`na\`.
343    **result (series float)**: Numeric result of the last evaluation.
344    **boolResult (series bool)**: Boolean result of the last evaluation.
345
346**createExpressionEvaluator()**
347  Creates an expression evaluator.
348  Returns: Expression evaluator.
349
350**method evaluate(evaluator, expr)**
351  Evaluates an expression.
352  Namespace types: ExpressionEvaluator
353  Parameters:
354    **evaluator (ExpressionEvaluator)**: Expression evaluator.
355    **expr (Expression)**: Expression to evaluate.
356  Returns: Numeric evaluation result.
357For boolean-result expressions \`1.0\` means \`true\` and \`0.0\` means \`false\`.
358Returns \`na\` if expression is empty.
359
360**method evaluateToBool(evaluator, expr)**
361  Evaluates an expression.
362  Namespace types: ExpressionEvaluator
363  Parameters:
364    **evaluator (ExpressionEvaluator)**: Expression evaluator.
365    **expr (Expression)**: Expression to evaluate.
366  Returns: Boolean evaluation result.
367Returns \`false\` if expression is empty.
368
369**method setFailOnDivisionByZero(evaluator, value)**
370  Sets whether division or modulo by zero should fail evaluation.
371  Namespace types: ExpressionEvaluator
372  Parameters:
373    **evaluator (ExpressionEvaluator)**: Expression evaluator.
374    **value (bool)**: If \`true\`, division or modulo by zero fails evaluation. If \`false\`, it produces \`na\`.
375  Returns: This expression evaluator.
376
377**❱❱  Errors**
378
379**ParseError**
380  Error that occurred during expression parsing.
381  Fields:
382    **message (series string)**: Error message.
383    **index (series int)**: Character index where the parser detected the error.
384
385**EvaluationError**
386  Error that occurred during expression evaluation.
387  Fields:
388    **reason (series EvaluationErrorReason)**: Error reason.
389    **message (series string)**: Error message.