exprv4:reference:lexical_basics



Lexical Basics

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.


Character Set and Encoding

Expr scripts are plain text.

Use UTF-8 for script files.

Practical rules:

  • Keep language tokens in ASCII.
  • Use ASCII for keywords, operators, identifiers, punctuation, and file syntax.
  • Non-ASCII text is fine inside string literals.

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 and Newlines

Whitespace is ignored between tokens.

The following can be used for formatting:

  • spaces
  • tabs
  • newlines

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 `;`.


Comments

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 */

Modifiable Comments

//= 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

Identifiers are names used for variables, functions, classes, parameters, and methods.

Standard identifier form:

[A-Za-z_][A-Za-z0-9_]*

This means:

  • the first character must be a letter or underscore
  • later characters may be letters, digits, or underscore

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.


Namespaces

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

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.


G-code Hash Variables Compatibility Mode

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

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

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

Boolean literals are:

true
false

Example:

enabled = true;
 
if(enabled)
{
    print('enabled');
};

Boolean values are described in Type system.


String Literals

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

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.


Statements and Semicolons

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);
};

Block-Style Statements

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';
};

Practical Style

Recommended style for readable Expr code:

  • Use UTF-8 files.
  • Use ASCII identifiers.
  • End normal statements with `;`.
  • Put one statement per line.
  • Use spaces around operators.
  • Use `{ … }` blocks for `if`, loops, functions, and classes.
  • Use comments to explain intent, not every individual operation.

Example:

function Clamp(value, low, high)
{
    if(value < low)
    {
        return low;
    };
 
    if(value > high)
    {
        return high;
    };
 
    return value;
}

Next: Type system

exprv4/reference/lexical_basics.txt · Last modified: by 127.0.0.1

Page Tools