The include system imports Expr code from another file at parse time.
Use includes for reusable functions, classes, constants, and shared script libraries.
Syntax:
include 'MyMath.expr'
The included file is parsed and inserted into the current program.
Example library file:
// MyMath.expr function Add(a, b) { return a + b; } function Sub(a, b) { return a - b; }
Using it:
include 'MyMath.expr' print(Add(2, 3)); print(Sub(8, 5));
An include statement can be followed by a semicolon, but it does not require one:
include 'MyMath.expr'; include 'Other.expr'
`include` is a top-level statement.
It is valid at the top level of a script:
include 'Library.expr' result = LibraryValue();
It is not valid inside blocks, functions, or classes:
if (1) { include 'Library.expr' // error }
An include statement must start a statement. It cannot be used as part of an expression.
Included code is parsed as if it appeared in the including script.
This means an included file can contain:
For library files, prefer function and class declarations only. Top-level statements in included files run each time the file is included.
Use `as` to import a file under a namespace alias.
include 'MyMath.expr' as MathLib print(MathLib::Add(2, 3));
With a namespaced include, top-level function and class declarations from the included file are placed into the alias namespace.
// MyMath.expr function Add(a, b) { return a + b; }
include 'MyMath.expr' as MathLib MathLib::Add(2, 3); // OK Add(2, 3); // error unless another Add exists
The alias after `as` is a namespace name, such as `MathLib`.
Namespaced includes also apply to class declarations.
// Tools.expr class ToolInfo(number, diameter) { Number = number; Diameter = diameter; function Radius() { return Diameter / 2; } }
include 'Tools.expr' as Tools tool = Tools::ToolInfo(3, 6.0); print(tool.Radius());
If an included class or function already has a namespace, the include alias is the namespace used for the imported definition.
The namespace alias applies to imported top-level function and class declarations.
It does not rewrite arbitrary top-level statements.
For example, this file is not a good candidate for aliased include:
// Init.expr value = Add(2, 3);
If it is included with an alias, the call expression is not rewritten to `Alias::Add(…)`.
Keep aliased include files definition-only unless you are deliberately executing top-level code.
Includes are not treated as `pragma once`.
Including the same file more than once is allowed.
Effects of duplicate include:
Example:
include 'MyMath.expr' as A include 'MyMath.expr' as B A::Add(1, 2); B::Add(1, 2);
Expr detects active recursive include chains.
If a file includes itself directly or indirectly while it is already being parsed, parsing fails with a recursive include error.
Example:
// A.expr include 'B.expr' // B.expr include 'A.expr' // recursive include error
Expr also limits include nesting depth. Include nesting deeper than 16 levels is rejected.
Include file names are strings.
include './lib/MyMath.expr' include 'LocalHelper.expr' include 'C:/PlanetCNC/scripts/MyMath.expr'
Path resolution is handled by the host path resolver.
General rules:
Use profile-relative include paths for shared profile libraries:
include './lib/probing/probe_job.expr' as Probe include './lib/atc/tool_change.expr' as ATC
Use source-relative include paths for helper files beside the current source script:
include 'probe_steps.expr' as Steps include '~/local_report.expr' as Report
Do not use `../lib/…` when you mean a library inside the profile folder. Because it starts with `.`, it resolves from the profile path and goes outside the profile folder.
Runtime path resolution uses the current source path and profile path from the host evaluation context.
A function or class method should use explicit profile-relative paths for shared profile assets:
function LoadLogo() { return image_data().load('./assets/images/logo.png'); }
Use paths without a leading dot for files that belong beside the current source script:
function LoadJobData() { return bytes().load('job_data.csv'); }
Included files are parsed with strict default Expr parsing options.
They do not inherit caller compatibility options enabled by a host context, such as:
Write include files using normal Expr syntax.
For reusable libraries:
Example:
include './lib/Geometry.expr' as Geometry area = Geometry::CircleArea(10);
Previous: Classes and user-defined objects
Next: Error model