This page defines the basic text rules used by Expr source code: character encoding, whitespace, comments, identifiers, literals, and statement terminators.
Lexical rules are the rules used before Expr evaluates a script. They describe how source text is split into keywords, names, numbers, strings, operators, and punctuation.
Expr scripts are plain text.
Use UTF-8 for script files.
Practical rules:
Example:
message = 'Hello'; print(message);
Identifier parsing is oriented toward ASCII letters, digits, and underscore. Non-ASCII identifier names are not recommended.
Use this:
toolName = 'End mill';
Avoid this:
toolName = 'End mill'; // OK, ASCII identifier tool-count = 10; // not valid, '-' is an operator
Whitespace is ignored between tokens.
The following can be used for formatting:
These scripts are equivalent:
a=1+2;
a = 1 + 2;
a = 1 + 2;
A newline is not a statement terminator by itself. Statements normally end with `;`.
This is valid:
a = 10; b = 20;
This is not valid as two statements:
a = 10 b = 20;
The first statement is missing `;`.
Expr supports line comments.
A line comment starts with // and continues to the end of the line.
// this is a comment a = 10; // trailing comment
Comments are ignored by the parser.
Block comments are not part of Expr syntax:
/* not supported */
//= is a special host-integration form when modifiable-comment mode is enabled.
It is not ordinary comment syntax for normal Expr scripts. Use the host-specific documentation for places where //= is supported.
Identifiers are names used for variables, functions, classes, parameters, and methods.
Standard identifier form:
[A-Za-z_][A-Za-z0-9_]*
This means:
Valid identifiers:
speed _state Tool1 ProbeResult
Invalid identifiers:
1abc // starts with a digit tool-name // '-' is an operator feed rate // space separates tokens
Identifier names are case-sensitive.
speed = 100; Speed = 200;
`speed` and `Speed` are different names.
Namespace-qualified names use `::`.
Math::Add(2, 3);
This calls `Add` from the `Math` namespace.
Namespaces are commonly used with included files:
include 'MyMath.expr' as MyMath result = MyMath::Add(2, 3);
See Include system for exact include behavior.
Member access and method calls use `.`.
Object or value method call:
object.MethodName(arg1, arg2);
Examples:
'hello'.upper(); (255).to_hex(); tool.Radius();
Property read:
tool.Number;
Direct property assignment from outside an object is not supported:
tool.Number = 2; // not supported
Use object methods to change object state.
When Expr is called from G-code expression evaluation, the host can enable hash-variable compatibility mode.
In this mode, G-code variable and parameter syntax is accepted as Expr variable syntax:
#123 #name #<name>
This allows Expr variables and G-code parameters to refer to the same names in that context.
Hash variables are G-code compatibility syntax. They are not normal standalone Expr style. For regular Expr scripts, prefer normal identifiers:
toolNumber = 3; feedRate = 1200;
Keywords are reserved words recognized by the parser.
Expr keywords include:
if else loop while for return break continue include set function class true false
`as` is used as a contextual keyword in include statements:
include 'MyMath.expr' as MyMath
Do not use keywords as ordinary variable, function, or class names.
Number literals represent numeric values.
Integer and decimal examples:
10 3.14 0.5 -0.5
Exponent examples:
1e3 // 1000 -2.5e-2 // -0.025
The minus sign is parsed as part of the numeric expression where appropriate. In more complex expressions, it behaves as the unary minus operator.
a = -10; b = 5 * -2; c = 5 - 2;
Hexadecimal and binary numeric forms are supported by the numeric parser where accepted by the runtime.
String methods can also parse numeric text explicitly:
'FF'.parse_hex(); '1010'.parse_bin();
Boolean literals are:
true false
Example:
enabled = true; if(enabled) { print('enabled'); };
Boolean values are described in Type system.
String literals can be quoted with double quotes, single quotes, or backticks.
s1 = "Hello"; s2 = 'World'; s3 = `Text`;
Escape sequences are processed by the runtime in normal quoted strings.
Common examples include:
line = 'first\nsecond'; tabbed = 'a\tb'; quote1 = 'It\'s OK'; quote2 = "He said \"OK\"";
Use whichever quote style makes the string easiest to read.
text1 = 'He said "OK"'; text2 = "It's OK";
Backtick strings are useful when the text contains both single and double quotes.
text = `He said "it's OK"`;
Triple double-quoted strings use """ as the opening and closing delimiter.
They are useful for multiline text, templates, and messages where normal quoting would be hard to read.
text = """ line 1 line "2" line 3 """;
The value of `text` is:
line 1 line "2" line 3
If the opening """ is followed immediately by a newline, that first newline is omitted from the string value. This lets the content start on the next line without adding an empty first line.
Triple double-quoted strings are raw strings. Escape sequences are not processed inside them.
text = """ first\nsecond """;
The `\n` remains backslash plus `n`; it does not become a newline escape. Actual line breaks in the source text are preserved.
A triple double-quoted string ends at the next """ sequence. If you need to include that exact sequence in the text, build the string from smaller strings instead.
Most expressions and statements must end with `;`.
a = 10; b = a + 5; print(b);
Inside `{ … }` blocks, regular expression statements still require `;`.
if(a > 0) { b = 1; print(b); };
A semicolon is not required after some block-style statements, but it is accepted.
Examples:
if(a > 0) { b = 1; }
function Add(x, y) { return x + y; }
class MyClass() { function Ping() { return 1; } }
include 'MyMath.expr'
For consistency in tutorial-style code, using a semicolon after block expressions is often clearer when the block is used as a value or statement in a larger script.
result = if(a > 0) { 'positive'; } else { 'not positive'; };
Recommended style for readable Expr code:
Example:
function Clamp(value, low, high) { if(value < low) { return low; }; if(value > high) { return high; }; return value; }
Next: Type system