Custom Operators

See also

See this section for details on operator precedence.

For use as a DSL (Domain-Specific Languages), it is sometimes more convenient to augment Rhai with customized operators performing specific logic.

Engine::register_custom_operator registers a keyword as a custom operator, giving it a particular precedence (which cannot be zero).

Support for custom operators can be disabled via the no_custom_syntax feature.

Example

use rhai::Engine;

let mut engine = Engine::new();

// Register a custom operator '#' and give it a precedence of 160
// (i.e. between +|- and *|/)
// Also register the implementation of the custom operator as a function
engine.register_custom_operator("#", 160)?
      .register_fn("#", |x: i64, y: i64| (x * y) - (x + y));

// The custom operator can be used in expressions
let result = engine.eval_expression::<i64>("1 + 2 * 3 # 4 - 5 / 6")?;
//                                                    ^ custom operator

// The above is equivalent to: 1 + ((2 * 3) # 4) - (5 / 6)
result == 15;

Alternatives to a Custom Operator

Custom operators are merely syntactic sugar. They map directly to registered functions.

let mut engine = Engine::new();

// Define 'foo' operator
engine.register_custom_operator("foo", 160)?;

engine.eval::<i64>("1 + 2 * 3 foo 4 - 5 / 6")?;       // use custom operator

engine.eval::<i64>("1 + foo(2 * 3, 4) - 5 / 6")?;     // <- above is equivalent to this

A script using custom operators can always be pre-processed, via a pre-processor application, into a syntax that uses the corresponding function calls.

Using Engine::register_custom_operator merely enables a convenient shortcut.

Must be a Valid Identifier or Reserved Symbol

All custom operators must be identifiers that follow the same naming rules as variables.

Alternatively, they can also be reserved symbols, disabled operators or keywords.

engine.register_custom_operator("foo", 20)?;          // 'foo' is a valid custom operator

engine.register_custom_operator("#", 20)?;            // the reserved symbol '#' is also
                                                      // a valid custom operator

engine.register_custom_operator("+", 30)?;            // <- error: '+' is an active operator

engine.register_custom_operator("=>", 30)?;           // <- error: '=>' is an active symbol

Binary Operators Only

All custom operators must be binary (i.e. they take two operands). Unary custom operators are not supported.

// Register unary '#' operator
engine.register_custom_operator("#", 160)?
      .register_fn("#", |x: i64| x * x);

engine.eval::<i64>("# 42")?;                          // <- syntax error