Expressions¶
MWorks’ expression language should feel familiar to anyone who has used programming or scripting languages before. The following sections describe it in detail.
Literals¶
The expression parser recognizes literal values for a variety of data types.
Data Type 
Examples 
Notes 

Boolean 
true
false
YES
NO

Not casesensitive 
Integer 
1
+123
4567


Floating point 
1.0
1.
.1
0.1
+0.1
1.2e10


String 
''
"foo"
'bar'
"Hello, world!"

Supports variable and expression interpolation and some C/C++ escape sequences 
List 
[]
[1.5]
[1, 2.5, 'foo']
[1:10]
[1,2,3:6,7,8:10]

Can include range expressions 
Dictionary 
{}
{'foo': 1.5}
{'a': 1, true: 2.5, 3.5: 'foo'}

Operators¶
The expression parser supports a number of mathematical, logical, comparison, and other operators.
Description 
Operator 
Alternative Form(s) 
Example 
Precedence 

Unit operators (postfix) 

Microseconds 


1 

Milliseconds 


1 

Seconds 


1 

Element access operators 

Subscript 


2 

Unary operators (prefix) 

Positive 


3 

Negative 


3 

Logical “not” 



3 
Type conversion operators (prefix) 

Boolean 


4 

Integer 



4 
Floating point 



4 
String 


4 

Binary operators 

Multiplication 


5 

Division 


5 

Modulus (remainder) 


5 

Addition 


6 

Subtraction 


6 

Equality 



7 
Inequality 


7 

Less than 



7 
Less than or equal 



7 
Greater than 



7 
Greater than or equal 



7 
Logical “and” 



8 
Logical “or” 



9 
Note that the unit operators and the plainEnglish logical operators (not
, and
, and or
) are not casesensitive. However, the typeconversion operators and all operators that begin with #
(#LT
, #AND
, etc.) are casesensitive.
Also, be aware that the division operator (/
) always produces a floatingpoint result, even if both of its operands are integers. For example, 1/2
evaluates to 0.5, not 0 (as it does in some programming languages).
Units¶
Since MWorks does not provide true support for quantities with associated units, the unit operators are simply shorthand for multiplication operations. In the case of time units (us
, ms
, and s
), the operators multiply by a factor suitable for converting to microseconds (1, 1000, and 1000000, respectively).
Subscripting¶
If the expression exp
evaluates to a list, then exp[n]
returns the element at index n. If n is out of bounds, the expression evaluates to zero, and the parser issues an error message. (Note that the first element of a list is at index 0, not 1.)
If the expression exp
evaluates to a dictionary, then exp[k]
returns the value associated with key k in the dictionary. If the dictionary has no matching key, the expression evaluates to zero, and the parser issues an error message.
Precedence¶
The above table lists the operators from highest precedence (1) to lowest precedence (9). Operator precedence determines the order of operations in expressions, as higherprecedence operations are evaluated before lowerprecedence ones.
The order of operations can be altered by wrapping subexpressions in parentheses, which have higher precedence than all other operators. For example, *
has higher precedence than +
, so 1+2*3
evaluates to 7, but (1+2)*3
evaluates to 9.
Ranges¶
A range expression is a compact representation of an evenlyspaced, ordered sequence of integers.
The general form of a range expression is start:stop:step, where start, stop, and step are expressions that evaluate to integers. step is optional. If provided, it must evaluate to a positive integer; if omitted, it defaults to 1. If start is less than stop, the sequence will be increasing; otherwise, it will be decreasing. start is always included in the sequence. If start and stop are separated by a multiple of step, stop will be included as well.
List literals, function calls, and selection variable value lists can all incorporate range expressions. In all cases, range expressions can be mixed with other expressions, so long as all items are separated by commas.
The following table shows some examples of range expression usage, with equivalent, rangeexpressionfree versions shown alongside.
Expression 
Equivalent 













Variables¶
MWorks variables can be incorporated into expressions by referencing each variable by its name. For example, if your experiment defines two variables, x
and y
, which hold the values 1 and 2, respectively, then the expression 3*x+y
will evaluate to 5.
Variable names are casesensitive, so myvar
, MYVAR
, and MyVar
all refer to different variables.
Selection¶
When used in an expression, a selection variable evaluates to the currentlyselected value. If no selections have been made on the variable, the first one is made automatically, and its value is returned.
Timer¶
MWorks timers are implemented as variables. When used in an expression, the name of a timer evaluates to true if the timer has expired, false otherwise.
Note: timer_expired
(see TimeRelated functions below) actually just passes its input value unchanged. However, using it may help to clarify the intent of an expression.
Variable and Expression Interpolation¶
A string literal can incorporate the value of one or more variables via variable interpolation. When a string literal containing placeholder text of the form $var
or ${var}
is evaluated, the placeholder is replaced with the current value of variable var
(converted to a string). For example:
var greeting = 'Hello'
var subject = 'World'
var message = '$greeting, ${subject}!' // message contains "Hello, World!"
To inhibit variable interpolation, preface the dollar sign with a backslash:
var text = '123\$abc' // text contains "123$abc"
A string literal may also incorporate the value of one or more expressions via expression interpolation. When a string literal containing placeholder text of the form $(expr)
is evaluated, the placeholder is replaced with the result of evaluating the expression, converted to a string. For example:
message = '1 + 2 = $(1 + 2)' // message contains "1 + 2 = 3"
text = '$(round(pi())) is a magic number' // text contains "3 is a magic number"
As with variable interpolation, expression interpolation can be inhibited by prefacing the dollar sign with a backslash:
text = '123\$abc\$(whee!)' // text contains "123$abc$(whee!)"
Functions¶
The expression parser recognizes a number of predefined functions, many of which are found in other programming or scripting languages. Note that function names are not case sensitive, so now()
, NOW()
, and Now()
are all equivalent.
Mathematical¶
abs(x)
Absolute value of x
acos(x)
Arc cosine of x (in radians)
asin(x)
Arc sine of x (in radians)
atan(x)
Arc tangent of x (in radians)
atan2(y,x)
Arc tangent of y/x (in radians), using the signs of the arguments to determine the correct quadrant
ceil(x)
Nearest integer not less than x
cos(x)
Cosine of x (measured in radians)
exp(x)
Euler’s number (e) raised to the power x
floor(x)
Nearest integer not greater than x
fmod(x,y)
Floatingpoint remainder of x/y
logn(x)
Natural logarithm of x
max(x,y)
Larger of x and y
min(x,y)
Smaller of x and y
pi()
The constant 𝜋
pow(x,y)
x raised to the power y
round(x)
Nearest integer to x. Number is rounded away from zero in halfway cases.
sin(x)
Sine of x (measured in radians)
sqrt(x)
Square root of x
tan(x)
Tangent of x (measured in radians)
Random Number Generators¶
rand()
Random floatingpoint value uniformly distributed in the range [0..1)
rand(min,max)
Random floatingpoint value uniformly distributed in the range [min..max)
disc_rand(min,max)
Random integer value uniformly distributed in the set of integer numbers {min, min+1, min+2, …, max}
geom_rand(prob,max)
Discrete random number sampled in the interval [0, max] from a geometric distribution with constant Bernoulli probability prob
exp_rand(beta,min,max)
Random number from exponential distribution with mean beta+min, optionally truncated at max. min and max are both optional and default to zero and positive infinity, respectively.
Other¶
date(fmt)
Returns the current date/time as a string, formatted according to format string fmt. The format string can contain any of the conversion specifiers supported by strftime, as well as arbitrary text.
display_bounds()
Returns a dictionary containing the bounds (in degrees) of the default stimulus display (if available). The keys in the dictionary are the strings “left”, “right”, “bottom”, and “top”.
display_bounds('disp')
Given the name of a stimulus display (as a string), returns a dictionary containing the bounds (in degrees) of the display. The keys in the dictionary are the strings “left”, “right”, “bottom”, and “top”.
display_bounds(edge)
Given one of the strings “left”, “right”, “bottom”, or “top”, returns the corresponding boundary (in degrees) of the default stimulus display (if available)
display_bounds('disp', edge)
Given the name of a stimulus display (as a string) and one of the strings “left”, “right”, “bottom”, or “top”, returns the corresponding boundary (in degrees) of the display
filenames(glob_expr)
Given glob_expr, a string containing a shellstyle file name pattern, returns a list of strings containing the names of all matching files (or any empty list, if no files match)
format(fmt,...)
printfstyle string formatting. fmt is the format string, and any subsequent arguments are items to be formatted.
num_accepted('sel')
Takes the name of a selectable object (as a string) and returns the number of accepted selections that have been made on it
osname()
Name of the current operating system as a string (e.g. “macos”, “ios”)
py_call(expr,...)
Evaluates expr as a Python expression, calls the resulting Python object with the remaining arguments, and returns the result. If a Python error occurs, logs the error message and returns 0.
py_eval(expr)
Evaluates expr as a Python expression and returns the result. If a Python error occurs, logs the error message and returns 0.
selection('sel',n)
Takes the name of a selection variable (as a string) and an integer n and returns the nth tentative (i.e. nonaccepted) selection on the variable
size(x)
Size of x: number of characters in a string, number of elements in a list or dictionary, 0 otherwise
type(x)
Data type of x as a string (“boolean”, “integer”, “float”, “string”, “list”, or “dictionary”)