PSScript Docs / Reference

Language reference

Everything the parser and virtual machine accept: lexical rules, values, variables, operators, control flow and structured error handling.

Comments

Both C-style comment forms are supported and ignored by the lexer:

// line comment — runs to end of line

/* block comment
   spanning multiple lines */

Literals

TypeExamplesNotes
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:

EscapeProduces
\nnewline
\ttab
\\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;        // reassignment
Statements end with ; Every declaration, assignment and call statement is terminated by a semicolon.

Maps & 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");
}
No else clause PSScript has no else. Express alternatives with a second if on the inverse condition.

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.");
}
Rule A try must be followed by a catch block, a finally block, or both. The catch variable holds the error text formatted as runtime: … or host error: …

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:

SpecifierMeaning
%svalue as a string
%Svalue as an upper-cased string
%dinteger (a whole-valued float is accepted)
%fnumber (int or float)
%btrue / 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));
Two ways to interpolate context$.log() uses positional {} placeholders; .formatted() uses typed % specifiers. Reach for .formatted() whenever you need the formatted string as a value.