PSScript Docs / Reference
Language reference
Everything the parser and virtual machine accept: lexical rules, values, variables, operators, control flow and structured error handling.
On this page
Literals
| Type | Examples | Notes |
|---|---|---|
Int |
0, 42, 100 |
64-bit signed integer. |
Float |
2.45, 149.99 |
64-bit double; a literal is a float as soon as it contains a . |
String |
"Hello" |
Double-quoted; may not span lines. |
Bool |
true, false |
|
Null |
null |
The absent / empty value. |
Map |
{} |
An empty map literal; fill it via indexed assignment. |
String escapes
Inside a string literal the backslash introduces these escapes:
| Escape | Produces |
|---|---|
\n | newline |
\t | tab |
\\ | backslash |
\" | double quote |
\{ \} | literal braces (useful next to {} log placeholders) |
Variables
Declare a local with var. Variables are block-scoped to the main or rollback body and are dynamically typed — a name simply holds whatever value was last assigned to it.
var token = util$.uuid();
var total = 149.99;
var summary = {}; // empty map
total = total + 10; // reassignmentMaps & indexing
A map is a string-keyed collection. Create one with {}, then read and write members with the index operator [ ]. Reading a missing key yields null. Integer keys are coerced to their string form.
var item = {};
item["name"] = "Pencil";
item["price"] = 2.45;
context$.log("name = {}", item["name"]); // Pencil
context$.log("qty = {}", item["qty"]); // null (absent)Indexing chains for nested data, for example reading nested input parameters:
context$.log("A.B = {}", param$["A"]["B"]);Operators
Arithmetic
+ - * / operate on numbers. Two integers produce an integer (integer division for /); if either side is a float the result is a float. Dividing an integer by 0 raises a runtime error. Arithmetic on non-numbers is an error.
Comparison
< > <= >= compare two numbers and yield a Bool. Comparing non-numbers is an error.
Equality
== and != work across scalar types. Numbers compare by value (1 == 1.0 is true); strings, booleans and null compare structurally. Mismatched kinds (e.g. a string and a number) are simply not equal rather than an error — this makes the common x == null guard safe on any value.
if (model == null) {
model = PSEntity(className);
model.identifier(idn);
}Truthiness
Conditions in if and for are evaluated for truthiness: null and false are falsy; every other value is truthy (including 0 and empty strings).
Control flow
if
A condition in parentheses followed by a block. The block runs when the condition is truthy.
if (count > 100) {
router$.allow("bulk_connector");
}for
A C-style counted loop: initializer, condition, update, then a body.
for (var i = 0; i < 50; i = i + 1) {
var e = PSEntity("com.paradicshift.test.GISTempData");
e.identifier("GIS-TEMP-%s".formatted(util$.uuid()));
data$.persist(e);
}Error handling
Wrap fallible work in try. A runtime error inside the try block jumps to catch, binding the error message (a string) to the named variable. A finally block, if present, always runs last — on success, on a caught error, or while an uncaught error propagates.
try {
context$.log("Starting risky step.");
data$.persist({}); // throws: not an entity
context$.log("skipped on error");
} catch (err) {
context$.log("The step failed: {}", err);
output$["status"] = "handled";
} finally {
context$.log("Cleanup always runs.");
}String methods
Strings carry two built-in methods.
.replace(from, to)
Returns a copy with every occurrence of from replaced by to.
var s = "Hello {a}";
context$.log("{}", s.replace("{a}", "abc")); // Hello abc.formatted(args…)
A printf-style formatter. Each specifier consumes the next argument in order:
| Specifier | Meaning |
|---|---|
%s | value as a string |
%S | value as an upper-cased string |
%d | integer (a whole-valued float is accepted) |
%f | number (int or float) |
%b | true / false by truthiness |
%% | a literal percent sign |
var url = "%s/icons/%s.svg".formatted(baseURL, name);
e.gis("location", "POINT(%f %f)".formatted(lon, lat));
Comments
Both C-style comment forms are supported and ignored by the lexer: