expr
)Expressions: mathematical, string comparisons, logical operators
expr
is the underlying builtin which handles all
expression parsing and evaluation in Murex.
Idiomatic Murex would be to write expressions without explicitly calling the underlying builtin:
# idiomatic expressions
1 + 2
# non-idiomatic expressions
expr 1 + 2
Though you can invoke them via expr
if needed, please
bare in mind that expressions have special parsing rules to make them
more ergonomic. So if you write an expression as a command (ie prefixed
with expr
) then it will be parsed as a statement. This
means more complex expressions might parse in unexpected ways and thus
fail. You can still raise a bug if that does happens.
A full list of operators is available in the Operators And Tokens document.
expression -> <stdout>
statement (expression)
expr expression -> <stdout>
» 3 * (3 + 1)
12
Any parameter surrounded by parenthesis is first evaluated as an expression, then as a string“.
» out (3 * 2)
6
Expressions also support running commands as C-style functions, for example:
» 5 * out(5)
25
» datetime(--in {now} --out {unix}) / 60
28339115.783333335
» $file_contents = open(example_file.txt)
Please note that currently the only functions supported are ones who’s names are comprised entirely of alpha, numeric, underscore and/or exclamation marks.
» %[apples oranges grapes]
[
"apples",
"oranges",
"grapes"
]
Sometimes known as dictionaries or maps:
» %{ Age: { Tom: 20, Dick: 30, Sally: 40 } }
{
"Age": {
"Dick": 30,
"Sally": 40,
"Tom": 20
}
}
The order of operations follows the same rules as the C programming language, which itself is an extension of the order of operations in mathematics, often referred to as PEMDAS or MODMAS (read more).
The Wikipedia article summarises that order succinctly however the detailed specification is defined by its implementation, as seen in the code below:
package expressions
import (
"fmt"
"github.com/lmorg/murex/lang/expressions/primitives"
"github.com/lmorg/murex/lang/expressions/symbols"
"github.com/lmorg/murex/utils/consts"
)
func (tree *ParserT) executeExpr() (*primitives.DataType, error) {
:= tree.validateExpression()
err if err != nil {
return nil, err
}
for i := range orderOfOperations {
= executeExpression(tree, orderOfOperations[i])
err if err != nil {
return nil, err
}
}
if len(tree.ast) > 1 {
return nil, fmt.Errorf(
"expression failed to execute correctly (AST results > 1).\n%s",
.IssueTrackerURL)
consts}
return tree.ast[0].dt, nil
}
// To allow for extendability and developer expectations, the order of operations
// will follow what is defined by (for example) C, as outlined in the following:
// https://en.wikipedia.org/wiki/Order_of_operations#Programming_languages
// Not all operations will be available in murex and some are likely to be added
// in future versions of this package.
//
// Please also note that the slice below is just defining the groupings. Each
// operator within the _same_ group will then be processed from left to right.
// Read the `executeExpression` function further down this source file to view
// every supported operator
var orderOfOperations = []symbols.Exp{
// 01. Function call, scope, array/member access
// 02. (most) unary operators, sizeof and type casts (right to left)
// 03. Multiplication, division, modulo
.Multiply,
symbols
// 04. Addition and subtraction
.Add,
symbols
// 04.1 Merge
.Merge,
symbols
// 05. Bitwise shift left and right
// 06. Comparisons: less-than and greater-than
.GreaterThan,
symbols
// 07. Comparisons: equal and not equal
.EqualTo,
symbols
// 08. Bitwise AND
// 09. Bitwise exclusive OR (XOR)
// 10. Bitwise inclusive (normal) OR
// 11. Logical AND
.LogicalAnd,
symbols
// 12. Logical OR
.LogicalOr,
symbols
// 13. Conditional expression (ternary)
.Elvis,
symbols
// 14. Assignment operators (right to left)
.Assign,
symbols
// 15. Comma operator
}
func executeExpression(tree *ParserT, order symbols.Exp) (err error) {
for tree.astPos = 0; tree.astPos < len(tree.ast); tree.astPos++ {
:= tree.ast[tree.astPos]
node
if node.key < order {
continue
}
switch node.key {
// 15. Comma operator
// 14. Assignment operators (right to left)
case symbols.Assign:
= expAssign(tree, true)
err case symbols.AssignUpdate:
= expAssign(tree, false)
err case symbols.AssignAndAdd:
//err = expAssignAdd(tree)
= expAssignAndOperate(tree, _assAdd)
err case symbols.AssignAndSubtract:
= expAssignAndOperate(tree, _assSub)
err case symbols.AssignAndDivide:
= expAssignAndOperate(tree, _assDiv)
err case symbols.AssignAndMultiply:
= expAssignAndOperate(tree, _assMulti)
err case symbols.AssignOrMerge:
= expAssignMerge(tree)
err
// 13. Conditional expression (ternary)
case symbols.NullCoalescing:
= expNullCoalescing(tree)
err case symbols.Elvis:
= expElvis(tree)
err
// 12. Logical OR
case symbols.LogicalOr:
= expLogicalOr(tree)
err
// 11. Logical AND
case symbols.LogicalAnd:
= expLogicalAnd(tree)
err
// 10. Bitwise inclusive (normal) OR
// 09. Bitwise exclusive OR (XOR)
// 08. Bitwise AND
// 07. Comparisons: equal and not equal
case symbols.EqualTo:
= expEqualTo(tree)
err case symbols.NotEqualTo:
= expNotEqualTo(tree)
err case symbols.Like:
= expLike(tree, true)
err case symbols.NotLike:
= expLike(tree, false)
err case symbols.Regexp:
= expRegexp(tree, true)
err case symbols.NotRegexp:
= expRegexp(tree, false)
err
// 06. Comparisons: less-than and greater-than
case symbols.GreaterThan:
= expGtLt(tree, _gtF, _gtS)
err case symbols.GreaterThanOrEqual:
= expGtLt(tree, _gtEqF, _gtEqS)
err case symbols.LessThan:
= expGtLt(tree, _ltF, _ltS)
err case symbols.LessThanOrEqual:
= expGtLt(tree, _ltEqF, _ltEqS)
err
// 05. Bitwise shift left and right
// 04.1 Merge
case symbols.Merge:
= expMerge(tree)
err
// 04. Addition and subtraction
case symbols.PlusPlus:
= expPlusPlus(tree, 1)
err case symbols.MinusMinus:
= expPlusPlus(tree, -1)
err case symbols.Add:
= expAdd(tree)
err case symbols.Subtract:
= expSubtract(tree)
err
// 03. Multiplication, division, modulo
case symbols.Multiply:
= expMultiply(tree)
err case symbols.Divide:
= expDivide(tree)
err
// 02. (most) unary operators, sizeof and type casts (right to left)
// 01. Function call, scope, array/member access
default:
= raiseError(tree.expression, node, 0, fmt.Sprintf(
err "no code written to handle symbol (%s)",
.IssueTrackerURL))
consts}
if err != nil {
return err
}
.astPos = 0
tree}
return nil
}
open
):
Open a file with a preferred handlerout
):
Print a string to the stdout with a trailing new line character%[]
Array
Builder: Quickly generate arrays%{}
Object
Builder: Quickly generate objects (dictionaries / maps)*=
Multiply By
Operator: Multiplies a variable by the right hand value
(expression)*
Multiplication
Operator: Multiplies one numeric value with another
(expression)+=
Add With
Operator: Adds the right hand value to a variable (expression)+
Addition
Operator: Adds two numeric values together (expression)-=
Subtract By
Operator: Subtracts a variable by the right hand value
(expression)-
Subtraction
Operator: Subtracts one numeric value from another (expression)/=
Divide By
Operator: Divides a variable by the right hand value
(expression)/
Division
Operator: Divides one numeric value from another (expression)<~
Assign Or
Merge: Merges the right hand value to a variable on the left hand
side (expression)?:
Elvis Operator:
Returns the right operand if the left operand is falsy (expression)??
Null
Coalescing Operator: Returns the right operand if the left operand
is empty / undefined (expression)This document was generated from builtins/core/expressions/expressions_doc.yaml.
This site's content is rebuilt automatically from murex's source code after each merge to the master
branch. Downloadable murex binaries are also built with the website.
Last built on Wed Jan 15 23:07:50 UTC 2025 against commit b4c4296b4c429617fd41527ea0efef33c52c15ef2b64972.
Current version is 6.4.2063 (develop) which has been verified against tests cases.