-
Notifications
You must be signed in to change notification settings - Fork 0
Language Guide
This guide documents RuleScript language behavior for the current stable v1.10.0 line.
- Identifiers and function names are case-sensitive.
- Simple statements end with
;. - Block headers end with
:. -
endcan close most blocks; dedicated endings such asendif,endfunction,endtask, andendparallelremain valid. -
//starts a single-line comment. -
/* ... */creates a multi-line comment. -
///creates documentation metadata for the next function. -
#regionand#endregioncreate editor folding regions.
// A comment
var distance = 519;
result = distance + 1;
RuleScript supports:
| Value | Example |
|---|---|
| number |
10, 2.5, -3
|
| string |
"RuleScript", "Line 1\nLine 2"
|
| boolean |
true, false
|
| null | null |
| array | [1, "two", true] |
| object | { Status: "OK", Position: { X: 519 } } |
Strings use double quotes. Supported escapes are \", \\, \n, \r, and \t.
Arrays are mutable list values. Indexes are zero-based and must be whole-number values within bounds.
Object properties can be read from dictionaries, read-only dictionaries, object literals, JSON values, and public C# object properties:
var robot = { status: "OK", position: { x: 519 } };
var status = robot.status;
var x = robot.position.x;
value?.property returns null when the receiver is null. Missing properties and null member access without ?. are runtime errors.
var distance = 519;
var result;
const threshold = 500;
distance = distance + 1;
result = distance > threshold;
const creates a read-only binding. Assignments can target variables, array elements, object members, nested targets, mutable dictionaries, and writable host-object properties:
var robot = { position: { x: 0 }, samples: [1, 2] };
robot.position.x = 519;
robot.samples[0] = 42;
Destructuring declares multiple variables:
var [first, second] = [10, 20];
var { name, enabled } = { name: "RuleScript", enabled: true };
Top-level variables live in RuntimeContext. Inside a function, normal assignments write to local scope. Use global.name for explicit shared context access:
var count = 0;
function Increment() -> void:
global.count = global.count + 1;
return;
endfunction
From highest to lowest precedence:
| Precedence | Operators |
|---|---|
| 1 | () |
| 2 |
!, unary -
|
| 3 |
*, /, %
|
| 4 |
+, -
|
| 5 |
>, >=, <, <=
|
| 6 |
==, !=
|
| 7 | and |
| 8 | or |
| 9 | ?? |
+ performs numeric addition when both operands are numbers and string concatenation when either side is a string. and, or, and ! require boolean operands. left ?? right evaluates the right side only when the left side is null.
if distance > 500 then:
result = "NG";
elseif distance == 500 then:
result = "EDGE";
else:
result = "OK";
endif
switch status:
case "ok":
result = "Continue";
case "warning", "error" when retryCount <= 3:
result = "Inspect";
case null:
result = "Missing";
default:
result = "Unknown";
endswitch
switch selects the first matching case and does not fall through. default is optional but analysis reports a warning when omitted.
var i = 0;
while i < 5:
i = i + 1;
endwhile
foreach item in [1, 2, 3]:
if item == 2 then:
continue;
endif
if item > 10 then:
break;
endif
endforeach
foreach supports lists, arrays, IEnumerable<object?>, and strings. break and continue apply to the nearest loop.
Functions are declared at top level. v1.10.0 supports both classic untyped functions and strongly typed signatures.
function Add(left: number, right: number) -> number:
return left + right;
endfunction
function Log(message: string) -> void:
Print(message);
return;
endfunction
Supported type names are any, null, number, string, bool, boolean, array, object, and void.
Rules:
- Parameters and
vardeclarations are local. -
return expression;returns a value. -
return;returns null and is required forvoidfunctions that return explicitly. - A non-void typed function must return a compatible value on every path.
- Overloads may share a name when parameter signatures differ.
- Return type does not participate in overload resolution.
- Recursion is intentionally blocked.
import "common";
import "robot" as robot;
result = Shared();
status = robot.GetStatus();
Imports are top-level only. Extensionless paths use RuleScriptEngine.ScriptFileExtension, .rules by default. Imported files may contain imports and declarations, but not top-level executable statements.
Use export function and export const to define a module's public surface:
export const DefaultLimit = 500;
export function IsHigh(value: number) -> bool:
return value > DefaultLimit;
endfunction
Once a module contains any explicit export, unmarked declarations are private.
A parallel expression returns task results in declaration order:
var values = parallel:
task:
return LoadA();
endtask
task:
return LoadB();
endtask
endparallel;
A statement-form block runs concurrent work without collecting a result:
parallel:
task:
SaveA();
endtask
task:
SaveB();
endtask
endparallel
Host Functions called from ordinary task blocks must be registered as thread-safe. Task-local variables and function call stacks are isolated; RuntimeContext is shared and synchronized.
Host Trigger is v1.10.0's long-running runtime syntax.
@HostTrigger("LotArrived")
function OnLotArrived(lotId: string) -> void:
Print("lot arrived: " + lotId);
return;
endfunction
parallel:
trigger task:
dispatch;
endtask
endparallel
@HostTrigger("Name") marks a user function as callable by the host through RuleScriptRuntime.TriggerAsync. A trigger task is only valid directly inside parallel. dispatch; waits for one queued host trigger request, invokes the matching trigger function, and then the trigger task continues waiting.
See Host Trigger for runtime lifecycle details.
var payload = JsonParse("{ \"robot\": { \"status\": \"OK\" }, \"items\": [1, 2, 3] }");
var status = payload.robot.status;
var second = payload.items[1];
if JsonExists(payload, "robot.status") then:
result = JsonGet(payload, "robot.status");
endif
JSON objects become dictionaries, arrays become lists, and numbers become decimal values. JsonSet mutates existing dictionaries or lists in place.
RuleScript does not include package management, generics, lambdas, delegates, language-level async / await, locks, channels, task handles, or fire-and-forget execution.