Expressions and operators
Arithmetic/concatenation operators
| Operator | Use |
|---|---|
+ | Numeric addition between Numbers, or concatenation between char/varchar (depending on the operand types). |
- | Numeric subtraction. |
* | Numeric multiplication. |
/ | Numeric division. |
&Total = &Price * &Quantity
&Greeting = "Hello, " + &Username
Comparison operators
=, <>, <, <=, >, >= — used in Where, If, While.
Logical operators
And/Or combine comparisons (typically in If/While): And binds tighter than Or. Not expr negates a condition.
If &a = 1 And &b = 2 Or &c = 3
...
EndIf
Not (logical negation)
Not expr inverts the condition that follows it. It is a reserved word, like And and Or.
Precedence, from lowest to highest: Or, And, Not, comparisons. That is, Not binds looser than a comparison and tighter than And:
// Not &a = 1 And &b = 2 reads as (Not (&a = 1)) And (&b = 2)
If Not &a = 1 And &b = 2
...
EndIf
To negate a compound condition, use parentheses: Not (&a = 1 Or &b = 2).
Not can also be used in @Layout conditions (see @Layout: conditions).
WARP has no boolean type of its own: each operand is validated like any other expression.
Implicit line continuation
In @Source, an expression or statement can span several lines without any special character. The line break is ignored in these cases:
- After an operator:
+ - * /, the comparisons= <> < <= > >=,And,Or,Not, and after the=of an assignment. - Inside parentheses: after
(, after each,and before). This applies to function or builtin calls (DateAdd(…)),Do Proc(...),Call(...),Message(...),Member(...),Export(...),Procedure/Functionparameter lists and parenthesized expressions. And/Orat the start of the next line also continue the condition.
&text = "one" +
"two"
&d = DateAdd(
&d,
1,
Days
)
If &n > 1
And &n < 10
...
EndIf
Additional rules:
- An arithmetic or comparison operator at the start of the next line (for example
+ "two") is still an error (E00008), because it would be ambiguous. - A line cannot be continued in the middle of an identifier or a text literal.
//comments between continued lines are ignored.- Diagnostic line numbers remain the real ones.
Literals
- Numbers:
100,9.5. - Text:
"text"or'text'(equivalent). - Date/time: obtained via
TODAY()/TIME(), there’s no date literal.
Variables and fields
- Variable: always with
&(&Username). - Table field: without
&, only inside aFor Each/Newover that table (CustCode,Name). list/matrixelement:&Variable[index]/&Variable[row, col](1-based).listmethod:&Variable.Method(...)(Add/Clear/Init/Removeas a statement,Count()as an expression) — see Data types: List.Json()method ofstruct,list(struct(...))and scalarlist(list(char),list(number),list(date),list(time),list(timestamp); the result is a JSON array, e.g.["a","b"]or[1,2])- Statement
JsonSplit(&json, &list[, indent]): splits a JSON into lines — see JsonSplit. - Fixed-width records: expression
&rec.FixedWidth()and statements&rec.FromFixedWidth(&text),FixedWidthSplit(&records, &lines),FixedWidthParse(&lines, &records)— see Fixed-width records. structmember:&Variable.Member(read and assignment); with nested structs, by path:&Variable.Cab.Member,&Variable.Cab.List.Add(&row),&Variable.Cab.List[1]— see Data types: Struct.
Function/procedure calls as an expression
&variable = FunctionName(expr, ...)
See Builtin functions and @Source: control statements for your own Functions.