Painless Language Specification
Painless is a scripting language designed for security and performance. Painless syntax is similar to Java syntax along with some additional features such as dynamic typing, Map and List accessor shortcuts, and array initializers. As a direct comparison to Java, there are some important differences, especially related to the casting model. For more detailed conceptual information about the basic constructs that Painless and Java share, refer to the corresponding topics in the Java Language Specification.
Painless scripts are parsed and compiled using the ANTLR4 and ASM libraries. Scripts are compiled directly into Java Virtual Machine (JVM) byte code and executed against a standard JVM. This specification uses ANTLR4 grammar notation to describe the allowed syntax. However, the actual Painless grammar is more compact than what is shown here.
Comments
Use a comment to annotate or explain code within a script. Use the //
token
anywhere on a line to specify a single-line comment. All characters from the
//
token to the end of the line are ignored. Use an opening /
token and a
closing /
token to specify a multi-line comment. Multi-line comments can
start anywhere on a line, and all characters in between the /
token and /
token are ignored. A comment is included anywhere within a script.
Grammar
SINGLE_LINE_COMMENT: '//' .*? [\n\r];
MULTI_LINE_COMMENT: '/*' .*? '*/';
Examples
-
Single-line comments.
// single-line comment int value; // single-line comment
-
Multi-line comments.
/* multi- line comment */ int value; /* multi- line comment */ value = 0; int value; /* multi-line comment */ /* multi-line comment */ int value; int value; /* multi-line comment */ value = 0; int value; /* multi-line comment */ value = 0;
Keywords
Keywords are reserved tokens for built-in language features.
Errors
-
If a keyword is used as an identifier.
Keywords
if |
else |
while |
do |
for |
in |
continue |
break |
return |
new |
try |
catch |
throw |
this |
instanceof |
Literals
Use a literal to specify a value directly in an operation.
Integers
Use an integer literal to specify an integer type value in decimal, octal, or
hex notation of a primitive type int
, long
, float
,
or double
. Use the following single letter designations to specify the
primitive type: l
or L
for long
, f
or F
for float
, and d
or D
for double
. If not specified, the type defaults to int
. Use 0
as a prefix
to specify an integer literal as octal, and use 0x
or 0X
as a prefix to
specify an integer literal as hex.
Grammar
INTEGER: '-'? ( '0' | [1-9] [0-9]* ) [lLfFdD]?;
OCTAL: '-'? '0' [0-7]+ [lL]?;
HEX: '-'? '0' [xX] [0-9a-fA-F]+ [lL]?;
Examples
-
Integer literals.
0 (1) 0D (2) 1234L (3) -90f (4) -022 (5) 0xF2A (6)
-
int 0
-
double 0.0
-
long 1234
-
float -90.0
-
int -18
in octal -
int 3882
in hex
-
Floats
Use a floating point literal to specify a floating point type value of a
primitive type float
or double
. Use the following
single letter designations to specify the primitive type: f
or F
for float
and d
or D
for double
. If not specified, the type defaults to double
.
Grammar
DECIMAL: '-'? ( '0' | [1-9] [0-9]* ) (DOT [0-9]+)? EXPONENT? [fFdD]?;
EXPONENT: ( [eE] [+\-]? [0-9]+ );
Examples
-
Floating point literals.
0.0 (1) 1E6 (2) 0.977777 (3) -126.34 (4) 89.9F (5)
-
double 0.0
-
double 1000000.0
in exponent notation -
double 0.977777
-
double -126.34
-
float 89.9
-
Strings
Use a string literal to specify a String
type value with
either single-quotes or double-quotes. Use a \"
token to include a
double-quote as part of a double-quoted string literal. Use a \'
token to
include a single-quote as part of a single-quoted string literal. Use a \\
token to include a backslash as part of any string literal.
Grammar
STRING: ( '"' ( '\\"' | '\\\\' | ~[\\"] )*? '"' )
| ( '\'' ( '\\\'' | '\\\\' | ~[\\'] )*? '\'' );
Examples
-
String literals using single-quotes.
'single-quoted string literal' '\'single-quoted with escaped single-quotes\' and backslash \\' 'single-quoted with non-escaped "double-quotes"'
-
String literals using double-quotes.
"double-quoted string literal" "\"double-quoted with escaped double-quotes\" and backslash: \\" "double-quoted with non-escaped 'single-quotes'"
Characters
Character literals are not specified directly. Instead, use the
cast operator to convert a String
type value
into a char
type value.
Identifiers
Errors
If a keyword is used as an identifier.
Grammar
ID: [_a-zA-Z] [_a-zA-Z-0-9]*;
Examples
-
Variations of identifiers.
a Z id list list0 MAP25 _map25 Map_25
Variables
A variable loads and stores a value for evaluation during operations.
Declaration
Declare a variable before use with the format of type
followed by identifier. Declare an
array type variable using an opening [
token and a closing ]
token for each dimension directly after the identifier. Specify a
comma-separated list of identifiers following the type to declare multiple
variables in a single statement. Use an
assignment operator combined with a declaration to
immediately assign a value to a variable. A variable not immediately assigned a
value will have a default value assigned implicitly based on the type.
Errors
-
If a variable is used prior to or without declaration.
Grammar
declaration : type ID assignment? (',' ID assignment?)*;
type: ID ('.' ID)* ('[' ']')*;
assignment: '=' expression;
Examples
-
Different variations of variable declaration.
int x; (1) List y; (2) int x, y = 5, z; (3) def d; (4) int i = 10; (5) float[] f; (6) Map[][] m; (7)
-
declare
int x
; store defaultnull
tox
-
declare
List y
; store defaultnull
toy
-
declare
int x
; store defaultint 0
tox
; declareint y
; storeint 5
toy
; declareint z
; store defaultint 0
toz
; -
declare
def d
; store defaultnull
tod
-
declare
int i
; storeint 10
toi
-
declare
float[] f
; store defaultnull
tof
-
declare
Map[][] m
; store defaultnull
tom
-
Assignment
Use the assignment operator '='
to store a value in a variable for use in
subsequent operations. Any operation that produces a value can be assigned to
any variable as long as the types are the same or the
resultant type can be implicitly cast to the variable
type.
Errors
-
If the type of value is unable to match the type of variable.
Grammar
assignment: ID '=' expression
Examples
-
Variable assignment with an integer literal.
int i; (1) i = 10; (2)
-
declare
int i
; store defaultint 0
toi
-
store
int 10
toi
-
-
Declaration combined with immediate assignment.
int i = 10; (1) double j = 2.0; (2)
-
declare
int i
; storeint 10
toi
-
declare
double j
; storedouble 2.0
toj
-
-
Assignment of one variable to another using primitive type values.
int i = 10; (1) int j = i; (2)
-
declare
int i
; storeint 10
toi
-
declare
int j
; load fromi
→int 10
; storeint 10
toj
-
-
Assignment with reference types using the new instance operator.
ArrayList l = new ArrayList(); (1) Map m = new HashMap(); (2)
-
declare
ArrayList l
; allocateArrayList
instance →ArrayList reference
; storeArrayList reference
tol
-
declare
Map m
; allocateHashMap
instance →HashMap reference
; implicit castHashMap reference
toMap reference
→Map reference
; storeMap reference
tom
-
-
Assignment of one variable to another using reference type values.
List l = new ArrayList(); (1) List k = l; (2) List m; (3) m = k; (4)
-
declare
List l
; allocateArrayList
instance →ArrayList reference
; implicit castArrayList reference
toList reference
→List reference
; storeList reference
tol
-
declare
List k
; load froml
→List reference
; storeList reference
tok
; (notel
andk
refer to the same instance known as a shallow-copy) -
declare
List m
; store defaultnull
tom
-
load from
k
→List reference
; storeList reference
tom
; (notel
,k
, andm
refer to the same instance)
-
-
Assignment with array type variables using the new array operator.
int[] ia1; (1) ia1 = new int[2]; (2) ia1[0] = 1; (3) int[] ib1 = ia1; (4) int[][] ic2 = new int[2][5]; (5) ic2[1][3] = 2; (6) ic2[0] = ia1; (7)
-
declare
int[] ia1
; store defaultnull
toia1
-
allocate
1-d int array
instance withlength [2]
→1-d int array reference
; store1-d int array reference
toia1
-
load from
ia1
→1-d int array reference
; storeint 1
toindex [0]
of1-d int array reference
-
declare
int[] ib1
; load fromia1
→1-d int array reference
; store1-d int array reference
toib1
; (noteia1
andib1
refer to the same instance known as a shallow copy) -
declare
int[][] ic2
; allocate2-d int array
instance withlength [2, 5]
→2-d int array reference
; store2-d int array reference
toic2
-
load from
ic2
→2-d int array reference
; storeint 2
toindex [1, 3]
of2-d int array reference
-
load from
ia1
→1-d int array reference
; load fromic2
→2-d int array reference
; store1-d int array reference
toindex [0]
of2-d int array reference
; (noteia1
,ib1
, andindex [0]
ofia2
refer to the same instance)
-
Types
A type is a classification of data used to define the properties of a value. These properties specify what data a value represents and the rules for how a value is evaluated during an operation. Each type belongs to one of the following categories: primitive, reference, or dynamic.
Primitive Types
A primitive type represents basic data built natively into the JVM and is allocated to non-heap memory. Declare a primitive type variable or access a primitive type member field (from a reference type instance), and assign it a primitive type value for evaluation during later operations. The default value for a newly-declared primitive type variable is listed as part of the definitions below. A primitive type value is copied during an assignment or as an argument for a method/function call.
A primitive type has a corresponding reference type (also known as a boxed type). Use the field access operator or method call operator on a primitive type value to force evaluation as its corresponding reference type value.
The following primitive types are available:
byte
|
8-bit, signed, two’s complement integer
|
short
|
16-bit, signed, two’s complement integer
|
char
|
16-bit, unsigned, Unicode character
|
int
|
32-bit, signed, two’s complement integer
|
long
|
64-bit, signed, two’s complement integer
|
float
|
32-bit, signed, single-precision, IEEE 754 floating point number
|
double
|
64-bit, signed, double-precision, IEEE 754 floating point number
|
boolean
|
logical quantity with two possible values of
|
Examples
-
Primitive types used in declaration, declaration and assignment.
int i = 1; (1) double d; (2) boolean b = true; (3)
-
declare
int i
; storeint 1
toi
-
declare
double d
; store defaultdouble 0.0
tod
-
declare
boolean b
; storeboolean true
tob
-
-
Method call on a primitive type using the corresponding reference type.
int i = 1; (1) i.toString(); (2)
-
declare
int i
; storeint 1
toi
-
load from
i
→int 1
; boxint 1
→Integer 1 reference
; calltoString
onInteger 1 reference
→String '1'
-
Reference Types
A reference type is a named construct (object), potentially representing multiple pieces of data (member fields) and logic to manipulate that data (member methods), defined as part of the application programming interface (API) for scripts.
A reference type instance is a single set of data for one reference type object allocated to the heap. Use the new instance operator to allocate a reference type instance. Use a reference type instance to load from, store to, and manipulate complex data.
A reference type value refers to a reference type instance, and multiple reference type values may refer to the same reference type instance. A change to a reference type instance will affect all reference type values referring to that specific instance.
Declare a reference type variable or access a reference
type member field (from a reference type instance), and assign it a reference
type value for evaluation during later operations. The default value for a
newly-declared reference type variable is null
. A reference type value is
shallow-copied during an assignment or as an argument for a method/function
call. Assign null
to a reference type variable to indicate the reference type
value refers to no reference type instance. The JVM will garbage collect a
reference type instance when it is no longer referred to by any reference type
values. Pass null
as an argument to a method/function call to indicate the
argument refers to no reference type instance.
A reference type object defines zero-to-many of each of the following:
- static member field
-
A static member field is a named and typed piece of data. Each reference type object contains one set of data representative of its static member fields. Use the field access operator in correspondence with the reference type object name to access a static member field for loading and storing to a specific reference type object. No reference type instance allocation is necessary to use a static member field.
- non-static member field
-
A non-static member field is a named and typed piece of data. Each reference type instance contains one set of data representative of its reference type object’s non-static member fields. Use the field access operator for loading and storing to a non-static member field of a specific reference type instance. An allocated reference type instance is required to use a non-static member field.
- static member method
-
A static member method is a function called on a reference type object. Use the method call operator in correspondence with the reference type object name to call a static member method. No reference type instance allocation is necessary to use a static member method.
- non-static member method
-
A non-static member method is a function called on a reference type instance. A non-static member method called on a reference type instance can load from and store to non-static member fields of that specific reference type instance. Use the method call operator in correspondence with a specific reference type instance to call a non-static member method. An allocated reference type instance is required to use a non-static member method.
- constructor
-
A constructor is a special type of function used to allocate a reference type instance defined by a specific reference type object. Use the new instance operator to allocate a reference type instance.
A reference type object follows a basic inheritance model. Consider types A and B. Type A is considered to be a parent of B, and B a child of A, if B inherits (is able to access as its own) all of A’s non-static members. Type B is considered a descendant of A if there exists a recursive parent-child relationship from B to A with none to many types in between. In this case, B inherits all of A’s non-static members along with all of the non-static members of the types in between. Type B is also considered to be a type A in both relationships.
Examples
-
Reference types evaluated in several different operations.
List l = new ArrayList(); (1) l.add(1); (2) int i = l.get(0) + 2; (3)
-
declare
List l
; allocateArrayList
instance →ArrayList reference
; implicit castArrayList reference
toList reference
→List reference
; storeList reference
tol
-
load from
l
→List reference
; implicit castint 1
todef
→def
calladd
onList reference
with arguments (def
) -
declare
int i
; load froml
→List reference
; callget
onList reference
with arguments (int 0
) →def
; implicit castdef
toint 1
→int 1
; addint 1
andint 2
→int 3
; storeint 3
toi
-
-
Sharing a reference type instance.
List l0 = new ArrayList(); (1) List l1 = l0; (2) l0.add(1); (3) l1.add(2); (4) int i = l1.get(0) + l0.get(1); (5)
-
declare
List l0
; allocateArrayList
instance →ArrayList reference
; implicit castArrayList reference
toList reference
→List reference
; storeList reference
tol0
-
declare
List l1
; load froml0
→List reference
; storeList reference
tol1
(notel0
andl1
refer to the same instance known as a shallow-copy) -
load from
l0
→List reference
; implicit castint 1
todef
→def
calladd
onList reference
with arguments (def
) -
load from
l1
→List reference
; implicit castint 2
todef
→def
calladd
onList reference
with arguments (def
) -
declare
int i
; load froml0
→List reference
; callget
onList reference
with arguments (int 0
) →def @0
; implicit castdef @0
toint 1
→int 1
; load froml1
→List reference
; callget
onList reference
with arguments (int 1
) →def @1
; implicit castdef @1
toint 2
→int 2
; addint 1
andint 2
→int 3
; storeint 3
toi
;
-
-
Using the static members of a reference type.
int i = Integer.MAX_VALUE; (1) long l = Long.parseLong("123L"); (2)
-
declare
int i
; load fromMAX_VALUE
onInteger
→int 2147483647
; storeint 2147483647
toi
-
declare
long l
; callparseLong
onLong
with arguments (long 123
) →long 123
; storelong 123
tol
-
Dynamic Types
A dynamic type value can represent the value of any primitive type or
reference type using a single type name def
. A def
type value mimics
the behavior of whatever value it represents at run-time and will always
represent the child-most descendant type value of any type value when evaluated
during operations.
Declare a def
type variable or access a def
type
member field (from a reference type instance), and assign it any type of value
for evaluation during later operations. The default value for a newly-declared
def
type variable is null
. A def
type variable or method/function
parameter can change the type it represents during the compilation and
evaluation of a script.
Using the def
type can have a slight impact on performance. Use only primitive
types and reference types directly when performance is critical.
Errors
-
If a
def
type value represents an inappropriate type for evaluation of an operation at run-time.
Examples
-
General uses of the
def
type.def dp = 1; (1) def dr = new ArrayList(); (2) dr = dp; (3)
-
declare
def dp
; implicit castint 1
todef
→def
; storedef
todp
-
declare
def dr
; allocateArrayList
instance →ArrayList reference
; implicit castArrayList reference
todef
→def
; storedef
todr
-
load from
dp
→def
; storedef
todr
; (note the switch in the typedr
represents fromArrayList
toint
)
-
-
A
def
type value representing the child-most descendant of a value.Object l = new ArrayList(); (1) def d = l; (2) d.ensureCapacity(10); (3)
-
declare
Object l
; allocateArrayList
instance →ArrayList reference
; implicit castArrayList reference
toObject reference
→Object reference
; storeObject reference
tol
-
declare
def d
; load froml
→Object reference
; implicit castObject reference
todef
→def
; storedef
tod
; -
load from
d
→def
; implicit castdef
toArrayList reference
→ArrayList reference
; callensureCapacity
onArrayList reference
with arguments (int 10
); (notedef
was implicit cast toArrayList reference
since ArrayList` is the child-most descendant type value that thedef
type value represents)
-
String Type
The String
type is a specialized reference type that does not require
explicit allocation. Use a string literal to directly
evaluate a String
type value. While not required, the
new instance operator can allocate String
type
instances.
Examples
-
General use of the
String
type.String r = "some text"; (1) String s = 'some text'; (2) String t = new String("some text"); (3) String u; (4)
-
declare
String r
; storeString "some text"
tor
-
declare
String s
; storeString 'some text'
tos
-
declare
String t
; allocateString
instance with arguments (String "some text"
) →String "some text"
; storeString "some text"
tot
-
declare
String u
; store defaultnull
tou
-
void Type
The void
type represents the concept of a lack of type. Use the void
type to
indicate a function returns no value.
Examples
-
Use of the
void
type in a function.void addToList(List l, def d) { l.add(d); }
Array Type
An array type is a specialized reference type where an array type instance
contains a series of values allocated to the heap. Each value in an array type
instance is defined as an element. All elements in an array type instance are of
the same type (element type) specified as part of declaration. Each element is
assigned an index within the range [0, length)
where length is the total
number of elements allocated for an array type instance.
Use the new array operator or the
array initialization operator to allocate an
array type instance. Declare an array type variable or
access an array type member field (from a reference type instance), and assign
it an array type value for evaluation during later operations. The default value
for a newly-declared array type variable is null
. An array type value is
shallow-copied during an assignment or as an argument for a method/function
call. Assign null
to an array type variable to indicate the array type value
refers to no array type instance. The JVM will garbage collect an array type
instance when it is no longer referred to by any array type values. Pass null
as an argument to a method/function call to indicate the argument refers to no
array type instance.
Use the array length operator to retrieve the length
of an array type value as an int
type value. Use the
array access operator to load from and store to
an individual element within an array type instance.
When an array type instance is allocated with multiple dimensions using the
range [2, d]
where d >= 2
, each element within each dimension in the range
[1, d-1]
is also an array type. The element type of each dimension, n
, is an
array type with the number of dimensions equal to d-n
. For example, consider
int[][][]
with 3 dimensions. Each element in the 3rd dimension, d-3
, is the
primitive type int
. Each element in the 2nd dimension, d-2
, is the array
type int[]
. And each element in the 1st dimension, d-1
is the array type
int[][]
.
Examples
-
General use of single-dimensional arrays.
int[] x; (1) float[] y = new float[10]; (2) def z = new float[5]; (3) y[9] = 1.0F; (4) z[0] = y[9]; (5)
-
declare
int[] x
; store defaultnull
tox
-
declare
float[] y
; allocate1-d float array
instance withlength [10]
→1-d float array reference
; store1-d float array reference
toy
-
declare
def z
; allocate1-d float array
instance withlength [5]
→1-d float array reference
; implicit cast1-d float array reference
todef
→def
; storedef
toz
-
load from
y
→1-d float array reference
; storefloat 1.0
toindex [9]
of1-d float array reference
-
load from
y
→1-d float array reference @0
; load fromindex [9]
of1-d float array reference @0
→float 1.0
; load fromz
→def
; implicit castdef
to1-d float array reference @1
→1-d float array reference @1
; storefloat 1.0
toindex [0]
of1-d float array reference @1
-
-
General use of a multi-dimensional array.
int[][][] ia3 = new int[2][3][4]; (1) ia3[1][2][3] = 99; (2) int i = ia3[1][2][3]; (3)
-
declare
int[][][] ia
; allocate3-d int array
instance with length[2, 3, 4]
→3-d int array reference
; store3-d int array reference
toia3
-
load from
ia3
→3-d int array reference
; storeint 99
toindex [1, 2, 3]
of3-d int array reference
-
declare
int i
; load fromia3
→3-d int array reference
; load fromindex [1, 2, 3]
of3-d int array reference
→int 99
; storeint 99
toi
-
Casting
A cast converts the value of an original type to the equivalent value of a
target type. An implicit cast infers the target type and automatically occurs
during certain operations. An explicit cast specifies
the target type and forcefully occurs as its own operation. Use the cast
operator '()'
to specify an explicit cast.
Refer to the cast table for a quick reference on all allowed casts.
Errors
-
If during a cast there exists no equivalent value for the target type.
-
If an implicit cast is given, but an explicit cast is required.
Grammar
cast: '(' TYPE ')' expression
Examples
-
Valid casts.
int i = (int)5L; (1) Map m = new HashMap(); (2) HashMap hm = (HashMap)m; (3)
-
declare
int i
; explicit castlong 5
toint 5
→int 5
; storeint 5
toi
-
declare
Map m
; allocateHashMap
instance →HashMap reference
; implicit castHashMap reference
toMap reference
→Map reference
; storeMap reference
tom
-
declare
HashMap hm
; load fromm
→Map reference
; explicit castMap reference
toHashMap reference
→HashMap reference
; storeHashMap reference
tohm
-
Numeric Type Casting
A numeric type cast converts the value of an original numeric type to the equivalent value of a target numeric type. A cast between two numeric type values results in data loss when the value of the original numeric type is larger than the target numeric type can accommodate. A cast between an integer type value and a floating point type value can result in precision loss.
The allowed casts for values of each numeric type are shown as a row in the following table:
byte |
short |
char |
int |
long |
float |
double |
|
byte |
implicit |
implicit |
implicit |
implicit |
implicit |
implicit |
|
short |
explicit |
explicit |
implicit |
implicit |
implicit |
implicit |
|
char |
explicit |
explicit |
implicit |
implicit |
implicit |
implicit |
|
int |
explicit |
explicit |
explicit |
implicit |
implicit |
implicit |
|
long |
explicit |
explicit |
explicit |
explicit |
implicit |
implicit |
|
float |
explicit |
explicit |
explicit |
explicit |
explicit |
implicit |
|
double |
explicit |
explicit |
explicit |
explicit |
explicit |
explicit |
Examples
-
Valid numeric type casts.
int a = 1; (1) long b = a; (2) short c = (short)b; (3) double e = (double)a; (4)
-
declare
int a
; storeint 1
toa
-
declare
long b
; load froma
→int 1
; implicit castint 1
tolong 1
→long 1
; storelong 1
tob
-
declare
short c
; load fromb
→long 1
; explicit castlong 1
toshort 1
→short 1
; storeshort 1
value toc
-
declare
double e
; load froma
→int 1
; explicit castint 1
todouble 1.0
; storedouble 1.0
toe
; (note the explicit cast is extraneous since an implicit cast is valid)
-
-
Invalid numeric type casts resulting in errors.
int a = 1.0; // error (1) int b = 2; (2) byte c = b; // error (3)
-
declare
int i
; error → cannot implicit castdouble 1.0
toint 1
; (note an explicit cast is valid) -
declare
int b
; storeint 2
tob
-
declare byte
c
; load fromb
→int 2
; error → cannot implicit castint 2
tobyte 2
; (note an explicit cast is valid)
-
Reference Type Casting
A reference type cast converts the value of an original reference type to the equivalent value of a target reference type. An implicit cast between two reference type values is allowed when the original reference type is a descendant of the target type. An explicit cast between two reference type values is allowed when the original type is a descendant of the target type or the target type is a descendant of the original type.
Examples
-
Valid reference type casts.
List x; (1) ArrayList y = new ArrayList(); (2) x = y; (3) y = (ArrayList)x; (4) x = (List)y; (5)
-
declare
List x
; store default valuenull
tox
-
declare
ArrayList y
; allocateArrayList
instance →ArrayList reference
; storeArrayList reference
toy
; -
load from
y
→ArrayList reference
; implicit castArrayList reference
toList reference
→List reference
; storeList reference
tox
; (noteArrayList
is a descendant ofList
) -
load from
x
→List reference
; explicit castList reference
toArrayList reference
→ArrayList reference
; storeArrayList reference
toy
; -
load from
y
→ArrayList reference
; explicit castArrayList reference
toList reference
→List reference
; storeList reference
tox
; (note the explicit cast is extraneous, and an implicit cast is valid)
-
-
Invalid reference type casts resulting in errors.
List x = new ArrayList(); (1) ArrayList y = x; // error (2) Map m = (Map)x; // error (3)
-
declare
List x
; allocateArrayList
instance →ArrayList reference
; implicit castArrayList reference
toList reference
→List reference
; storeList reference
tox
-
declare
ArrayList y
; load fromx
→List reference
; error → cannot implicit castList reference
toArrayList reference
; (note an explicit cast is valid sinceArrayList
is a descendant ofList
) -
declare
ArrayList y
; load fromx
→List reference
; error → cannot explicit castList reference
toMap reference
; (note no cast is valid since neitherList
norMap
is a descendant of the other)
-
Dynamic Type Casting
A dynamic (def
) type cast converts the value of an original
def
type to the equivalent value of any target type or converts the value of
any original type to the equivalent value of a target def
type.
An implicit cast from any original type value to a def
type value is always
allowed. An explicit cast from any original type value to a def
type value is
always allowed but never necessary.
An implicit or explicit cast from an original def
type value to
any target type value is allowed if and only if the cast is normally allowed
based on the current type value the def
type value represents.
Examples
-
Valid dynamic type casts with any original type to a target
def
type.def d0 = 3; (1) d0 = new ArrayList(); (2) Object o = new HashMap(); (3) def d1 = o; (4) int i = d1.size(); (5)
-
declare
def d0
; implicit castint 3
todef
; storeint 3
tod0
-
allocate
ArrayList
instance →ArrayList reference
; implicit castArrayList reference
todef
→def
; storedef
tod0
-
declare
Object o
; allocateHashMap
instance →HashMap reference
; implicit castHashMap reference
toObject reference
→Object reference
; storeObject reference
too
-
declare
def d1
; load fromo
→Object reference
; implicit castObject reference
todef
→def
; storedef
tod1
-
declare
int i
; load fromd1
→def
; implicit castdef
toHashMap reference
→ HashMap reference`; callsize
onHashMap reference
→int 0
; storeint 0
toi
; (notedef
was implicit cast toHashMap reference
sinceHashMap
is the child-most descendant type value that thedef
type value represents)
-
-
Valid dynamic type casts with an original
def
type to any target type.def d = 1.0; (1) int i = (int)d; (2) d = 1; (3) float f = d; (4) d = new ArrayList(); (5) List l = d; (6)
-
declare
def d
; implicit castdouble 1.0
todef
→def
; storedef
tod
-
declare
int i
; load fromd
→def
; implicit castdef
todouble 1.0
→double 1.0
; explicit castdouble 1.0
toint 1
→int 1
; storeint 1
toi
; (note the explicit cast is necessary since adouble
type value is not converted to anint
type value implicitly) -
store
int 1
tod
; (note the switch in the typed
represents fromdouble
toint
) -
declare
float i
; load fromd
→def
; implicit castdef
toint 1
→int 1
; implicit castint 1
tofloat 1.0
→float 1.0
; storefloat 1.0
tof
-
allocate
ArrayList
instance →ArrayList reference
; storeArrayList reference
tod
; (note the switch in the typed
represents fromint
toArrayList
) -
declare
List l
; load fromd
→def
; implicit castdef
toArrayList reference
→ArrayList reference
; implicit castArrayList reference
toList reference
→List reference
; storeList reference
tol
-
-
Invalid dynamic type casts resulting in errors.
def d = 1; (1) short s = d; // error (2) d = new HashMap(); (3) List l = d; // error (4)
-
declare
def d
; implicit castint 1
todef
→def
; storedef
tod
-
declare
short s
; load fromd
→def
; implicit castdef
toint 1
→int 1
; error → cannot implicit castint 1
toshort 1
; (note an explicit cast is valid) -
allocate
HashMap
instance →HashMap reference
; implicit castHashMap reference
todef
→def
; storedef
tod
-
declare
List l
; load fromd
→def
; implicit castdef
toHashMap reference
; error → cannot implicit castHashMap reference
toList reference
; (note no cast is valid since neitherHashMap
norList
is a descendant of the other)
-
String to Character Casting
Use the cast operator to convert a String
type value into a
char
type value.
Errors
-
If the
String
type value isn’t one character in length. -
If the
String
type value isnull
.
Examples
-
Casting string literals into
char
type values.char c = (char)"C"; (1) c = (char)'c'; (2)
-
declare
char c
; explicit castString "C"
tochar C
→char C
; storechar C
toc
-
explicit cast
String 'c'
tochar c
→char c
; storechar c
toc
-
-
Casting a
String
reference into achar
type value.String s = "s"; (1) char c = (char)s; (2)
-
declare
String s
; storeString "s"
tos
; -
declare
char c
load froms
→String "s"
; explicit castString "s"
tochar s
→char s
; storechar s
toc
-
Boxing and Unboxing
Boxing is a special type of cast used to convert a primitive type to its corresponding reference type. Unboxing is the reverse used to convert a reference type to its corresponding primitive type.
Implicit boxing/unboxing occurs during the following operations:
-
Conversions between a
def
type and a primitive type are implicitly boxed/unboxed as necessary, though this is referred to as an implicit cast throughout the documentation. -
Method/function call arguments are implicitly boxed/unboxed as necessary.
-
A primitive type value is implicitly boxed when a reference type method is called on it.
Explicit boxing/unboxing is not allowed. Use the reference type API to explicitly convert a primitive type value to its respective reference type value and vice versa.
Errors
-
If an explicit cast is made to box/unbox a primitive type.
Examples
-
Uses of implicit boxing/unboxing.
List l = new ArrayList(); (1) l.add(1); (2) Integer I = Integer.valueOf(0); (3) int i = l.get(i); (4)
-
declare
List l
; allocateArrayList
instance →ArrayList reference
; storeArrayList reference
tol
; -
load from
l
→List reference
; implicit castint 1
todef
→def
; calladd
onList reference
with arguments (def
); (note internallyint 1
is boxed toInteger 1
to store as adef
type value) -
declare
Integer I
; callvalueOf
onInteger
with arguments of (int 0
) →Integer 0
; storeInteger 0
toI
; -
declare
int i
; load fromI
→Integer 0
; unboxInteger 0
→int 0
; load froml
→List reference
; callget
onList reference
with arguments (int 0
) →def
; implicit castdef
toint 1
→int 1
; storeint 1
toi
; (note internallyint 1
is unboxed fromInteger 1
when loaded from adef
type value)
-
-
Uses of invalid boxing/unboxing resulting in errors.
Integer x = 1; // error (1) Integer y = (Integer)1; // error (2) int a = Integer.valueOf(1); // error (3) int b = (int)Integer.valueOf(1); // error (4)
-
declare
Integer x
; error → cannot implicit boxint 1
toInteger 1
during assignment -
declare
Integer y
; error → cannot explicit boxint 1
toInteger 1
during assignment -
declare
int a
; callvalueOf
onInteger
with arguments of (int 1
) →Integer 1
; error → cannot implicit unboxInteger 1
toint 1
during assignment -
declare
int a
; callvalueOf
onInteger
with arguments of (int 1
) →Integer 1
; error → cannot explicit unboxInteger 1
toint 1
during assignment
-
Promotion
Promotion is when a single value is implicitly cast to a certain type or
multiple values are implicitly cast to the same type as required for evaluation
by certain operations. Each operation that requires promotion has a promotion
table that shows all required implicit casts based on the type(s) of value(s). A
value promoted to a def
type at compile-time is promoted again at run-time
based on the type the def
value represents.
Errors
-
If a specific operation cannot find an allowed promotion type for the type(s) of value(s) given.
Examples
-
Uses of promotion.
double d = 2 + 2.0; (1) def x = 1; (2) float f = x + 2.0F; (3)
-
declare
double d
; promoteint 2
anddouble 2.0 @0
: resultdouble
; implicit castint 2
todouble 2.0 @1
→double 2.0 @1
; adddouble 2.0 @1
anddouble 2.0 @0
→double 4.0
; storedouble 4.0
tod
-
declare
def x
; implicit castint 1
todef
→def
; storedef
tox
; -
declare
float f
; load fromx
→def
; implicit castdef
toint 1
→int 1
; promoteint 1
andfloat 2.0
: resultfloat
; implicit castint 1
tofloat 1.0
→float `1.0
; addfloat 1.0
andfloat 2.0
→float 3.0
; storefloat 3.0
tof
; (note this example illustrates promotion done at run-time as promotion done at compile-time would have resolved to adef
type value)
-
Allowed Casts
The following tables show all allowed casts. Read the tables row by row, where the original type is shown in the first column, and each subsequent column indicates whether a cast to the specified target type is implicit (I), explicit (E), or is not allowed (-).
Primitive/Reference Types
o |
b |
s |
c |
i |
j |
f |
d |
O |
B |
S |
C |
I |
L |
F |
D |
T |
R |
def |
|
boolean ( o ) |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
I |
|
byte ( b ) |
- |
I |
I |
I |
I |
I |
I |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
I |
|
short ( s ) |
- |
E |
E |
I |
I |
I |
I |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
I |
|
char ( c ) |
- |
E |
E |
I |
I |
I |
I |
- |
- |
- |
- |
- |
- |
- |
- |
E |
- |
I |
|
int ( i ) |
- |
E |
E |
E |
I |
I |
I |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
I |
|
long ( j ) |
- |
E |
E |
E |
E |
I |
I |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
I |
|
float ( f ) |
- |
E |
E |
E |
E |
E |
I |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
I |
|
double ( d ) |
- |
E |
E |
E |
E |
E |
E |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
I |
|
Boolean ( O ) |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
I |
|
Byte ( B ) |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
I |
|
Short ( S ) |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
I |
|
Character ( C ) |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
I |
|
Integer ( I ) |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
I |
|
Long ( L ) |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
I |
|
Float ( F ) |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
I |
|
Double ( D ) |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
I |
|
String ( T ) |
- |
- |
- |
E |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
I |
|
Reference ( R ) |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
@ |
I |
@ See reference type casting for allowed reference type casts.
def
Type
o |
b |
s |
c |
i |
j |
f |
d |
O |
B |
S |
C |
I |
L |
F |
D |
T |
R |
def |
|
def as boolean |
I |
- |
- |
- |
- |
- |
- |
- |
I |
- |
- |
- |
- |
- |
- |
- |
- |
- |
|
def as byte |
- |
I |
I |
I |
I |
I |
I |
I |
- |
I |
I |
I |
I |
I |
I |
I |
- |
- |
|
def as short |
- |
E |
I |
E |
I |
I |
I |
I |
- |
E |
I |
E |
I |
I |
I |
I |
- |
- |
|
def as char |
- |
E |
E |
I |
I |
I |
I |
I |
- |
E |
E |
I |
I |
I |
I |
I |
E |
- |
|
def as int |
- |
E |
E |
E |
I |
I |
I |
I |
- |
E |
E |
E |
I |
I |
I |
I |
- |
- |
|
def as long |
- |
E |
E |
E |
E |
I |
I |
I |
- |
E |
E |
E |
E |
I |
I |
I |
- |
- |
|
def as float |
- |
E |
E |
E |
E |
E |
I |
I |
- |
E |
E |
E |
E |
E |
I |
I |
- |
- |
|
def as double |
- |
E |
E |
E |
E |
E |
E |
I |
- |
E |
E |
E |
E |
E |
E |
I |
- |
- |
|
def as Boolean |
I |
- |
- |
- |
- |
- |
- |
- |
I |
- |
- |
- |
- |
- |
- |
- |
- |
||
def as Byte |
- |
I |
I |
I |
I |
I |
I |
I |
- |
I |
I |
I |
I |
I |
I |
I |
- |
- |
|
def as Short |
- |
E |
I |
E |
I |
I |
I |
I |
- |
E |
I |
E |
I |
I |
I |
I |
- |
- |
|
def as Character |
- |
E |
E |
I |
I |
I |
I |
I |
- |
E |
E |
I |
I |
I |
I |
I |
- |
- |
|
def as Integer |
- |
E |
E |
E |
I |
I |
I |
I |
- |
E |
E |
E |
I |
I |
I |
I |
- |
- |
|
def as Long |
- |
E |
E |
E |
E |
I |
I |
I |
- |
E |
E |
E |
E |
I |
I |
I |
- |
- |
|
def as Float |
- |
E |
E |
E |
E |
E |
I |
I |
- |
E |
E |
E |
E |
E |
I |
I |
- |
- |
|
def as Double |
- |
E |
E |
E |
E |
E |
E |
I |
- |
E |
E |
E |
E |
E |
E |
I |
- |
- |
|
def as String |
- |
- |
- |
E |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
I |
- |
|
def as Reference |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
@ |
@ See reference type casting for allowed reference type casts.
Operators
An operator is the most basic action that can be taken to evaluate values in a script. An expression is one-to-many consecutive operations. Precedence is the order in which an operator will be evaluated relative to another operator. Associativity is the direction within an expression in which a specific operator is evaluated. The following table lists all available operators:
Operator |
Category |
Symbol(s) |
Precedence |
Associativity |
() |
0 |
left → right |
||
. () |
1 |
left → right |
||
. |
1 |
left → right |
||
?. |
1 |
left → right |
||
() |
1 |
left → right |
||
[] {} |
1 |
left → right |
||
[] |
1 |
left → right |
||
. |
1 |
left → right |
||
[] |
1 |
left → right |
||
[] |
1 |
left → right |
||
[:] |
1 |
left → right |
||
[] |
1 |
left → right |
||
++ |
1 |
left → right |
||
— |
1 |
left → right |
||
++ |
2 |
right → left |
||
— |
2 |
right → left |
||
+ |
2 |
right → left |
||
- |
2 |
right → left |
||
! |
2 |
right → left |
||
~ |
2 |
right → left |
||
() |
3 |
right → left |
||
new () |
3 |
right → left |
||
new [] |
3 |
right → left |
||
* |
4 |
left → right |
||
/ |
4 |
left → right |
||
% |
4 |
left → right |
||
+ |
5 |
left → right |
||
+ |
5 |
left → right |
||
- |
5 |
left → right |
||
<< |
6 |
left → right |
||
>> |
6 |
left → right |
||
>>> |
6 |
left → right |
||
> |
7 |
left → right |
||
>= |
7 |
left → right |
||
< |
7 |
left → right |
||
⇐ |
7 |
left → right |
||
instanceof |
8 |
left → right |
||
== |
9 |
left → right |
||
!= |
9 |
left → right |
||
=== |
9 |
left → right |
||
!== |
9 |
left → right |
||
& |
10 |
left → right |
||
^ |
11 |
left → right |
||
^ |
11 |
left → right |
||
| |
12 |
left → right |
||
&& |
13 |
left → right |
||
|| |
14 |
left → right |
||
? : |
15 |
right → left |
||
?: |
16 |
right → left |
||
= |
17 |
right → left |
||
$= |
17 |
right → left |
Operators: General
Precedence
Use the precedence operator '()'
to guarantee the order of evaluation for an
expression. An expression encapsulated by the precedence operator (enclosed in
parentheses) overrides existing precedence relationships between operators and
is evaluated prior to other expressions in inward-to-outward order.
Grammar
precedence: '(' expression ')';
Examples
-
Precedence with numeric operators.
int x = (5+4)*6; (1) int y = 12/(x-50); (2)
-
declare
int x
; addint 5
andint 4
→int 9
; multiplyint 9
andint 6
→int 54
; storeint 54
tox
; (note the add is evaluated before the multiply due to the precedence operator) -
declare
int y
; load fromx
→int 54
; subtractint 50
fromint 54
→int 4
; divideint 12
byint 4
→int 3
; storeint 3
toy
; (note the subtract is evaluated before the divide due to the precedence operator)
-
Function Call
Use the function call operator ()
to call an existing function. A
function call is defined within a script.
Grammar
function_call: ID '(' ( expression (',' expression)* )? ')'';
Examples
-
A function call.
int add(int x, int y) { (1) return x + y; } int z = add(1, 2); (2)
-
define function
add
that returnsint
and has parameters (int x
,int y
) -
declare
int z
; calladd
with arguments (int 1
,int 2
) →int 3
; storeint 3
toz
-
Cast
An explicit cast converts the value of an original type to the equivalent value
of a target type forcefully as an operation. Use the cast operator '()'
to
specify an explicit cast. Refer to casting for more
information.
Conditional
A conditional consists of three expressions. The first expression is evaluated
with an expected boolean result type. If the first expression evaluates to true
then the second expression will be evaluated. If the first expression evaluates
to false then the third expression will be evaluated. The second and third
expressions will be promoted if the evaluated values are not the
same type. Use the conditional operator '? :'
as a shortcut to avoid the need
for a full if/else branch in certain expressions.
Errors
-
If the first expression does not evaluate to a boolean type value.
-
If the values for the second and third expressions cannot be promoted.
Grammar
conditional: expression '?' expression ':' expression;
Promotion
byte |
short |
char |
int |
long |
float |
double |
Reference |
def |
|
byte |
int |
int |
int |
int |
long |
float |
double |
- |
def |
short |
int |
int |
int |
int |
long |
float |
double |
- |
def |
char |
int |
int |
int |
int |
long |
float |
double |
- |
def |
int |
int |
int |
int |
int |
long |
float |
double |
- |
def |
long |
long |
long |
long |
long |
long |
float |
double |
- |
def |
float |
float |
float |
float |
float |
float |
float |
double |
- |
def |
double |
double |
double |
double |
double |
double |
double |
double |
- |
def |
Reference |
- |
- |
- |
- |
- |
- |
- |
Object @ |
def |
def |
def |
def |
def |
def |
def |
def |
def |
def |
def |
@ If the two reference type values are the same then this promotion will not occur.
Examples
-
Evaluation of conditionals.
boolean b = true; (1) int x = b ? 1 : 2; (2) List y = x > 1 ? new ArrayList() : null; (3) def z = x < 2 ? x : 2.0; (4)
-
declare
boolean b
; storeboolean true
tob
-
declare
int x
; load fromb
→boolean true
evaluate 1st expression:int 1
→int 1
; storeint 1
tox
-
declare
List y
; load fromx
→int 1
;int 1
greater thanint 1
→boolean false
; evaluate 2nd expression:null
→null
; storenull
toy
; -
declare
def z
; load fromx
→int 1
;int 1
less thanint 2
→boolean true
; evaluate 1st expression: load fromx
→int 1
; promoteint 1
anddouble 2.0
: resultdouble
; implicit castint 1
todouble 1.0
→double 1.0
; implicit castdouble 1.0
todef
→def
; storedef
toz
;
-
Assignment
Use the assignment operator '='
to store a value in a variable or reference
type member field for use in subsequent operations. Any operation that produces
a value can be assigned to any variable/field as long as the
types are the same or the resultant type can be
implicitly cast to the variable/field type.
See variable assignment for examples using variables.
Errors
-
If the type of value is unable to match the type of variable or field.
Grammar
assignment: field '=' expression
Examples
The examples use the following reference type definition:
name:
Example
non-static member fields:
* int x
* def y
* List z
-
Field assignments of different type values.
Example example = new Example(); (1) example.x = 1; (2) example.y = 2.0; (3) example.z = new ArrayList(); (4)
-
declare
Example example
; allocateExample
instance →Example reference
; storeExample reference
toexample
-
load from
example
→Example reference
; storeint 1
tox
ofExample reference
-
load from
example
→Example reference
; implicit castdouble 2.0
todef
→def
; storedef
toy
ofExample reference
-
load from
example
→Example reference
; allocateArrayList
instance →ArrayList reference
; implicit castArrayList reference
toList reference
→List reference
; storeList reference
toz
ofExample reference
-
-
A field assignment from a field access.
Example example = new Example(); (1) example.x = 1; (2) example.y = example.x; (3)
-
declare
Example example
; allocateExample
instance →Example reference
; storeExample reference
toexample
-
load from
example
→Example reference
; storeint 1
tox
ofExample reference
-
load from
example
→Example reference @0
; load fromexample
→Example reference @1
; load fromx
ofExample reference @1
→int 1
; implicit castint 1
todef
→def
; storedef
toy
ofExample reference @0
; (noteExample reference @0
andExample reference @1
are the same)
-
Compound Assignment
Use the compound assignment operator '$='
as a shortcut for an assignment
where a binary operation would occur between the variable/field as the
left-hand side expression and a separate right-hand side expression.
A compound assignment is equivalent to the expression below where V is the variable/field and T is the type of variable/member.
V = (T)(V op expression);
Operators
The table below shows the available operators for use in a compound assignment. Each operator follows the casting/promotion rules according to their regular definition. For numeric operations there is an extra implicit cast when necessary to return the promoted numeric type value to the original numeric type value of the variable/field and can result in data loss.
Operator |
Compound Symbol |
Multiplication |
*= |
Division |
/= |
Remainder |
%= |
Addition |
+= |
Subtraction |
-= |
Left Shift |
<⇐ |
Right Shift |
>>= |
Unsigned Right Shift |
>>>= |
Bitwise And |
&= |
Boolean And |
&= |
Bitwise Xor |
^= |
Boolean Xor |
^= |
Bitwise Or |
|= |
Boolean Or |
|= |
String Concatenation |
+= |
Errors
-
If the type of value is unable to match the type of variable or field.
Grammar
compound_assignment: ( ID | field ) '$=' expression;
Note the use of the $=
represents the use of any of the possible binary
operators.
Examples
-
Compound assignment for each numeric operator.
int i = 10; (1) i *= 2; (2) i /= 5; (3) i %= 3; (4) i += 5; (5) i -= 5; (6) i <<= 2; (7) i >>= 1; (8) i >>>= 1; (9) i &= 15; (10) i ^= 12; (11) i |= 2; (12)
-
declare
int i
; storeint 10
toi
-
load from
i
→int 10
; multiplyint 10
andint 2
→int 20
; storeint 20
toi
; (note this is equivalent toi = i*2
) -
load from
i
→int 20
; divideint 20
byint 5
→int 4
; storeint 4
toi
; (note this is equivalent toi = i/5
) -
load from
i
→int 4
; remainderint 4
byint 3
→int 1
; storeint 1
toi
; (note this is equivalent toi = i%3
) -
load from
i
→int 1
; addint 1
andint 5
→int 6
; storeint 6
toi
; (note this is equivalent toi = i+5
) -
load from
i
→int 6
; subtractint 5
fromint 6
→int 1
; storeint 1
toi
; (note this is equivalent toi = i-5
) -
load from
i
→int 1
; left shiftint 1
byint 2
→int 4
; storeint 4
toi
; (note this is equivalent toi = i<<2
) -
load from
i
→int 4
; right shiftint 4
byint 1
→int 2
; storeint 2
toi
; (note this is equivalent toi = i>>1
) -
load from
i
→int 2
; unsigned right shiftint 2
byint 1
→int 1
; storeint 1
toi
; (note this is equivalent toi = i>>>1
) -
load from
i
→int 1
; bitwise andint 1
andint 15
→int 1
; storeint 1
toi
; (note this is equivalent toi = i&2
) -
load from
i
→int 1
; bitwise xorint 1
andint 12
→int 13
; storeint 13
toi
; (note this is equivalent toi = i^2
) -
load from
i
→int 13
; bitwise orint 13
andint 2
→int 15
; storeint 15
toi
; (note this is equivalent toi = i|2
)
-
-
Compound assignment for each boolean operator.
boolean b = true; (1) b &= false; (2) b ^= false; (3) b |= true; (4)
-
declare
boolean b
; storeboolean true
inb
; -
load from
b
→boolean true
; boolean andboolean true
andboolean false
→boolean false
; storeboolean false
tob
; (note this is equivalent tob = b && false
) -
load from
b
→boolean false
; boolean xorboolean false
andboolean false
→boolean false
; storeboolean false
tob
; (note this is equivalent tob = b ^ false
) -
load from
b
→boolean true
; boolean orboolean false
andboolean true
→boolean true
; storeboolean true
tob
; (note this is equivalent tob = b || true
)
-
-
A compound assignment with the string concatenation operator.
String s = 'compound'; (1) s += ' assignment'; (2)
-
declare
String s
; storeString 'compound'
tos
; -
load from
s
→String 'compound'
; string concatString 'compound'
andString ' assignment''
→String 'compound assignment'
; storeString 'compound assignment'
tos
; (note this is equivalent tos = s + ' assignment'
)
-
-
A compound assignment with the
def
type.def x = 1; (1) x += 2; (2)
-
declare
def x
; implicit castint 1
todef
; storedef
tox
; -
load from
x
→def
; implicit castdef
toint 1
→int 1
; addint 1
andint 2
→int 3
; implicit castint 3
todef
→def
; storedef
tox
; (note this is equivalent tox = x+2
)
-
-
A compound assignment with an extra implicit cast.
byte b = 1; (1) b += 2; (2)
-
declare
byte b
; storebyte 1
tox
; -
load from
x
→byte 1
; implicit castbyte 1 to `int 1
→int 1
; addint 1
andint 2
→int 3
; implicit castint 3
tobyte 3
→byte 3
; storebyte 3
tob
; (note this is equivalent tob = b+2
)
-
Operators: Numeric
Post Increment
Use the post increment operator '++'
to INCREASE the value of a numeric type
variable/field by 1
. An extra implicit cast is necessary to return the
promoted numeric type value to the original numeric type value of the
variable/field for the following types: byte
, short
, and char
. If a
variable/field is read as part of an expression the value is loaded prior to the
increment.
Errors
-
If the variable/field is a non-numeric type.
Grammar
post_increment: ( variable | field ) '++';
Promotion
original | promoted | implicit |
---|---|---|
byte |
int |
byte |
short |
int |
short |
char |
int |
char |
int |
int |
|
long |
long |
|
float |
float |
|
double |
double |
|
def |
def |
Examples
-
Post increment with different numeric types.
short i = 0; (1) i++; (2) long j = 1; (3) long k; (4) k = j++; (5)
-
declare
short i
; storeshort 0
toi
-
load from
i
→short 0
; promoteshort 0
: resultint
; addint 0
andint 1
→int 1
; implicit castint 1
toshort 1
; storeshort 1
toi
-
declare
long j
; implicit castint 1
tolong 1
→long 1
; storelong 1
toj
-
declare
long k
; store defaultlong 0
tok
-
load from
j
→long 1
; storelong 1
tok
; addlong 1
andlong 1
→long 2
; storelong 2
toj
-
-
Post increment with the
def
type.def x = 1; (1) x++; (2)
-
declare
def x
; implicit castint 1
todef
→def
; storedef
tox
-
load from
x
→def
; implicit castdef
toint 1
; addint 1
andint 1
→int 2
; implicit castint 2
todef
; storedef
tox
-
Post Decrement
Use the post decrement operator '--'
to DECREASE the value of a numeric type
variable/field by 1
. An extra implicit cast is necessary to return the
promoted numeric type value to the original numeric type value of the
variable/field for the following types: byte
, short
, and char
. If a
variable/field is read as part of an expression the value is loaded prior to
the decrement.
Errors
-
If the variable/field is a non-numeric type.
Grammar
post_decrement: ( variable | field ) '--';
Promotion
original | promoted | implicit |
---|---|---|
byte |
int |
byte |
short |
int |
short |
char |
int |
char |
int |
int |
|
long |
long |
|
float |
float |
|
double |
double |
|
def |
def |
Examples
-
Post decrement with different numeric types.
short i = 0; (1) i--; (2) long j = 1; (3) long k; (4) k = j--; (5)
-
declare
short i
; storeshort 0
toi
-
load from
i
→short 0
; promoteshort 0
: resultint
; subtractint 1
fromint 0
→int -1
; implicit castint -1
toshort -1
; storeshort -1
toi
-
declare
long j
; implicit castint 1
tolong 1
→long 1
; storelong 1
toj
-
declare
long k
; store defaultlong 0
tok
-
load from
j
→long 1
; storelong 1
tok
; subtractlong 1
fromlong 1
→long 0
; storelong 0
toj
-
-
Post decrement with the
def
type.def x = 1; (1) x--; (2)
-
declare
def x
; implicit castint 1
todef
→def
; storedef
tox
-
load from
x
→def
; implicit castdef
toint 1
; subtractint 1
fromint 1
→int 0
; implicit castint 0
todef
; storedef
tox
-
Pre Increment
Use the pre increment operator '++'
to INCREASE the value of a numeric type
variable/field by 1
. An extra implicit cast is necessary to return the
promoted numeric type value to the original numeric type value of the
variable/field for the following types: byte
, short
, and char
. If a
variable/field is read as part of an expression the value is loaded after the
increment.
Errors
-
If the variable/field is a non-numeric type.
Grammar
pre_increment: '++' ( variable | field );
Promotion
original | promoted | implicit |
---|---|---|
byte |
int |
byte |
short |
int |
short |
char |
int |
char |
int |
int |
|
long |
long |
|
float |
float |
|
double |
double |
|
def |
def |
Examples
-
Pre increment with different numeric types.
short i = 0; (1) ++i; (2) long j = 1; (3) long k; (4) k = ++j; (5)
-
declare
short i
; storeshort 0
toi
-
load from
i
→short 0
; promoteshort 0
: resultint
; addint 0
andint 1
→int 1
; implicit castint 1
toshort 1
; storeshort 1
toi
-
declare
long j
; implicit castint 1
tolong 1
→long 1
; storelong 1
toj
-
declare
long k
; store defaultlong 0
tok
-
load from
j
→long 1
; addlong 1
andlong 1
→long 2
; storelong 2
toj
; storelong 2
tok
-
-
Pre increment with the
def
type.def x = 1; (1) ++x; (2)
-
declare
def x
; implicit castint 1
todef
→def
; storedef
tox
-
load from
x
→def
; implicit castdef
toint 1
; addint 1
andint 1
→int 2
; implicit castint 2
todef
; storedef
tox
-
Pre Decrement
Use the pre decrement operator '--'
to DECREASE the value of a numeric type
variable/field by 1
. An extra implicit cast is necessary to return the
promoted numeric type value to the original numeric type value of the
variable/field for the following types: byte
, short
, and char
. If a
variable/field is read as part of an expression the value is loaded after the
decrement.
Errors
-
If the variable/field is a non-numeric type.
Grammar
pre_increment: '--' ( variable | field );
Promotion
original | promoted | implicit |
---|---|---|
byte |
int |
byte |
short |
int |
short |
char |
int |
char |
int |
int |
|
long |
long |
|
float |
float |
|
double |
double |
|
def |
def |
Examples
-
Pre decrement with different numeric types.
short i = 0; (1) --i; (2) long j = 1; (3) long k; (4) k = --j; (5)
-
declare
short i
; storeshort 0
toi
-
load from
i
→short 0
; promoteshort 0
: resultint
; subtractint 1
fromint 0
→int -1
; implicit castint -1
toshort -1
; storeshort -1
toi
-
declare
long j
; implicit castint 1
tolong 1
→long 1
; storelong 1
toj
-
declare
long k
; store defaultlong 0
tok
-
load from
j
→long 1
; subtractlong 1
fromlong 1
→long 0
; storelong 0
toj
storelong 0
tok
;
-
-
Pre decrement operator with the
def
type.def x = 1; (1) --x; (2)
-
declare
def x
; implicit castint 1
todef
→def
; storedef
tox
-
load from
x
→def
; implicit castdef
toint 1
; subtractint 1
fromint 1
→int 0
; implicit castint 0
todef
; storedef
tox
-
Unary Positive
Use the unary positive operator '+'
to the preserve the IDENTITY of a
numeric type value.
Errors
-
If the value is a non-numeric type.
Grammar
unary_positive: '+' expression;
Examples
-
Unary positive with different numeric types.
int x = +1; (1) long y = +x; (2)
-
declare
int x
; identityint 1
→int 1
; storeint 1
tox
-
declare
long y
; load fromx
→int 1
; identityint 1
→int 1
; implicit castint 1
tolong 1
→long 1
; storelong 1
toy
-
-
Unary positive with the
def
type.def z = +1; (1) int i = +z; (2)
-
declare
def z
; identityint 1
→int 1
; implicit castint 1
todef
; storedef
toz
-
declare
int i
; load fromz
→def
; implicit castdef
toint 1
; identityint 1
→int 1
; storeint 1
toi
;
-
Unary Negative
Use the unary negative operator '-'
to NEGATE a numeric type value.
Errors
-
If the value is a non-numeric type.
Grammar
unary_negative: '-' expression;
Examples
-
Unary negative with different numeric types.
int x = -1; (1) long y = -x; (2)
-
declare
int x
; negateint 1
→int -1
; storeint -1
tox
-
declare
long y
; load fromx
→int 1
; negateint -1
→int 1
; implicit castint 1
tolong 1
→long 1
; storelong 1
toy
-
-
Unary negative with the
def
type.def z = -1; (1) int i = -z; (2)
-
declare
def z
; negateint 1
→int -1
; implicit castint -1
todef
; storedef
toz
-
declare
int i
; load fromz
→def
; implicit castdef
toint -1
; negateint -1
→int 1
; storeint 1
toi
;
-
Bitwise Not
Use the bitwise not operator '~'
to NOT each bit in an integer type value
where a 1-bit
is flipped to a resultant 0-bit
and a 0-bit
is flipped to a
resultant 1-bit
.
Errors
-
If the value is a non-integer type.
Bits
original | result |
---|---|
1 |
0 |
0 |
1 |
Grammar
bitwise_not: '~' expression;
Promotion
original | promoted |
---|---|
byte |
int |
short |
int |
char |
int |
int |
int |
long |
long |
def |
def |
Examples
-
Bitwise not with different numeric types.
byte b = 1; (1) int i = ~b; (2) long l = ~i; (3)
-
declare
byte x
; storebyte 1
to b -
declare
int i
; load fromb
→byte 1
; implicit castbyte 1
toint 1
→int 1
; bitwise notint 1
→int -2
; storeint -2
toi
-
declare
long l
; load fromi
→int -2
; implicit castint -2
tolong -2
→long -2
; bitwise notlong -2
→long 1
; storelong 1
tol
-
-
Bitwise not with the
def
type.def d = 1; (1) def e = ~d; (2)
-
declare
def d
; implicit castint 1
todef
→def
; storedef
tod
; -
declare
def e
; load fromd
→def
; implicit castdef
toint 1
→int 1
; bitwise notint 1
→int -2
; implicit castint 1
todef
→def
; storedef
toe
-
Multiplication
Use the multiplication operator '*'
to MULTIPLY together two numeric type
values. Rules for resultant overflow and NaN values follow the JVM
specification.
Errors
-
If either of the values is a non-numeric type.
Grammar
multiplication: expression '*' expression;
Promotion
byte |
short |
char |
int |
long |
float |
double |
def |
|
byte |
int |
int |
int |
int |
long |
float |
double |
def |
short |
int |
int |
int |
int |
long |
float |
double |
def |
char |
int |
int |
int |
int |
long |
float |
double |
def |
int |
int |
int |
int |
int |
long |
float |
double |
def |
long |
long |
long |
long |
long |
long |
float |
double |
def |
float |
float |
float |
float |
float |
float |
float |
double |
def |
double |
double |
double |
double |
double |
double |
double |
double |
def |
def |
def |
def |
def |
def |
def |
def |
def |
def |
Examples
-
Multiplication with different numeric types.
int i = 5*4; (1) double d = i*7.0; (2)
-
declare
int i
; multiplyint 4
byint 5
→int 20
; storeint 20
ini
-
declare
double d
; load fromint i
→int 20
; promoteint 20
anddouble 7.0
: resultdouble
; implicit castint 20
todouble 20.0
→double 20.0
; multiplydouble 20.0
bydouble 7.0
→double 140.0
; storedouble 140.0
tod
-
-
Multiplication with the
def
type.def x = 5*4; (1) def y = x*2; (2)
-
declare
def x
; multiplyint 5
byint 4
→int 20
; implicit castint 20
todef
→def
; storedef
inx
-
declare
def y
; load fromx
→def
; implicit castdef
toint 20
; multiplyint 20
byint 2
→int 40
; implicit castint 40
todef
→def
; storedef
toy
-
Division
Use the division operator '/'
to DIVIDE one numeric type value by another.
Rules for NaN values and division by zero follow the JVM specification. Division
with integer values drops the remainder of the resultant value.
Errors
-
If either of the values is a non-numeric type.
-
If a left-hand side integer type value is divided by a right-hand side integer type value of
0
.
Grammar
division: expression '/' expression;
Promotion
byte |
short |
char |
int |
long |
float |
double |
def |
|
byte |
int |
int |
int |
int |
long |
float |
double |
def |
short |
int |
int |
int |
int |
long |
float |
double |
def |
char |
int |
int |
int |
int |
long |
float |
double |
def |
int |
int |
int |
int |
int |
long |
float |
double |
def |
long |
long |
long |
long |
long |
long |
float |
double |
def |
float |
float |
float |
float |
float |
float |
float |
double |
def |
double |
double |
double |
double |
double |
double |
double |
double |
def |
def |
def |
def |
def |
def |
def |
def |
def |
def |
Examples
-
Division with different numeric types.
int i = 29/4; (1) double d = i/7.0; (2)
-
declare
int i
; divideint 29
byint 4
→int 7
; storeint 7
ini
-
declare
double d
; load fromint i
→int 7
; promoteint 7
anddouble 7.0
: resultdouble
; implicit castint 7
todouble 7.0
→double 7.0
; dividedouble 7.0
bydouble 7.0
→double 1.0
; storedouble 1.0
tod
-
-
Division with the
def
type.def x = 5/4; (1) def y = x/2; (2)
-
declare
def x
; divideint 5
byint 4
→int 1
; implicit castint 1
todef
→def
; storedef
inx
-
declare
def y
; load fromx
→def
; implicit castdef
toint 1
; divideint 1
byint 2
→int 0
; implicit castint 0
todef
→def
; storedef
toy
-
Remainder
Use the remainder operator '%'
to calculate the REMAINDER for division
between two numeric type values. Rules for NaN values and division by zero follow the JVM
specification.
Errors
-
If either of the values is a non-numeric type.
Grammar
remainder: expression '%' expression;
Promotion
byte |
short |
char |
int |
long |
float |
double |
def |
|
byte |
int |
int |
int |
int |
long |
float |
double |
def |
short |
int |
int |
int |
int |
long |
float |
double |
def |
char |
int |
int |
int |
int |
long |
float |
double |
def |
int |
int |
int |
int |
int |
long |
float |
double |
def |
long |
long |
long |
long |
long |
long |
float |
double |
def |
float |
float |
float |
float |
float |
float |
float |
double |
def |
double |
double |
double |
double |
double |
double |
double |
double |
def |
def |
def |
def |
def |
def |
def |
def |
def |
def |
Examples
-
Remainder with different numeric types.
int i = 29%4; (1) double d = i%7.0; (2)
-
declare
int i
; remainderint 29
byint 4
→int 1
; storeint 7
ini
-
declare
double d
; load fromint i
→int 1
; promoteint 1
anddouble 7.0
: resultdouble
; implicit castint 1
todouble 1.0
→double 1.0
; remainderdouble 1.0
bydouble 7.0
→double 1.0
; storedouble 1.0
tod
-
-
Remainder with the
def
type.def x = 5%4; (1) def y = x%2; (2)
-
declare
def x
; remainderint 5
byint 4
→int 1
; implicit castint 1
todef
→def
; storedef
inx
-
declare
def y
; load fromx
→def
; implicit castdef
toint 1
; remainderint 1
byint 2
→int 1
; implicit castint 1
todef
→def
; storedef
toy
-
Addition
Use the addition operator '+'
to ADD together two numeric type values. Rules
for resultant overflow and NaN values follow the JVM specification.
Errors
-
If either of the values is a non-numeric type.
Grammar
addition: expression '+' expression;
Promotion
byte |
short |
char |
int |
long |
float |
double |
def |
|
byte |
int |
int |
int |
int |
long |
float |
double |
def |
short |
int |
int |
int |
int |
long |
float |
double |
def |
char |
int |
int |
int |
int |
long |
float |
double |
def |
int |
int |
int |
int |
int |
long |
float |
double |
def |
long |
long |
long |
long |
long |
long |
float |
double |
def |
float |
float |
float |
float |
float |
float |
float |
double |
def |
double |
double |
double |
double |
double |
double |
double |
double |
def |
def |
def |
def |
def |
def |
def |
def |
def |
def |
Examples
-
Addition operator with different numeric types.
int i = 29+4; (1) double d = i+7.0; (2)
-
declare
int i
; addint 29
andint 4
→int 33
; storeint 33
ini
-
declare
double d
; load fromint i
→int 33
; promoteint 33
anddouble 7.0
: resultdouble
; implicit castint 33
todouble 33.0
→double 33.0
; adddouble 33.0
anddouble 7.0
→double 40.0
; storedouble 40.0
tod
-
-
Addition with the
def
type.def x = 5+4; (1) def y = x+2; (2)
-
declare
def x
; addint 5
andint 4
→int 9
; implicit castint 9
todef
→def
; storedef
inx
-
declare
def y
; load fromx
→def
; implicit castdef
toint 9
; addint 9
andint 2
→int 11
; implicit castint 11
todef
→def
; storedef
toy
-
Subtraction
Use the subtraction operator '-'
to SUBTRACT a right-hand side numeric type
value from a left-hand side numeric type value. Rules for resultant overflow
and NaN values follow the JVM specification.
Errors
-
If either of the values is a non-numeric type.
Grammar
subtraction: expression '-' expression;
Promotion
byte |
short |
char |
int |
long |
float |
double |
def |
|
byte |
int |
int |
int |
int |
long |
float |
double |
def |
short |
int |
int |
int |
int |
long |
float |
double |
def |
char |
int |
int |
int |
int |
long |
float |
double |
def |
int |
int |
int |
int |
int |
long |
float |
double |
def |
long |
long |
long |
long |
long |
long |
float |
double |
def |
float |
float |
float |
float |
float |
float |
float |
double |
def |
double |
double |
double |
double |
double |
double |
double |
double |
def |
def |
def |
def |
def |
def |
def |
def |
def |
def |
Examples
-
Subtraction with different numeric types.
int i = 29-4; (1) double d = i-7.5; (2)
-
declare
int i
; subtractint 4
fromint 29
→int 25
; storeint 25
ini
-
declare
double d
load fromint i
→int 25
; promoteint 25
anddouble 7.5
: resultdouble
; implicit castint 25
todouble 25.0
→double 25.0
; subtractdouble 33.0
bydouble 7.5
→double 25.5
; storedouble 25.5
tod
-
-
Subtraction with the
def
type.def x = 5-4; (1) def y = x-2; (2)
-
declare
def x
; subtractint 4
andint 5
→int 1
; implicit castint 1
todef
→def
; storedef
inx
-
declare
def y
; load fromx
→def
; implicit castdef
toint 1
; subtractint 2
fromint 1
→int -1
; implicit castint -1
todef
→def
; storedef
toy
-
Left Shift
Use the left shift operator '<<'
to SHIFT lower order bits to higher order
bits in a left-hand side integer type value by the distance specified in a
right-hand side integer type value.
Errors
-
If either of the values is a non-integer type.
-
If the right-hand side value cannot be cast to an int type.
Grammar
left_shift: expression '<<' expression;
Promotion
The left-hand side integer type value is promoted as specified in the table
below. The right-hand side integer type value is always implicitly cast to an
int
type value and truncated to the number of bits of the promoted type value.
original | promoted |
---|---|
byte |
int |
short |
int |
char |
int |
int |
int |
long |
long |
def |
def |
Examples
-
Left shift with different integer types.
int i = 4 << 1; (1) long l = i << 2L; (2)
-
declare
int i
; left shiftint 4
byint 1
→int 8
; storeint 8
ini
-
declare
long l
load fromint i
→int 8
; implicit castlong 2
toint 2
→int 2
; left shiftint 8
byint 2
→int 32
; implicit castint 32
tolong 32
→long 32
; storelong 32
tol
-
-
Left shift with the
def
type.def x = 4 << 2; (1) def y = x << 1; (2)
-
declare
def x
; left shiftint 4
byint 2
→int 16
; implicit castint 16
todef
→def
; storedef
inx
-
declare
def y
; load fromx
→def
; implicit castdef
toint 16
; left shiftint 16
byint 1
→int 32
; implicit castint 32
todef
→def
; storedef
toy
-
Right Shift
Use the right shift operator '>>'
to SHIFT higher order bits to lower order
bits in a left-hand side integer type value by the distance specified in a
right-hand side integer type value. The highest order bit of the left-hand side
integer type value is preserved.
Errors
-
If either of the values is a non-integer type.
-
If the right-hand side value cannot be cast to an int type.
Grammar
right_shift: expression '>>' expression;
Promotion
The left-hand side integer type value is promoted as specified in the table
below. The right-hand side integer type value is always implicitly cast to an
int
type value and truncated to the number of bits of the promoted type value.
original | promoted |
---|---|
byte |
int |
short |
int |
char |
int |
int |
int |
long |
long |
def |
def |
Examples
-
Right shift with different integer types.
int i = 32 >> 1; (1) long l = i >> 2L; (2)
-
declare
int i
; right shiftint 32
byint 1
→int 16
; storeint 16
ini
-
declare
long l
load fromint i
→int 16
; implicit castlong 2
toint 2
→int 2
; right shiftint 16
byint 2
→int 4
; implicit castint 4
tolong 4
→long 4
; storelong 4
tol
-
-
Right shift with the
def
type.def x = 16 >> 2; (1) def y = x >> 1; (2)
-
declare
def x
; right shiftint 16
byint 2
→int 4
; implicit castint 4
todef
→def
; storedef
inx
-
declare
def y
; load fromx
→def
; implicit castdef
toint 4
; right shiftint 4
byint 1
→int 2
; implicit castint 2
todef
→def
; storedef
toy
-
Unsigned Right Shift
Use the unsigned right shift operator '>>>'
to SHIFT higher order bits to
lower order bits in a left-hand side integer type value by the distance
specified in a right-hand side type integer value. The highest order bit of the
left-hand side integer type value is not preserved.
Errors
-
If either of the values is a non-integer type.
-
If the right-hand side value cannot be cast to an int type.
Grammar
unsigned_right_shift: expression '>>>' expression;
Promotion
The left-hand side integer type value is promoted as specified in the table
below. The right-hand side integer type value is always implicitly cast to an
int
type value and truncated to the number of bits of the promoted type value.
original | promoted |
---|---|
byte |
int |
short |
int |
char |
int |
int |
int |
long |
long |
def |
def |
Examples
-
Unsigned right shift with different integer types.
int i = -1 >>> 29; (1) long l = i >>> 2L; (2)
-
declare
int i
; unsigned right shiftint -1
byint 29
→int 7
; storeint 7
ini
-
declare
long l
load fromint i
→int 7
; implicit castlong 2
toint 2
→int 2
; unsigned right shiftint 7
byint 2
→int 3
; implicit castint 3
tolong 3
→long 3
; storelong 3
tol
-
-
Unsigned right shift with the
def
type.def x = 16 >>> 2; (1) def y = x >>> 1; (2)
-
declare
def x
; unsigned right shiftint 16
byint 2
→int 4
; implicit castint 4
todef
→def
; storedef
inx
-
declare
def y
; load fromx
→def
; implicit castdef
toint 4
; unsigned right shiftint 4
byint 1
→int 2
; implicit castint 2
todef
→def
; storedef
toy
-
Bitwise And
Use the bitwise and operator '&'
to AND together each bit within two
integer type values where if both bits at the same index are 1
the resultant
bit is 1
and 0
otherwise.
Errors
-
If either of the values is a non-integer type.
Bits
1 |
0 |
|
1 |
1 |
0 |
0 |
0 |
0 |
Grammar
bitwise_and: expression '&' expression;
Promotion
byte |
short |
char |
int |
long |
def |
|
byte |
int |
int |
int |
int |
long |
def |
short |
int |
int |
int |
int |
long |
def |
char |
int |
int |
int |
int |
long |
def |
int |
int |
int |
int |
int |
long |
def |
long |
long |
long |
long |
long |
long |
def |
def |
def |
def |
def |
def |
def |
def |
Examples
-
Bitwise and with different integer types.
int i = 5 & 6; (1) long l = i & 5L; (2)
-
declare
int i
; bitwise andint 5
andint 6
→int 4
; storeint 4
ini
-
declare
long l
load fromint i
→int 4
; promoteint 4
andlong 5
: resultlong
; implicit castint 4
tolong 4
→long 4
; bitwise andlong 4
andlong 5
→long 4
; storelong 4
tol
-
-
Bitwise and with the
def
type.def x = 15 & 6; (1) def y = x & 5; (2)
-
declare
def x
; bitwise andint 15
andint 6
→int 6
; implicit castint 6
todef
→def
; storedef
inx
-
declare
def y
; load fromx
→def
; implicit castdef
toint 6
; bitwise andint 6
andint 5
→int 4
; implicit castint 4
todef
→def
; storedef
toy
-
Bitwise Xor
Use the bitwise xor operator '^'
to XOR together each bit within two integer
type values where if one bit is a 1
and the other bit is a 0
at the same
index the resultant bit is 1
otherwise the resultant bit is 0
.
Errors
-
If either of the values is a non-integer type.
Bits
The following table illustrates the resultant bit from the xoring of two bits.
1 |
0 |
|
1 |
0 |
1 |
0 |
1 |
0 |
Grammar
bitwise_xor: expression '^' expression;
Promotion
byte |
short |
char |
int |
long |
def |
|
byte |
int |
int |
int |
int |
long |
def |
short |
int |
int |
int |
int |
long |
def |
char |
int |
int |
int |
int |
long |
def |
int |
int |
int |
int |
int |
long |
def |
long |
long |
long |
long |
long |
long |
def |
def |
def |
def |
def |
def |
def |
def |
Examples
-
Bitwise xor with different integer types.
int i = 5 ^ 6; (1) long l = i ^ 5L; (2)
-
declare
int i
; bitwise xorint 5
andint 6
→int 3
; storeint 3
ini
-
declare
long l
load fromint i
→int 4
; promoteint 3
andlong 5
: resultlong
; implicit castint 3
tolong 3
→long 3
; bitwise xorlong 3
andlong 5
→long 6
; storelong 6
tol
-
-
Bitwise xor with the
def
type.def x = 15 ^ 6; (1) def y = x ^ 5; (2)
-
declare
def x
; bitwise xorint 15
andint 6
→int 9
; implicit castint 9
todef
→def
; storedef
inx
-
declare
def y
; load fromx
→def
; implicit castdef
toint 9
; bitwise xorint 9
andint 5
→int 12
; implicit castint 12
todef
→def
; storedef
toy
-
Bitwise Or
Use the bitwise or operator '|'
to OR together each bit within two integer
type values where if at least one bit is a 1
at the same index the resultant
bit is 1
otherwise the resultant bit is 0
.
Errors
-
If either of the values is a non-integer type.
Bits
The following table illustrates the resultant bit from the oring of two bits.
1 |
0 |
|
1 |
1 |
1 |
0 |
1 |
0 |
Grammar
bitwise_or: expression '|' expression;
Promotion
byte |
short |
char |
int |
long |
def |
|
byte |
int |
int |
int |
int |
long |
def |
short |
int |
int |
int |
int |
long |
def |
char |
int |
int |
int |
int |
long |
def |
int |
int |
int |
int |
int |
long |
def |
long |
long |
long |
long |
long |
long |
def |
def |
def |
def |
def |
def |
def |
def |
Examples
-
Bitwise or with different integer types.
int i = 5 | 6; (1) long l = i | 8L; (2)
-
declare
int i
; bitwise orint 5
andint 6
→int 7
; storeint 7
ini
-
declare
long l
load fromint i
→int 7
; promoteint 7
andlong 8
: resultlong
; implicit castint 7
tolong 7
→long 7
; bitwise orlong 7
andlong 8
→long 15
; storelong 15
tol
-
-
Bitwise or with the
def
type.def x = 5 ^ 6; (1) def y = x ^ 8; (2)
-
declare
def x
; bitwise orint 5
andint 6
→int 7
; implicit castint 7
todef
→def
; storedef
inx
-
declare
def y
; load fromx
→def
; implicit castdef
toint 7
; bitwise orint 7
andint 8
→int 15
; implicit castint 15
todef
→def
; storedef
toy
-
Operators: Boolean
Boolean Not
Use the boolean not operator '!'
to NOT a boolean
type value where true
is
flipped to false
and false
is flipped to true
.
Errors
-
If a value other than a
boolean
type value or a value that is castable to aboolean
type value is given.
Truth
original | result |
---|---|
true |
false |
false |
true |
Grammar
boolean_not: '!' expression;
Examples
-
Boolean not with the
boolean
type.boolean x = !false; (1) boolean y = !x; (2)
-
declare
boolean x
; boolean notboolean false
→boolean true
; storeboolean true
tox
-
declare
boolean y
; load fromx
→boolean true
; boolean notboolean true
→boolean false
; storeboolean false
toy
-
-
Boolean not with the
def
type.def y = true; (1) def z = !y; (2)
-
declare
def y
; implicit castboolean true
todef
→def
; storetrue
toy
-
declare
def z
; load fromy
→def
; implicit castdef
toboolean true
→ booleantrue
; boolean notboolean true
→boolean false
; implicit castboolean false
todef
→def
; storedef
toz
-
Greater Than
Use the greater than operator '>'
to COMPARE two numeric type values where a
resultant boolean
type value is true
if the left-hand side value is greater
than to the right-hand side value and false
otherwise.
Errors
-
If either the evaluated left-hand side or the evaluated right-hand side is a non-numeric value.
Grammar
greater_than: expression '>' expression;
Promotion
byte |
short |
char |
int |
long |
float |
double |
def |
|
byte |
int |
int |
int |
int |
long |
float |
double |
def |
short |
int |
int |
int |
int |
long |
float |
double |
def |
char |
int |
int |
int |
int |
long |
float |
double |
def |
int |
int |
int |
int |
int |
long |
float |
double |
def |
long |
long |
long |
long |
long |
long |
float |
double |
def |
float |
float |
float |
float |
float |
float |
float |
double |
def |
double |
double |
double |
double |
double |
double |
double |
double |
def |
def |
def |
def |
def |
def |
def |
def |
def |
def |
Examples
-
Greater than with different numeric types.
boolean x = 5 > 4; (1) double y = 6.0; (2) x = 6 > y; (3)
-
declare
boolean x
; greater thanint 5
andint 4
→boolean true
; storeboolean true
tox
; -
declare
double y
; storedouble 6.0
toy
; -
load from
y
→double 6.0 @0
; promoteint 6
anddouble 6.0
: resultdouble
; implicit castint 6
todouble 6.0 @1
→double 6.0 @1
; greater thandouble 6.0 @1
anddouble 6.0 @0
→boolean false
; storeboolean false
tox
-
-
Greater than with
def
type.int x = 5; (1) def y = 7.0; (2) def z = y > 6.5; (3) def a = x > y; (4)
-
declare
int x
; storeint 5
tox
-
declare
def y
; implicit castdouble 7.0
todef
→def
; storedef
toy
-
declare
def z
; load fromy
→def
; implicit castdef
todouble 7.0
→double 7.0
; greater thandouble 7.0
anddouble 6.5
→boolean true
; implicit castboolean true
todef
→def
; storedef
toz
-
declare
def a
; load fromy
→def
; implicit castdef
todouble 7.0
→double 7.0
; load fromx
→int 5
; promoteint 5
anddouble 7.0
: resultdouble
; implicit castint 5
todouble 5.0
→double 5.0
; greater thandouble 5.0
anddouble 7.0
→boolean false
; implicit castboolean false
todef
→def
; storedef
toz
-
Greater Than Or Equal
Use the greater than or equal operator '>='
to COMPARE two numeric type values
where a resultant boolean
type value is true
if the left-hand side value is
greater than or equal to the right-hand side value and false
otherwise.
Errors
-
If either the evaluated left-hand side or the evaluated right-hand side is a non-numeric value.
Grammar
greater_than_or_equal: expression '>=' expression;
Promotion
byte |
short |
char |
int |
long |
float |
double |
def |
|
byte |
int |
int |
int |
int |
long |
float |
double |
def |
short |
int |
int |
int |
int |
long |
float |
double |
def |
char |
int |
int |
int |
int |
long |
float |
double |
def |
int |
int |
int |
int |
int |
long |
float |
double |
def |
long |
long |
long |
long |
long |
long |
float |
double |
def |
float |
float |
float |
float |
float |
float |
float |
double |
def |
double |
double |
double |
double |
double |
double |
double |
double |
def |
def |
def |
def |
def |
def |
def |
def |
def |
def |
Examples
-
Greater than or equal with different numeric types.
boolean x = 5 >= 4; (1) double y = 6.0; (2) x = 6 >= y; (3)
-
declare
boolean x
; greater than or equalint 5
andint 4
→boolean true
; storeboolean true
tox
-
declare
double y
; storedouble 6.0
toy
-
load from
y
→double 6.0 @0
; promoteint 6
anddouble 6.0
: resultdouble
; implicit castint 6
todouble 6.0 @1
→double 6.0 @1
; greater than or equaldouble 6.0 @1
anddouble 6.0 @0
→boolean true
; storeboolean true
tox
-
-
Greater than or equal with the
def
type.int x = 5; (1) def y = 7.0; (2) def z = y >= 7.0; (3) def a = x >= y; (4)
-
declare
int x
; storeint 5
tox
; -
declare
def y
implicit castdouble 7.0
todef
→def
; storedef
toy
-
declare
def z
; load fromy
→def
; implicit castdef
todouble 7.0 @0
→double 7.0 @0
; greater than or equaldouble 7.0 @0
anddouble 7.0 @1
→boolean true
; implicit castboolean true
todef
→def
; storedef
toz
-
declare
def a
; load fromy
→def
; implicit castdef
todouble 7.0
→double 7.0
; load fromx
→int 5
; promoteint 5
anddouble 7.0
: resultdouble
; implicit castint 5
todouble 5.0
→double 5.0
; greater than or equaldouble 5.0
anddouble 7.0
→boolean false
; implicit castboolean false
todef
→def
; storedef
toz
-
Less Than
Use the less than operator '<'
to COMPARE two numeric type values where a
resultant boolean
type value is true
if the left-hand side value is less
than to the right-hand side value and false
otherwise.
Errors
-
If either the evaluated left-hand side or the evaluated right-hand side is a non-numeric value.
Grammar
less_than: expression '<' expression;
Promotion
byte |
short |
char |
int |
long |
float |
double |
def |
|
byte |
int |
int |
int |
int |
long |
float |
double |
def |
short |
int |
int |
int |
int |
long |
float |
double |
def |
char |
int |
int |
int |
int |
long |
float |
double |
def |
int |
int |
int |
int |
int |
long |
float |
double |
def |
long |
long |
long |
long |
long |
long |
float |
double |
def |
float |
float |
float |
float |
float |
float |
float |
double |
def |
double |
double |
double |
double |
double |
double |
double |
double |
def |
def |
def |
def |
def |
def |
def |
def |
def |
def |
Examples
-
Less than with different numeric types.
boolean x = 5 < 4; (1) double y = 6.0; (2) x = 6 < y; (3)
-
declare
boolean x
; less thanint 5
andint 4
→boolean false
; storeboolean false
tox
-
declare
double y
; storedouble 6.0
toy
-
load from
y
→double 6.0 @0
; promoteint 6
anddouble 6.0
: resultdouble
; implicit castint 6
todouble 6.0 @1
→double 6.0 @1
; less thandouble 6.0 @1
anddouble 6.0 @0
→boolean false
; storeboolean false
tox
-
-
Less than with the
def
type.int x = 5; (1) def y = 7.0; (2) def z = y < 6.5; (3) def a = x < y; (4)
-
declare
int x
; storeint 5
tox
-
declare
def y
; implicit castdouble 7.0
todef
→def
; storedef
toy
-
declare
def z
; load fromy
→def
; implicit castdef
todouble 7.0
→double 7.0
; less thandouble 7.0
anddouble 6.5
→boolean false
; implicit castboolean false
todef
→def
; storedef
toz
-
declare
def a
; load fromy
→def
; implicit castdef
todouble 7.0
→double 7.0
; load fromx
→int 5
; promoteint 5
anddouble 7.0
: resultdouble
; implicit castint 5
todouble 5.0
→double 5.0
; less thandouble 5.0
anddouble 7.0
→boolean true
; implicit castboolean true
todef
→def
; storedef
toz
-
Less Than Or Equal
Use the less than or equal operator '⇐'
to COMPARE two numeric type values
where a resultant boolean
type value is true
if the left-hand side value is
less than or equal to the right-hand side value and false
otherwise.
Errors
-
If either the evaluated left-hand side or the evaluated right-hand side is a non-numeric value.
Grammar
greater_than_or_equal: expression '<=' expression;
Promotion
byte |
short |
char |
int |
long |
float |
double |
def |
|
byte |
int |
int |
int |
int |
long |
float |
double |
def |
short |
int |
int |
int |
int |
long |
float |
double |
def |
char |
int |
int |
int |
int |
long |
float |
double |
def |
int |
int |
int |
int |
int |
long |
float |
double |
def |
long |
long |
long |
long |
long |
long |
float |
double |
def |
float |
float |
float |
float |
float |
float |
float |
double |
def |
double |
double |
double |
double |
double |
double |
double |
double |
def |
def |
def |
def |
def |
def |
def |
def |
def |
def |
Examples
-
Less than or equal with different numeric types.
boolean x = 5 <= 4; (1) double y = 6.0; (2) x = 6 <= y; (3)
-
declare
boolean x
; less than or equalint 5
andint 4
→boolean false
; storeboolean true
tox
-
declare
double y
; storedouble 6.0
toy
-
load from
y
→double 6.0 @0
; promoteint 6
anddouble 6.0
: resultdouble
; implicit castint 6
todouble 6.0 @1
→double 6.0 @1
; less than or equaldouble 6.0 @1
anddouble 6.0 @0
→boolean true
; storeboolean true
tox
-
-
Less than or equal with the
def
type.int x = 5; (1) def y = 7.0; (2) def z = y <= 7.0; (3) def a = x <= y; (4)
-
declare
int x
; storeint 5
tox
; -
declare
def y
; implicit castdouble 7.0
todef
→def
; storedef
toy
; -
declare
def z
; load fromy
→def
; implicit castdef
todouble 7.0 @0
→double 7.0 @0
; less than or equaldouble 7.0 @0
anddouble 7.0 @1
→boolean true
; implicit castboolean true
todef
→def
; storedef
toz
-
declare
def a
; load fromy
→def
; implicit castdef
todouble 7.0
→double 7.0
; load fromx
→int 5
; promoteint 5
anddouble 7.0
: resultdouble
; implicit castint 5
todouble 5.0
→double 5.0
; less than or equaldouble 5.0
anddouble 7.0
→boolean true
; implicit castboolean true
todef
→def
; storedef
toz
-
Instanceof
Use the instanceof operator
to COMPARE the variable/field type to a
specified reference type using the reference type name where a resultant
boolean
type value is true
if the variable/field type is the same as or a
descendant of the specified reference type and false otherwise.
Errors
-
If the reference type name doesn’t exist as specified by the right-hand side.
Grammar
instance_of: ID 'instanceof' TYPE;
Examples
-
Instance of with different reference types.
Map m = new HashMap(); (1) boolean a = m instanceof HashMap; (2) boolean b = m instanceof Map; (3)
-
declare
Map m
; allocateHashMap
instance →HashMap reference
; implicit castHashMap reference
toMap reference
; storeMap reference
tom
-
declare
boolean a
; load fromm
→Map reference
; implicit castMap reference
toHashMap reference
→HashMap reference
; instanceofHashMap reference
andHashMap
→boolean true
; storeboolean true
toa
-
declare
boolean b
; load fromm
→Map reference
; implicit castMap reference
toHashMap reference
→HashMap reference
; instanceofHashMap reference
andMap
→boolean true
; storetrue
tob
; (noteHashMap
is a descendant ofMap
)
-
-
Instance of with the
def
type.def d = new ArrayList(); (1) boolean a = d instanceof List; (2) boolean b = d instanceof Map; (3)
-
declare
def d
; allocateArrayList
instance →ArrayList reference
; implicit castArrayList reference
todef
→def
; storedef
tod
-
declare
boolean a
; load fromd
→def
; implicit castdef
toArrayList reference
→ArrayList reference
; instanceofArrayList reference
andList
→boolean true
; storeboolean true
toa
; (noteArrayList
is a descendant ofList
) -
declare
boolean b
; load fromd
→def
; implicit castdef
toArrayList reference
→ArrayList reference
; instanceofArrayList reference
andMap
→boolean false
; storeboolean false
toa
; (noteArrayList
is not a descendant ofMap
)
-
Equality Equals
Use the equality equals operator '=='
to COMPARE two values where a resultant
boolean
type value is true
if the two values are equal and false
otherwise. The member method, equals
, is implicitly called when the values are
reference type values where the first value is the target of the call and the
second value is the argument. This operation is null-safe where if both values
are null
the resultant boolean
type value is true
, and if only one value
is null
the resultant boolean
type value is false
. A valid comparison is
between boolean
type values, numeric type values, or reference type values.
Errors
-
If a comparison is made between a
boolean
type value and numeric type value. -
If a comparison is made between a primitive type value and a reference type value.
Grammar
equality_equals: expression '==' expression;
Promotion
boolean |
byte |
short |
char |
int |
long |
float |
double |
Reference |
def |
|
boolean |
boolean |
- |
- |
- |
- |
- |
- |
- |
- |
def |
byte |
- |
int |
int |
int |
int |
long |
float |
double |
- |
def |
short |
- |
int |
int |
int |
int |
long |
float |
double |
- |
def |
char |
- |
int |
int |
int |
int |
long |
float |
double |
- |
def |
int |
- |
int |
int |
int |
int |
long |
float |
double |
- |
def |
long |
- |
long |
long |
long |
long |
long |
float |
double |
- |
def |
float |
- |
float |
float |
float |
float |
float |
float |
double |
- |
def |
double |
- |
double |
double |
double |
double |
double |
double |
double |
- |
def |
Reference |
- |
- |
- |
- |
- |
- |
- |
- |
Object |
def |
def |
def |
def |
def |
def |
def |
def |
def |
def |
def |
def |
Examples
-
Equality equals with the
boolean
type.boolean a = true; (1) boolean b = false; (2) a = a == false; (3) b = a == b; (4)
-
declare
boolean a
; storeboolean true
toa
-
declare
boolean b
; storeboolean false
tob
-
load from
a
→boolean true
; equality equalsboolean true
andboolean false
→boolean false
; storeboolean false
toa
-
load from
a
→boolean false @0
; load fromb
→boolean false @1
; equality equalsboolean false @0
andboolean false @1
→boolean false
; storeboolean false
tob
-
-
Equality equals with primitive types.
int a = 1; (1) double b = 2.0; (2) boolean c = a == b; (3) c = 1 == a; (4)
-
declare
int a
; storeint 1
toa
-
declare
double b
; storedouble 1.0
tob
-
declare
boolean c
; load froma
→int 1
; load fromb
→double 2.0
; promoteint 1
anddouble 2.0
: resultdouble
; implicit castint 1
todouble 1.0
→double `1.0
; equality equalsdouble 1.0
anddouble 2.0
→boolean false
; storeboolean false
toc
-
load from
a
→int 1 @1
; equality equalsint 1 @0
andint 1 @1
→boolean true
; storeboolean true
toc
-
-
Equal equals with reference types.
List a = new ArrayList(); (1) List b = new ArrayList(); (2) a.add(1); (3) boolean c = a == b; (4) b.add(1); (5) c = a == b; (6)
-
declare
List a
; allocateArrayList
instance →ArrayList reference
; implicit castArrayList reference
toList reference
→List reference
; storeList reference
toa
-
declare
List b
; allocateArrayList
instance →ArrayList reference
; implicit castArrayList reference
toList reference
→List reference
; storeList reference
tob
-
load from
a
→List reference
; calladd
onList reference
with arguments (int 1)
-
declare
boolean c
; load froma
→List reference @0
; load fromb
→List reference @1
; callequals
onList reference @0
with arguments (List reference @1
) →boolean false
; storeboolean false
toc
-
load from
b
→List reference
; calladd
onList reference
with arguments (int 1
) -
load from
a
→List reference @0
; load fromb
→List reference @1
; callequals
onList reference @0
with arguments (List reference @1
) →boolean true
; storeboolean true
toc
-
-
Equality equals with
null
.Object a = null; (1) Object b = null; (2) boolean c = a == null; (3) c = a == b; (4) b = new Object(); (5) c = a == b; (6)
-
declare
Object a
; storenull
toa
-
declare
Object b
; storenull
tob
-
declare
boolean c
; load froma
→null @0
; equality equalsnull @0
andnull @1
→boolean true
; storeboolean true
toc
-
load from
a
→null @0
; load fromb
→null @1
; equality equalsnull @0
andnull @1
→boolean true
; storeboolean true
toc
-
allocate
Object
instance →Object reference
; storeObject reference
tob
-
load from
a
→Object reference
; load fromb
→null
; callequals
onObject reference
with arguments (null
) →boolean false
; storeboolean false
toc
-
-
Equality equals with the
def
type.def a = 0; (1) def b = 1; (2) boolean c = a == b; (3) def d = new HashMap(); (4) def e = new ArrayList(); (5) c = d == e; (6)
-
declare
def a
; implicit castint 0
todef
→def
; storedef
toa
; -
declare
def b
; implicit castint 1
todef
→def
; storedef
tob
; -
declare
boolean c
; load froma
→def
; implicit casta
toint 0
→int 0
; load fromb
→def
; implicit castb
toint 1
→int 1
; equality equalsint 0
andint 1
→boolean false
; storeboolean false
toc
-
declare
def d
; allocateHashMap
instance →HashMap reference
; implicit castHashMap reference
todef
→def
storedef
tod
; -
declare
def e
; allocateArrayList
instance →ArrayList reference
; implicit castArrayList reference
todef
→def
storedef
tod
; -
load from
d
→def
; implicit castdef
toHashMap reference
→HashMap reference
; load frome
→def
; implicit castdef
toArrayList reference
→ArrayList reference
; callequals
onHashMap reference
with arguments (ArrayList reference
) →boolean false
; storeboolean false
toc
-
Equality Not Equals
Use the equality not equals operator '!='
to COMPARE two values where a
resultant boolean
type value is true
if the two values are NOT equal and
false
otherwise. The member method, equals
, is implicitly called when the
values are reference type values where the first value is the target of the call
and the second value is the argument with the resultant boolean
type value
flipped. This operation is null-safe
where if both values are null
the
resultant boolean
type value is false
, and if only one value is null
the
resultant boolean
type value is true
. A valid comparison is between boolean
type values, numeric type values, or reference type values.
Errors
-
If a comparison is made between a
boolean
type value and numeric type value. -
If a comparison is made between a primitive type value and a reference type value.
Grammar
equality_not_equals: expression '!=' expression;
Promotion
boolean |
byte |
short |
char |
int |
long |
float |
double |
Reference |
def |
|
boolean |
boolean |
- |
- |
- |
- |
- |
- |
- |
- |
def |
byte |
- |
int |
int |
int |
int |
long |
float |
double |
- |
def |
short |
- |
int |
int |
int |
int |
long |
float |
double |
- |
def |
char |
- |
int |
int |
int |
int |
long |
float |
double |
- |
def |
int |
- |
int |
int |
int |
int |
long |
float |
double |
- |
def |
long |
- |
long |
long |
long |
long |
long |
float |
double |
- |
def |
float |
- |
float |
float |
float |
float |
float |
float |
double |
- |
def |
double |
- |
double |
double |
double |
double |
double |
double |
double |
- |
def |
Reference |
- |
- |
- |
- |
- |
- |
- |
- |
Object |
def |
def |
def |
def |
def |
def |
def |
def |
def |
def |
def |
def |
Examples
-
Equality not equals with the
boolean
type.boolean a = true; (1) boolean b = false; (2) a = a != false; (3) b = a != b; (4)
-
declare
boolean a
; storeboolean true
toa
-
declare
boolean b
; storeboolean false
tob
-
load from
a
→boolean true
; equality not equalsboolean true
andboolean false
→boolean true
; storeboolean true
toa
-
load from
a
→boolean true
; load fromb
→boolean false
; equality not equalsboolean true
andboolean false
→boolean true
; storeboolean true
tob
-
-
Equality not equals with primitive types.
int a = 1; (1) double b = 2.0; (2) boolean c = a != b; (3) c = 1 != a; (4)
-
declare
int a
; storeint 1
toa
-
declare
double b
; storedouble 1.0
tob
-
declare
boolean c
; load froma
→int 1
; load fromb
→double 2.0
; promoteint 1
anddouble 2.0
: resultdouble
; implicit castint 1
todouble 1.0
→double `1.0
; equality not equalsdouble 1.0
anddouble 2.0
→boolean true
; storeboolean true
toc
-
load from
a
→int 1 @1
; equality not equalsint 1 @0
andint 1 @1
→boolean false
; storeboolean false
toc
-
-
Equality not equals with reference types.
List a = new ArrayList(); (1) List b = new ArrayList(); (2) a.add(1); (3) boolean c = a == b; (4) b.add(1); (5) c = a == b; (6)
-
declare
List a
; allocateArrayList
instance →ArrayList reference
; implicit castArrayList reference
toList reference
→List reference
; storeList reference
toa
-
declare
List b
; allocateArrayList
instance →ArrayList reference
; implicit castArrayList reference
toList reference
→List reference
; storeList reference
tob
-
load from
a
→List reference
; calladd
onList reference
with arguments (int 1)
-
declare
boolean c
; load froma
→List reference @0
; load fromb
→List reference @1
; callequals
onList reference @0
with arguments (List reference @1
) →boolean false
; boolean notboolean false
→boolean true
storeboolean true
toc
-
load from
b
→List reference
; calladd
onList reference
with arguments (int 1
) -
load from
a
→List reference @0
; load fromb
→List reference @1
; callequals
onList reference @0
with arguments (List reference @1
) →boolean true
; boolean notboolean true
→boolean false
; storeboolean false
toc
-
-
Equality not equals with
null
.Object a = null; (1) Object b = null; (2) boolean c = a == null; (3) c = a == b; (4) b = new Object(); (5) c = a == b; (6)
-
declare
Object a
; storenull
toa
-
declare
Object b
; storenull
tob
-
declare
boolean c
; load froma
→null @0
; equality not equalsnull @0
andnull @1
→boolean false
; storeboolean false
toc
-
load from
a
→null @0
; load fromb
→null @1
; equality not equalsnull @0
andnull @1
→boolean false
; storeboolean false
toc
-
allocate
Object
instance →Object reference
; storeObject reference
tob
-
load from
a
→Object reference
; load fromb
→null
; callequals
onObject reference
with arguments (null
) →boolean false
; boolean notboolean false
→boolean true
; storeboolean true
toc
-
-
Equality not equals with the
def
type.def a = 0; (1) def b = 1; (2) boolean c = a == b; (3) def d = new HashMap(); (4) def e = new ArrayList(); (5) c = d == e; (6)
-
declare
def a
; implicit castint 0
todef
→def
; storedef
toa
; -
declare
def b
; implicit castint 1
todef
→def
; storedef
tob
; -
declare
boolean c
; load froma
→def
; implicit casta
toint 0
→int 0
; load fromb
→def
; implicit castb
toint 1
→int 1
; equality equalsint 0
andint 1
→boolean false
; storeboolean false
toc
-
declare
def d
; allocateHashMap
instance →HashMap reference
; implicit castHashMap reference
todef
→def
storedef
tod
; -
declare
def e
; allocateArrayList
instance →ArrayList reference
; implicit castArrayList reference
todef
→def
storedef
tod
; -
load from
d
→def
; implicit castdef
toHashMap reference
→HashMap reference
; load frome
→def
; implicit castdef
toArrayList reference
→ArrayList reference
; callequals
onHashMap reference
with arguments (ArrayList reference
) →boolean false
; storeboolean false
toc
-
Identity Equals
Use the identity equals operator '==='
to COMPARE two values where a resultant
boolean
type value is true
if the two values are equal and false
otherwise. A reference type value is equal to another reference type value if
both values refer to same instance on the heap or if both values are null
. A
valid comparison is between boolean
type values, numeric type values, or
reference type values.
Errors
-
If a comparison is made between a
boolean
type value and numeric type value. -
If a comparison is made between a primitive type value and a reference type value.
Grammar
identity_equals: expression '===' expression;
Promotion
boolean |
byte |
short |
char |
int |
long |
float |
double |
Reference |
def |
|
boolean |
boolean |
- |
- |
- |
- |
- |
- |
- |
- |
def |
byte |
- |
int |
int |
int |
int |
long |
float |
double |
- |
def |
short |
- |
int |
int |
int |
int |
long |
float |
double |
- |
def |
char |
- |
int |
int |
int |
int |
long |
float |
double |
- |
def |
int |
- |
int |
int |
int |
int |
long |
float |
double |
- |
def |
long |
- |
long |
long |
long |
long |
long |
float |
double |
- |
def |
float |
- |
float |
float |
float |
float |
float |
float |
double |
- |
def |
double |
- |
double |
double |
double |
double |
double |
double |
double |
- |
def |
Reference |
- |
- |
- |
- |
- |
- |
- |
- |
Object |
def |
def |
def |
def |
def |
def |
def |
def |
def |
def |
def |
def |
Examples
-
Identity equals with reference types.
List a = new ArrayList(); (1) List b = new ArrayList(); (2) List c = a; (3) boolean c = a === b; (4) c = a === c; (5)
-
declare
List a
; allocateArrayList
instance →ArrayList reference
; implicit castArrayList reference
toList reference
→List reference
; storeList reference
toa
-
declare
List b
; allocateArrayList
instance →ArrayList reference
; implicit castArrayList reference
toList reference
→List reference
; storeList reference
tob
-
load from
a
→List reference
; storeList reference
toc
-
declare
boolean c
; load froma
→List reference @0
; load fromb
→List reference @1
; identity equalsList reference @0
andList reference @1
→boolean false
storeboolean false
toc
-
load from
a
→List reference @0
; load fromc
→List reference @1
; identity equalsList reference @0
andList reference @1
→boolean true
storeboolean true
toc
(noteList reference @0
andList reference @1
refer to the same instance)
-
-
Identity equals with
null
.Object a = null; (1) Object b = null; (2) boolean c = a === null; (3) c = a === b; (4) b = new Object(); (5) c = a === b; (6)
-
declare
Object a
; storenull
toa
-
declare
Object b
; storenull
tob
-
declare
boolean c
; load froma
→null @0
; identity equalsnull @0
andnull @1
→boolean true
; storeboolean true
toc
-
load from
a
→null @0
; load fromb
→null @1
; identity equalsnull @0
andnull @1
→boolean true
; storeboolean true
toc
-
allocate
Object
instance →Object reference
; storeObject reference
tob
-
load from
a
→Object reference
; load fromb
→null
; identity equalsObject reference
andnull
→boolean false
; storeboolean false
toc
-
-
Identity equals with the
def
type.def a = new HashMap(); (1) def b = new ArrayList(); (2) boolean c = a === b; (3) b = a; (4) c = a === b; (5)
-
declare
def d
; allocateHashMap
instance →HashMap reference
; implicit castHashMap reference
todef
→def
storedef
tod
-
declare
def e
; allocateArrayList
instance →ArrayList reference
; implicit castArrayList reference
todef
→def
storedef
tod
-
declare
boolean c
; load froma
→def
; implicit castdef
toHashMap reference
→HashMap reference
; load fromb
→def
; implicit castdef
toArrayList reference
→ArrayList reference
; identity equalsHashMap reference
andArrayList reference
→boolean false
; storeboolean false
toc
-
load from
a
→def
; storedef
tob
-
load from
a
→def
; implicit castdef
toHashMap reference @0
→HashMap reference @0
; load fromb
→def
; implicit castdef
toHashMap reference @1
→HashMap reference @1
; identity equalsHashMap reference @0
andHashMap reference @1
→boolean true
; storeboolean true
tob
; (noteHashMap reference @0
andHashMap reference @1
refer to the same instance)
-
Identity Not Equals
Use the identity not equals operator '!=='
to COMPARE two values where a
resultant boolean
type value is true
if the two values are NOT equal and
false
otherwise. A reference type value is not equal to another reference type
value if both values refer to different instances on the heap or if one value is
null
and the other is not. A valid comparison is between boolean
type
values, numeric type values, or reference type values.
Errors
-
If a comparison is made between a
boolean
type value and numeric type value. -
If a comparison is made between a primitive type value and a reference type value.
Grammar
identity_not_equals: expression '!==' expression;
Promotion
boolean |
byte |
short |
char |
int |
long |
float |
double |
Reference |
def |
|
boolean |
boolean |
- |
- |
- |
- |
- |
- |
- |
- |
def |
byte |
- |
int |
int |
int |
int |
long |
float |
double |
- |
def |
short |
- |
int |
int |
int |
int |
long |
float |
double |
- |
def |
char |
- |
int |
int |
int |
int |
long |
float |
double |
- |
def |
int |
- |
int |
int |
int |
int |
long |
float |
double |
- |
def |
long |
- |
long |
long |
long |
long |
long |
float |
double |
- |
def |
float |
- |
float |
float |
float |
float |
float |
float |
double |
- |
def |
double |
- |
double |
double |
double |
double |
double |
double |
double |
- |
def |
Reference |
- |
- |
- |
- |
- |
- |
- |
- |
Object |
def |
def |
def |
def |
def |
def |
def |
def |
def |
def |
def |
def |
Examples
-
Identity not equals with reference type values.
List a = new ArrayList(); (1) List b = new ArrayList(); (2) List c = a; (3) boolean c = a !== b; (4) c = a !== c; (5)
-
declare
List a
; allocateArrayList
instance →ArrayList reference
; implicit castArrayList reference
toList reference
→List reference
; storeList reference
toa
-
declare
List b
; allocateArrayList
instance →ArrayList reference
; implicit castArrayList reference
toList reference
→List reference
; storeList reference
tob
-
load from
a
→List reference
; storeList reference
toc
-
declare
boolean c
; load froma
→List reference @0
; load fromb
→List reference @1
; identity not equalsList reference @0
andList reference @1
→boolean true
storeboolean true
toc
-
load from
a
→List reference @0
; load fromc
→List reference @1
; identity not equalsList reference @0
andList reference @1
→boolean false
storeboolean false
toc
(noteList reference @0
andList reference @1
refer to the same instance)
-
-
Identity not equals with
null
.Object a = null; (1) Object b = null; (2) boolean c = a !== null; (3) c = a !== b; (4) b = new Object(); (5) c = a !== b; (6)
-
declare
Object a
; storenull
toa
-
declare
Object b
; storenull
tob
-
declare
boolean c
; load froma
→null @0
; identity not equalsnull @0
andnull @1
→boolean false
; storeboolean false
toc
-
load from
a
→null @0
; load fromb
→null @1
; identity not equalsnull @0
andnull @1
→boolean false
; storeboolean false
toc
-
allocate
Object
instance →Object reference
; storeObject reference
tob
-
load from
a
→Object reference
; load fromb
→null
; identity not equalsObject reference
andnull
→boolean true
; storeboolean true
toc
-
-
Identity not equals with the
def
type.def a = new HashMap(); (1) def b = new ArrayList(); (2) boolean c = a !== b; (3) b = a; (4) c = a !== b; (5)
-
declare
def d
; allocateHashMap
instance →HashMap reference
; implicit castHashMap reference
todef
→def
storedef
tod
-
declare
def e
; allocateArrayList
instance →ArrayList reference
; implicit castArrayList reference
todef
→def
storedef
tod
-
declare
boolean c
; load froma
→def
; implicit castdef
toHashMap reference
→HashMap reference
; load fromb
→def
; implicit castdef
toArrayList reference
→ArrayList reference
; identity not equalsHashMap reference
andArrayList reference
→boolean true
; storeboolean true
toc
-
load from
a
→def
; storedef
tob
-
load from
a
→def
; implicit castdef
toHashMap reference @0
→HashMap reference @0
; load fromb
→def
; implicit castdef
toHashMap reference @1
→HashMap reference @1
; identity not equalsHashMap reference @0
andHashMap reference @1
→boolean false
; storeboolean false
tob
; (noteHashMap reference @0
andHashMap reference @1
refer to the same instance)
-
Boolean Xor
Use the boolean xor operator '^'
to XOR together two boolean
type values
where if one boolean
type value is true
and the other is false
the
resultant boolean
type value is true
and false
otherwise.
Errors
-
If either evaluated value is a value other than a
boolean
type value or a value that is castable to aboolean
type value.
Truth
true |
false |
|
true |
false |
true |
false |
true |
false |
Grammar
boolean_xor: expression '^' expression;
Examples
-
Boolean xor with the
boolean
type.boolean x = false; (1) boolean y = x ^ true; (2) y = y ^ x; (3)
-
declare
boolean x
; storeboolean false
tox
-
declare
boolean y
; load fromx
→boolean false
boolean xorboolean false
andboolean true
→boolean true
; storeboolean true
toy
-
load from
y
→boolean true @0
; load fromx
→boolean true @1
; boolean xorboolean true @0
andboolean true @1
→boolean false
; storeboolean false
toy
-
-
Boolean xor with the
def
type.def x = false; (1) def y = x ^ true; (2) y = y ^ x; (3)
-
declare
def x
; implicit castboolean false
todef
→def
; storedef
tox
-
declare
def y
; load fromx
→def
; implicit castdef
toboolean false
→boolean false
; boolean xorboolean false
andboolean true
→boolean true
; implicit castboolean true
todef
→def
; storedef
toy
-
load from
y
→def
; implicit castdef
toboolean true @0
→boolean true @0
; load fromx
→def
; implicit castdef
toboolean true @1
→boolean true @1
; boolean xorboolean true @0
andboolean true @1
→boolean false
; implicit castboolean false
→def
; storedef
toy
-
Boolean And
Use the boolean and operator '&&'
to AND together two boolean
type values
where if both boolean
type values are true
the resultant boolean
type
value is true
and false
otherwise.
Errors
-
If either evaluated value is a value other than a
boolean
type value or a value that is castable to aboolean
type value.
Truth
true |
false |
|
true |
true |
false |
false |
false |
false |
Grammar
boolean_and: expression '&&' expression;
Examples
-
Boolean and with the
boolean
type.boolean x = true; (1) boolean y = x && true; (2) x = false; (3) y = y && x; (4)
-
declare
boolean x
; storeboolean true
tox
-
declare
boolean y
; load fromx
→boolean true @0
; boolean andboolean true @0
andboolean true @1
→boolean true
; storeboolean true
toy
-
store
boolean false
tox
-
load from
y
→boolean true
; load fromx
→boolean false
; boolean andboolean true
andboolean false
→boolean false
; storeboolean false
toy
-
-
Boolean and with the
def
type.def x = true; (1) def y = x && true; (2) x = false; (3) y = y && x; (4)
-
declare
def x
; implicit castboolean true
todef
→def
; storedef
tox
-
declare
def y
; load fromx
→def
; implicit castdef
toboolean true @0
→boolean true @0
; boolean andboolean true @0
andboolean true @1
→boolean true
; implicit castboolean true
todef
→def
; storedef
toy
-
implicit cast
boolean false
todef
→def
; storedef
tox
; -
load from
y
→def
; implicit castdef
toboolean true
→boolean true
; load fromx
→def
; implicit castdef
toboolean false
→boolean false
; boolean andboolean true
andboolean false
→boolean false
; implicit castboolean false
→def
; storedef
toy
-
Boolean Or
Use the boolean or operator '||'
to OR together two boolean
type values
where if either one of the boolean
type values is true
the resultant
boolean
type value is true
and false
otherwise.
Errors
-
If either evaluated value is a value other than a
boolean
type value or a value that is castable to aboolean
type value.
Truth
true |
false |
|
true |
true |
true |
false |
true |
false |
Grammar:
boolean_and: expression '||' expression;
Examples
-
Boolean or with the
boolean
type.boolean x = false; (1) boolean y = x || true; (2) y = false; (3) y = y || x; (4)
-
declare
boolean x
; storeboolean false
tox
-
declare
boolean y
; load fromx
→boolean false
; boolean orboolean false
andboolean true
→boolean true
; storeboolean true
toy
-
store
boolean false
toy
-
load from
y
→boolean false @0
; load fromx
→boolean false @1
; boolean orboolean false @0
andboolean false @1
→boolean false
; storeboolean false
toy
-
-
Boolean or with the
def
type.def x = false; (1) def y = x || true; (2) y = false; (3) y = y || x; (4)
-
declare
def x
; implicit castboolean false
todef
→def
; storedef
tox
-
declare
def y
; load fromx
→def
; implicit castdef
toboolean false
→boolean true
; boolean orboolean false
andboolean true
→boolean true
; implicit castboolean true
todef
→def
; storedef
toy
-
implicit cast
boolean false
todef
→def
; storedef
toy
; -
load from
y
→def
; implicit castdef
toboolean false @0
→boolean false @0
; load fromx
→def
; implicit castdef
toboolean false @1
→boolean false @1
; boolean orboolean false @0
andboolean false @1
→boolean false
; implicit castboolean false
→def
; storedef
toy
-
Operators: Reference
Method Call
Use the method call operator '()'
to call a member method on a
reference type value. Implicit
boxing/unboxing is evaluated as necessary per argument
during the method call. When a method call is made on a target def
type value,
the parameters and return type value are considered to also be of the def
type
and are evaluated at run-time.
An overloaded method is one that shares the same name with two or more methods. A method is overloaded based on arity where the same name is re-used for multiple methods as long as the number of parameters differs.
Errors
-
If the reference type value is
null
. -
If the member method name doesn’t exist for a given reference type value.
-
If the number of arguments passed in is different from the number of specified parameters.
-
If the arguments cannot be implicitly cast or implicitly boxed/unboxed to the correct type values for the parameters.
Grammar
method_call: '.' ID arguments;
arguments: '(' (expression (',' expression)*)? ')';
Examples
-
Method calls on different reference types.
Map m = new HashMap(); (1) m.put(1, 2); (2) int z = m.get(1); (3) def d = new ArrayList(); (4) d.add(1); (5) int i = Integer.parseInt(d.get(0).toString()); (6)
-
declare
Map m
; allocateHashMap
instance →HashMap reference
; storeHashMap reference
tom
-
load from
m
→Map reference
; implicit castint 1
todef
→def
; implicit castint 2
todef
→def
; callput
onMap reference
with arguments (int 1
,int 2
) -
declare
int z
; load fromm
→Map reference
; callget
onMap reference
with arguments (int 1
) →def
; implicit castdef
toint 2
→int 2
; storeint 2
toz
-
declare
def d
; allocateArrayList
instance →ArrayList reference
; implicit castArrayList
todef
→def
; storedef
tod
-
load from
d
→def
; implicit castdef
toArrayList reference
→ArrayList reference
calladd
onArrayList reference
with arguments (int 1
); -
declare
int i
; load fromd
→def
; implicit castdef
toArrayList reference
→ArrayList reference
callget
onArrayList reference
with arguments (int 1
) →def
; implicit castdef
toInteger 1 reference
→Integer 1 reference
; calltoString
onInteger 1 reference
→String '1'
; callparseInt
onInteger
with arguments (String '1'
) →int 1
; storeint 1
ini
;
-
Field Access
Use the field access operator '.'
to store a value to or load a value from a
reference type member field.
Errors
-
If the reference type value is
null
. -
If the member field name doesn’t exist for a given reference type value.
Grammar
field_access: '.' ID;
Examples
The examples use the following reference type definition:
name:
Example
non-static member fields:
* int x
* def y
* List z
-
Field access with the
Example
type.Example example = new Example(); (1) example.x = 1; (2) example.y = example.x; (3) example.z = new ArrayList(); (4) example.z.add(1); (5) example.x = example.z.get(0); (6)
-
declare
Example example
; allocateExample
instance →Example reference
; storeExample reference
toexample
-
load from
example
→Example reference
; storeint 1
tox
ofExample reference
-
load from
example
→Example reference @0
; load fromexample
→Example reference @1
; load fromx
ofExample reference @1
→int 1
; implicit castint 1
todef
→def
; storedef
toy
ofExample reference @0
; (noteExample reference @0
andExample reference @1
are the same) -
load from
example
→Example reference
; allocateArrayList
instance →ArrayList reference
; implicit castArrayList reference
toList reference
→List reference
; storeList reference
toz
ofExample reference
-
load from
example
→Example reference
; load fromz
ofExample reference
→List reference
; calladd
onList reference
with arguments (int 1
) -
load from
example
→Example reference @0
; load fromexample
→Example reference @1
; load fromz
ofExample reference @1
→List reference
; callget
onList reference
with arguments (int 0
) →int 1
; storeint 1
inx
ofList reference @0
; (noteExample reference @0
andExample reference @1
are the same)
-
Null Safe
Use the null safe operator '?.'
instead of the method call operator or field
access operator to ensure a reference type value is non-null
before
a method call or field access. A null
value will be returned if the reference
type value is null
, otherwise the method call or field access is evaluated.
Errors
-
If the method call return type value or the field access type value is not a reference type value and is not implicitly castable to a reference type value.
Grammar
null_safe: null_safe_method_call
| null_safe_field_access
;
null_safe_method_call: '?.' ID arguments;
arguments: '(' (expression (',' expression)*)? ')';
null_safe_field_access: '?.' ID;
Examples
The examples use the following reference type definition:
name:
Example
non-static member methods:
* List factory()
non-static member fields:
* List x
-
Null safe without a
null
value.Example example = new Example(); (1) List x = example?.factory(); (2)
-
declare
Example example
; allocateExample
instance →Example reference
; storeExample reference
toexample
-
declare
List x
; load fromexample
→Example reference
; null safe callfactory
onExample reference
→List reference
; storeList reference
tox
;
-
-
Null safe with a
null
value;Example example = null; (1) List x = example?.x; (2)
-
declare
Example example
; storenull
toexample
-
declare
List x
; load fromexample
→Example reference
; null safe accessx
onExample reference
→null
; storenull
tox
; (note the null safe operator returnednull
becauseexample
isnull
)
-
List Initialization
Use the list initialization operator '[]'
to allocate an List
type instance
to the heap with a set of pre-defined values. Each value used to initialize the
List
type instance is cast to a def
type value upon insertion into the
List
type instance using the add
method. The order of the specified values
is maintained.
Grammar
list_initialization: '[' expression (',' expression)* ']'
| '[' ']';
Examples
-
List initialization of an empty
List
type value.List empty = []; (1)
-
declare
List empty
; allocateArrayList
instance →ArrayList reference
; implicit castArrayList reference
toList reference
→List reference
; storeList reference
toempty
-
-
List initialization with static values.
List list = [1, 2, 3]; (1)
-
declare
List list
; allocateArrayList
instance →ArrayList reference
; calladd
onArrayList reference
with arguments(int 1
); calladd
onArrayList reference
with arguments(int 2
); calladd
onArrayList reference
with arguments(int 3
); implicit castArrayList reference
toList reference
→List reference
; storeList reference
tolist
-
-
List initialization with non-static values.
int i = 1; (1) long l = 2L; (2) float f = 3.0F; (3) double d = 4.0; (4) String s = "5"; (5) List list = [i, l, f*d, s]; (6)
-
declare
int i
; storeint 1
toi
-
declare
long l
; storelong 2
tol
-
declare
float f
; storefloat 3.0
tof
-
declare
double d
; storedouble 4.0
tod
-
declare
String s
; storeString "5"
tos
-
declare
List list
; allocateArrayList
instance →ArrayList reference
; load fromi
→int 1
; calladd
onArrayList reference
with arguments(int 1
); load froml
→long 2
; calladd
onArrayList reference
with arguments(long 2
); load fromf
→float 3.0
; load fromd
→double 4.0
; promotefloat 3.0
anddouble 4.0
: resultdouble
; implicit castfloat 3.0
todouble 3.0
→double 3.0
; multiplydouble 3.0
anddouble 4.0
→double 12.0
; calladd
onArrayList reference
with arguments(double 12.0
); load froms
→String "5"
; calladd
onArrayList reference
with arguments(String "5"
); implicit castArrayList reference
toList reference
→List reference
; storeList reference
tolist
-
List Access
Use the list access operator '[]'
as a shortcut for a set
method call or
get
method call made on a List
type value.
Errors
-
If a value other than a
List
type value is accessed. -
If a non-integer type value is used as an index for a
set
method call orget
method call.
Grammar
list_access: '[' expression ']'
Examples
-
List access with the
List
type.List list = new ArrayList(); (1) list.add(1); (2) list.add(2); (3) list.add(3); (4) list[0] = 2; (5) list[1] = 5; (6) int x = list[0] + list[1]; (7) int y = 1; (8) int z = list[y]; (9)
-
declare
List list
; allocateArrayList
instance →ArrayList reference
; implicit castArrayList reference
toList reference
→List reference
; storeList reference
tolist
-
load from
list
→List reference
; calladd
onList reference
with arguments(int 1
) -
load from
list
→List reference
; calladd
onList reference
with arguments(int 2
) -
load from
list
→List reference
; calladd
onList reference
with arguments(int 3
) -
load from
list
→List reference
; callset
onList reference
with arguments(int 0
,int 2
) -
load from
list
→List reference
; callset
onList reference
with arguments(int 1
,int 5
) -
declare
int x
; load fromlist
→List reference
; callget
onList reference
with arguments(int 0
) →def
; implicit castdef
toint 2
→int 2
; load fromlist
→List reference
; callget
onList reference
with arguments(int 1
) →def
; implicit castdef
toint 5
→int 5
; addint 2
andint 5
→int 7
; storeint 7
tox
-
declare
int y
; storeint 1
inty
-
declare
int z
; load fromlist
→List reference
; load fromy
→int 1
; callget
onList reference
with arguments(int 1
) →def
; implicit castdef
toint 5
→int 5
; storeint 5
toz
-
-
List access with the
def
type.def d = new ArrayList(); (1) d.add(1); (2) d.add(2); (3) d.add(3); (4) d[0] = 2; (5) d[1] = 5; (6) def x = d[0] + d[1]; (7) def y = 1; (8) def z = d[y]; (9)
-
declare
List d
; allocateArrayList
instance →ArrayList reference
; implicit castArrayList reference
todef
→def
; storedef
tod
-
load from
d
→def
; implicit castdef
toArrayList reference
→ArrayList reference
; calladd
onArrayList reference
with arguments(int 1
) -
load from
d
→def
; implicit castdef
toArrayList reference
→ArrayList reference
; calladd
onArrayList reference
with arguments(int 2
) -
load from
d
→def
; implicit castdef
toArrayList reference
→ArrayList reference
; calladd
onArrayList reference
with arguments(int 3
) -
load from
d
→def
; implicit castdef
toArrayList reference
→ArrayList reference
; callset
onArrayList reference
with arguments(int 0
,int 2
) -
load from
d
→def
; implicit castdef
toArrayList reference
→ArrayList reference
; callset
onArrayList reference
with arguments(int 1
,int 5
) -
declare
def x
; load fromd
→def
; implicit castdef
toArrayList reference
→ArrayList reference
; callget
onArrayList reference
with arguments(int 0
) →def
; implicit castdef
toint 2
→int 2
; load fromd
→def
; implicit castdef
toArrayList reference
→ArrayList reference
; callget
onArrayList reference
with arguments(int 1
) →def
; implicit castdef
toint 2
→int 2
; addint 2
andint 5
→int 7
; storeint 7
tox
-
declare
int y
; storeint 1
inty
-
declare
int z
; load fromd
→ArrayList reference
; load fromy
→def
; implicit castdef
toint 1
→int 1
; callget
onArrayList reference
with arguments(int 1
) →def
; storedef
toz
-
Map Initialization
Use the map initialization operator '[:]'
to allocate a Map
type instance to
the heap with a set of pre-defined values. Each pair of values used to
initialize the Map
type instance are cast to def
type values upon insertion
into the Map
type instance using the put
method.
Grammar
map_initialization: '[' key_pair (',' key_pair)* ']'
| '[' ':' ']';
key_pair: expression ':' expression
Examples
-
Map initialization of an empty
Map
type value.Map empty = [:]; (1)
-
declare
Map empty
; allocateHashMap
instance →HashMap reference
; implicit castHashMap reference
toMap reference
→Map reference
; storeMap reference
toempty
-
-
Map initialization with static values.
Map map = [1:2, 3:4, 5:6]; (1)
-
declare
Map map
; allocateHashMap
instance →HashMap reference
; callput
onHashMap reference
with arguments(int 1
,int 2
); callput
onHashMap reference
with arguments(int 3
,int 4
); callput
onHashMap reference
with arguments(int 5
,int 6
); implicit castHashMap reference
toMap reference
→Map reference
; storeMap reference
tomap
-
-
Map initialization with non-static values.
byte b = 0; (1) int i = 1; (2) long l = 2L; (3) float f = 3.0F; (4) double d = 4.0; (5) String s = "5"; (6) Map map = [b:i, l:f*d, d:s]; (7)
-
declare
byte b
; storebyte 0
tob
-
declare
int i
; storeint 1
toi
-
declare
long l
; storelong 2
tol
-
declare
float f
; storefloat 3.0
tof
-
declare
double d
; storedouble 4.0
tod
-
declare
String s
; storeString "5"
tos
-
declare
Map map
; allocateHashMap
instance →HashMap reference
; load fromb
→byte 0
; load fromi
→int 1
; callput
onHashMap reference
with arguments(byte 0
,int 1
); load froml
→long 2
; load fromf
→float 3.0
; load fromd
→double 4.0
; promotefloat 3.0
anddouble 4.0
: resultdouble
; implicit castfloat 3.0
todouble 3.0
→double 3.0
; multiplydouble 3.0
anddouble 4.0
→double 12.0
; callput
onHashMap reference
with arguments(long 2
,double 12.0
); load fromd
→double 4.0
; load froms
→String "5"
; callput
onHashMap reference
with arguments(double 4.0
,String "5"
); implicit castHashMap reference
toMap reference
→Map reference
; storeMap reference
tomap
-
Map Access
Use the map access operator '[]'
as a shortcut for a put
method call or
get
method call made on a Map
type value.
Errors
-
If a value other than a
Map
type value is accessed.
Grammar
map_access: '[' expression ']'
Examples
-
Map access with the
Map
type.Map map = new HashMap(); (1) map['value2'] = 2; (2) map['value5'] = 5; (3) int x = map['value2'] + map['value5']; (4) String y = 'value5'; (5) int z = x[z]; (6)
-
declare
Map map
; allocateHashMap
instance →HashMap reference
; implicit castHashMap reference
toMap reference
→Map reference
; storeMap reference
tomap
-
load from
map
→Map reference
; callput
onMap reference
with arguments(String 'value2'
,int 2
) -
load from
map
→Map reference
; callput
onMap reference
with arguments(String 'value5'
,int 5
) -
declare
int x
; load frommap
→Map reference
; callget
onMap reference
with arguments(String 'value2'
) →def
; implicit castdef
toint 2
→int 2
; load frommap
→Map reference
; callget
onMap reference
with arguments(String 'value5'
) →def
; implicit castdef
toint 5
→int 5
; addint 2
andint 5
→int 7
; storeint 7
tox
-
declare
String y
; storeString 'value5'
toy
-
declare
int z
; load frommap
→Map reference
; load fromy
→String 'value5'
; callget
onMap reference
with arguments(String 'value5'
) →def
; implicit castdef
toint 5
→int 5
; storeint 5
toz
-
-
Map access with the
def
type.def d = new HashMap(); (1) d['value2'] = 2; (2) d['value5'] = 5; (3) int x = d['value2'] + d['value5']; (4) String y = 'value5'; (5) def z = d[y]; (6)
-
declare
def d
; allocateHashMap
instance →HashMap reference
; implicit castHashMap reference
todef
→def
; storedef
tod
-
load from
d
→def
; implicit castdef
toHashMap reference
→HashMap reference
; callput
onHashMap reference
with arguments(String 'value2'
,int 2
) -
load from
d
→def
; implicit castdef
toHashMap reference
→HashMap reference
; callput
onHashMap reference
with arguments(String 'value5'
,int 5
) -
declare
int x
; load fromd
→def
; implicit castdef
toHashMap reference
→HashMap reference
; callget
onHashMap reference
with arguments(String 'value2'
) →def
; implicit castdef
toint 2
→int 2
; load fromd
→def
; callget
onHashMap reference
with arguments(String 'value5'
) →def
; implicit castdef
toint 5
→int 5
; addint 2
andint 5
→int 7
; storeint 7
tox
-
declare
String y
; storeString 'value5'
toy
-
declare
def z
; load fromd
→def
; load fromy
→String 'value5'
; callget
onHashMap reference
with arguments(String 'value5'
) →def
; storedef
toz
-
New Instance
Use the new instance operator 'new ()'
to allocate a
reference type instance to the heap and call a specified
constructor. Implicit boxing/unboxing is evaluated as
necessary per argument during the constructor call.
An overloaded constructor is one that shares the same name with two or more constructors. A constructor is overloaded based on arity where the same reference type name is re-used for multiple constructors as long as the number of parameters differs.
Errors
-
If the reference type name doesn’t exist for instance allocation.
-
If the number of arguments passed in is different from the number of specified parameters.
-
If the arguments cannot be implicitly cast or implicitly boxed/unboxed to the correct type values for the parameters.
Grammar
new_instance: 'new' TYPE '(' (expression (',' expression)*)? ')';
Examples
-
Allocation of new instances with different types.
Map m = new HashMap(); (1)
def d = new ArrayList(); (2)
def e = new HashMap(m); (3)
-
declare
Map m
; allocateHashMap
instance →HashMap reference
; implicit castHashMap reference
toMap reference
→Map reference
; storeMap reference
tom
; -
declare
def d
; allocateArrayList
instance →ArrayList reference
; implicit castArrayList reference
todef
→def
; storedef
tod
; -
declare
def e
; load fromm
→Map reference
; allocateHashMap
instance with arguments (Map reference
) →HashMap reference
; implicit castHashMap reference
todef
→def
; storedef
toe
;
String Concatenation
Use the string concatenation operator '+'
to concatenate two values together
where at least one of the values is a String
type.
Grammar
concatenate: expression '+' expression;
Examples
-
String concatenation with different primitive types.
String x = "con"; (1) String y = x + "cat"; (2) String z = 4 + 5 + x; (3)
-
declare
String x
; storeString "con"
tox
; -
declare
String y
; load fromx
→String "con"
; concatString "con"
andString "cat"
→String "concat"
; storeString "concat"
toy
-
declare
String z
; addint 4
andint 5
→int 9
; concatint 9
andString "9concat"
; storeString "9concat"
toz
; (note the addition is done prior to the concatenation due to precedence and associativity of the specific operations)
-
-
String concatenation with the
def
type.def d = 2; (1) d = "con" + d + "cat"; (2)
-
declare
def
; implicit castint 2
todef
→def
; storedef
ind
; -
concat
String "con"
andint 9
→String "con9"
; concatString "con9"
andString "con"
→String "con9cat"
implicit castString "con9cat"
todef
→def
; storedef
tod
; (note the switch in type ofd
fromint
toString
)
-
Elvis
An elvis consists of two expressions. The first expression is evaluated
with to check for a null
value. If the first expression evaluates to
null
then the second expression is evaluated and its value used. If the first
expression evaluates to non-null
then the resultant value of the first
expression is used. Use the elvis operator '?:'
as a shortcut for the
conditional operator.
Errors
-
If the first expression or second expression cannot produce a
null
value.
Grammar
elvis: expression '?:' expression;
Examples
-
Elvis with different reference types.
List x = new ArrayList(); (1) List y = x ?: new ArrayList(); (2) y = null; (3) List z = y ?: new ArrayList(); (4)
-
declare
List x
; allocateArrayList
instance →ArrayList reference
; implicit castArrayList reference
toList reference
→List reference
; storeList reference
tox
; -
declare
List y
; loadx
→List reference
;List reference
equalsnull
→false
; evaluate 1st expression:List reference
→List reference
; storeList reference
toy
-
store
null
toy
; -
declare
List z
; loady
→List reference
;List reference
equalsnull
→true
; evaluate 2nd expression: allocateArrayList
instance →ArrayList reference
; implicit castArrayList reference
toList reference
→List reference
; storeList reference
toz
;
-
Operators: Array
Array Initialization
Use the array initialization operator '[] {}'
to allocate a single-dimensional
array type instance to the heap with a set of pre-defined
elements. Each value used to initialize an element in the array type instance is
cast to the specified element type value upon insertion. The order of specified
values is maintained.
Errors
-
If a value is not castable to the specified type value.
Grammar
array_initialization: 'new' TYPE '[' ']' '{' expression_list '}'
| 'new' TYPE '[' ']' '{' '}';
expression_list: expression (',' expression);
Example:
-
Array initialization with static values.
int[] x = new int[] {1, 2, 3}; (1)
-
declare
int[] x
; allocate1-d int array
instance withlength [3]
→1-d int array reference
; storeint 1
toindex [0]
of1-d int array reference
; storeint 2
toindex [1]
of1-d int array reference
; storeint 3
toindex [2]
of1-d int array reference
; store1-d int array reference
tox
;
-
-
Array initialization with non-static values.
int i = 1; (1) long l = 2L; (2) float f = 3.0F; (3) double d = 4.0; (4) String s = "5"; (5) def array = new def[] {i, l, f*d, s}; (6)
-
declare
int i
; storeint 1
toi
-
declare
long l
; storelong 2
tol
-
declare
float f
; storefloat 3.0
tof
-
declare
double d
; storedouble 4.0
tod
-
declare
String s
; storeString "5"
tos
-
declare
def array
; allocate1-d def array
instance withlength [4]
→1-d def array reference
; load fromi
→int 1
; implicit castint 1
todef
→def
; storedef
toindex [0]
of1-d def array reference
; load froml
→long 2
; implicit castlong 2
todef
→def
; storedef
toindex [1]
of1-d def array reference
; load fromf
→float 3.0
; load fromd
→double 4.0
; promotefloat 3.0
anddouble 4.0
: resultdouble
; implicit castfloat 3.0
todouble 3.0
→double 3.0
; multiplydouble 3.0
anddouble 4.0
→double 12.0
; implicit castdouble 12.0
todef
→def
; storedef
toindex [2]
of1-d def array reference
; load froms
→String "5"
; implicit castString "5"
todef
→def
; storedef
toindex [3]
of1-d def array reference
; implicit cast1-d int array reference
todef
→def
; storedef
toarray
-
Array Access
Use the array access operator '[]'
to store a value to or load a value from
an array type value. Each element of an array type value is
accessed with an int
type value to specify the index to store/load. The range
of elements within an array that are accessible is [0, size)
where size is the
number of elements specified at the time of allocation. Use a negative int
type value as an index to access an element in reverse from the end of an array
type value within a range of [-size, -1]
.
Errors
-
If a value other than an
int
type value or a value that is castable to anint
type value is provided as an index. -
If an element is accessed outside of the valid ranges.
Grammar
brace_access: '[' expression ']'
Examples
-
Array access with a single-dimensional array.
int[] x = new int[2]; (1) x[0] = 2; (2) x[1] = 5; (3) int y = x[0] + x[1]; (4) int z = 1; (5) int i = x[z]; (6)
-
declare
int[] x
; allocate1-d int array
instance withlength [2]
→1-d int array reference
; store1-d int array reference
tox
-
load from
x
→1-d int array reference
; storeint 2
toindex [0]
of1-d int array reference
; -
load from
x
→1-d int array reference
; storeint 5
toindex [1]
of1-d int array reference
; -
declare
int y
; load fromx
→1-d int array reference
; load fromindex [0]
of1-d int array reference
→int 2
; load fromx
→1-d int array reference
; load fromindex [1]
of1-d int array reference
→int 5
; addint 2
andint 5
→int 7
; storeint 7
toy
-
declare
int z
; storeint 1
toz
; -
declare
int i
; load fromx
→1-d int array reference
; load fromz
→int 1
; load fromindex [1]
of1-d int array reference
→int 5
; storeint 5
toi
;
-
-
Array access with the
def
type.def d = new int[2]; (1) d[0] = 2; (2) d[1] = 5; (3) def x = d[0] + d[1]; (4) def y = 1; (5) def z = d[y]; (6)
-
declare
def d
; allocate1-d int array
instance withlength [2]
→1-d int array reference
; implicit cast1-d int array reference
todef
→def
; storedef
tod
-
load from
d
→def
implicit castdef
to1-d int array reference
→1-d int array reference
; storeint 2
toindex [0]
of1-d int array reference
; -
load from
d
→def
implicit castdef
to1-d int array reference
→1-d int array reference
; storeint 5
toindex [1]
of1-d int array reference
; -
declare
int x
; load fromd
→def
implicit castdef
to1-d int array reference
→1-d int array reference
; load fromindex [0]
of1-d int array reference
→int 2
; load fromd
→def
implicit castdef
to1-d int array reference
→1-d int array reference
; load fromindex [1]
of1-d int array reference
→int 5
; addint 2
andint 5
→int 7
; implicit castint 7
todef
→def
; storedef
tox
-
declare
def y
; implicit castint 1
todef
→def
; storedef
toy
; -
declare
int i
; load fromd
→def
implicit castdef
to1-d int array reference
→1-d int array reference
; load fromy
→def
; implicit castdef
toint 1
→int 1
; load fromindex [1]
of1-d int array reference
→int 5
; implicit castint 5
todef
; storedef
toz
;
-
-
Array access with a multi-dimensional array.
int[][][] ia3 = new int[2][3][4]; (1) ia3[1][2][3] = 99; (2) int i = ia3[1][2][3]; (3)
-
declare
int[][][] ia
; allocate3-d int array
instance with length[2, 3, 4]
→3-d int array reference
; store3-d int array reference
toia3
-
load from
ia3
→3-d int array reference
; storeint 99
toindex [1, 2, 3]
of3-d int array reference
-
declare
int i
; load fromia3
→3-d int array reference
; load fromindex [1, 2, 3]
of3-d int array reference
→int 99
; storeint 99
toi
-
Array Length
An array type value contains a read-only member field named length
. The
length
field stores the size of the array as an int
type value where size is
the number of elements specified at the time of allocation. Use the
field access operator to load the field length
from an array type value.
Examples
-
Access the
length
field.int[] x = new int[10]; (1) int l = x.length; (2)
-
declare
int[] x
; allocate1-d int array
instance withlength [2]
→1-d int array reference
; store1-d int array reference
tox
-
declare
int l
; loadx
→1-d int array reference
; loadlength
from1-d int array reference
→int 10
; storeint 10
tol
;
-
New Array
Use the new array operator 'new []'
to allocate an array type instance to
the heap. Specify the element type following the new
token. Specify each
dimension with the [
and ]
tokens following the element type name. The size
of each dimension is specified by an int
type value in between each set of [
and ]
tokens.
Errors
-
If a value other than an
int
type value or a value that is castable to anint
type value is specified for a dimension’s size.
Grammar
new_array: 'new' TYPE ('[' expression ']')+;
Examples
-
Allocation of different array types.
int[] x = new int[5]; (1) x = new int[10]; (2) int y = 2; (3) def z = new def[y][y*2]; (4)
-
declare
int[] x
; allocate1-d int array
instance withlength [5]
→1-d int array reference
; store1-d int array reference
tox
-
allocate
1-d int array
instance withlength [10]
→1-d int array reference
; store1-d int array reference
tox
-
declare
int y
; storeint 2
toy
; -
declare
def z
; load fromy
→int 2 @0
; load fromy
→int 2 @1
; multiplyint 2 @1
byint 2 @2
→int 4
; allocate2-d int array
instance with length[2, 4]
→2-d int array reference
; implicit cast2-d int array reference
todef
→def
; storedef
toz
;
-
Statements
Painless supports all of Java’s
control flow statements except the switch
statement.
Conditional statements
If / Else
if (doc[item].size() == 0) {
// do something if "item" is missing
} else {
// do something else
}
Loop statements
For
Painless also supports the for in
syntax from Groovy:
for (def item : list) {
...
}
Scripts
Scripts are composed of one-to-many statements and are run in a sandbox that determines what local variables are immediately available along with what APIs are whitelisted for use.
Functions
A function is a named piece of code comprised of one-to-many statements to perform a specific task. A function is called multiple times in a single script to repeat its specific task. A parameter is a named type value available as a variable within the statement(s) of a function. A function specifies zero-to-many parameters, and when a function is called a value is specified per parameter. An argument is a value passed into a function at the point of call. A function specifies a return type value, though if the type is void then no value is returned. Any non-void type return value is available for use within an operation or is discarded otherwise.
You can declare functions at the beginning of a Painless script, for example:
boolean isNegative(def x) { x < 0 }
...
if (isNegative(someVar)) {
...
}
Lambdas
Lambda expressions and method references work the same as in Java.
list.removeIf(item -> item == 2);
list.removeIf((int item) -> item == 2);
list.removeIf((int item) -> { item == 2 });
list.sort((x, y) -> x - y);
list.sort(Integer::compare);
You can make method references to functions within the script with this
,
for example list.sort(this::mycompare)
.
Regexes
Regular expression constants are directly supported. To ensure fast performance, this is the only mechanism for creating patterns. Regular expressions are always constants and compiled efficiently a single time.
Pattern p = /[aeiou]/
Pattern flags
You can define flags on patterns in Painless by adding characters after the
trailing /
like /foo/i
or /foo \w #comment/iUx
. Painless exposes all of
the flags from Java’s
Pattern class using these characters:
Character | Java Constant | Example |
---|---|---|
|
CANON_EQ |
|
|
CASE_INSENSITIVE |
|
|
LITERAL |
|
|
MULTILINE |
|
|
DOTALL (aka single line) |
|
|
UNICODE_CHARACTER_CLASS |
|
|
UNICODE_CASE |
|
|
COMMENTS (aka extended) |
|