Operators: Reference

edit

Method Call

edit

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();                         
    m.put(1, 2);                                   
    int z = m.get(1);                              
    def d = new ArrayList();                       
    d.add(1);                                      
    int i = Integer.parseInt(d.get(0).toString()); 

    declare Map m; allocate HashMap instance → HashMap reference; store HashMap reference to m

    load from mMap reference; implicit cast int 1 to defdef; implicit cast int 2 to defdef; call put on Map reference with arguments (int 1, int 2)

    declare int z; load from mMap reference; call get on Map reference with arguments (int 1) → def; implicit cast def to int 2int 2; store int 2 to z

    declare def d; allocate ArrayList instance → ArrayList reference; implicit cast ArrayList to defdef; store def to d

    load from ddef; implicit cast def to ArrayList referenceArrayList reference call add on ArrayList reference with arguments (int 1);

    declare int i; load from ddef; implicit cast def to ArrayList referenceArrayList reference call get on ArrayList reference with arguments (int 1) → def; implicit cast def to Integer 1 referenceInteger 1 reference; call toString on Integer 1 referenceString '1'; call parseInt on Integer with arguments (String '1') → int 1; store int 1 in i;

Field Access

edit

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(); 
    example.x = 1;                   
    example.y = example.x;           
    example.z = new ArrayList();     
    example.z.add(1);                
    example.x = example.z.get(0);    

    declare Example example; allocate Example instance → Example reference; store Example reference to example

    load from exampleExample reference; store int 1 to x of Example reference

    load from exampleExample reference @0; load from exampleExample reference @1; load from x of Example reference @1int 1; implicit cast int 1 to defdef; store def to y of Example reference @0; (note Example reference @0 and Example reference @1 are the same)

    load from exampleExample reference; allocate ArrayList instance → ArrayList reference; implicit cast ArrayList reference to List referenceList reference; store List reference to z of Example reference

    load from exampleExample reference; load from z of Example referenceList reference; call add on List reference with arguments (int 1)

    load from exampleExample reference @0; load from exampleExample reference @1; load from z of Example reference @1List reference; call get on List reference with arguments (int 0) → int 1; store int 1 in x of List reference @0; (note Example reference @0 and Example reference @1 are the same)

Null Safe

edit

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(); 
    List x = example?.factory();     

    declare Example example; allocate Example instance → Example reference; store Example reference to example

    declare List x; load from exampleExample reference; null safe call factory on Example referenceList reference; store List reference to x;

  • Null safe with a null value;

    Example example = null; 
    List x = example?.x;    

    declare Example example; store null to example

    declare List x; load from exampleExample reference; null safe access x on Example referencenull; store null to x; (note the null safe operator returned null because example is null)

List Initialization

edit

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 = []; 

    declare List empty; allocate ArrayList instance → ArrayList reference; implicit cast ArrayList reference to List referenceList reference; store List reference to empty

  • List initialization with static values.

    List list = [1, 2, 3]; 

    declare List list; allocate ArrayList instance → ArrayList reference; call add on ArrayList reference with arguments(int 1); call add on ArrayList reference with arguments(int 2); call add on ArrayList reference with arguments(int 3); implicit cast ArrayList reference to List referenceList reference; store List reference to list

  • List initialization with non-static values.

    int i = 1;                  
    long l = 2L;                
    float f = 3.0F;             
    double d = 4.0;             
    String s = "5";             
    List list = [i, l, f*d, s]; 

    declare int i; store int 1 to i

    declare long l; store long 2 to l

    declare float f; store float 3.0 to f

    declare double d; store double 4.0 to d

    declare String s; store String "5" to s

    declare List list; allocate ArrayList instance → ArrayList reference; load from iint 1; call add on ArrayList reference with arguments(int 1); load from llong 2; call add on ArrayList reference with arguments(long 2); load from ffloat 3.0; load from ddouble 4.0; promote float 3.0 and double 4.0: result double; implicit cast float 3.0 to double 3.0double 3.0; multiply double 3.0 and double 4.0double 12.0; call add on ArrayList reference with arguments(double 12.0); load from sString "5"; call add on ArrayList reference with arguments(String "5"); implicit cast ArrayList reference to List referenceList reference; store List reference to list

List Access

edit

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 or get method call.

Grammar

list_access: '[' expression ']'

Examples

  • List access with the List type.

    List list = new ArrayList(); 
    list.add(1);                 
    list.add(2);                 
    list.add(3);                 
    list[0] = 2;                 
    list[1] = 5;                 
    int x = list[0] + list[1];   
    int y = 1;                   
    int z = list[y];             

    declare List list; allocate ArrayList instance → ArrayList reference; implicit cast ArrayList reference to List referenceList reference; store List reference to list

    load from listList reference; call add on List reference with arguments(int 1)

    load from listList reference; call add on List reference with arguments(int 2)

    load from listList reference; call add on List reference with arguments(int 3)

    load from listList reference; call set on List reference with arguments(int 0, int 2)

    load from listList reference; call set on List reference with arguments(int 1, int 5)

    declare int x; load from listList reference; call get on List reference with arguments(int 0) → def; implicit cast def to int 2int 2; load from listList reference; call get on List reference with arguments(int 1) → def; implicit cast def to int 5int 5; add int 2 and int 5int 7; store int 7 to x

    declare int y; store int 1 int y

    declare int z; load from listList reference; load from yint 1; call get on List reference with arguments(int 1) → def; implicit cast def to int 5int 5; store int 5 to z

  • List access with the def type.

    def d = new ArrayList(); 
    d.add(1);                
    d.add(2);                
    d.add(3);                
    d[0] = 2;                
    d[1] = 5;                
    def x = d[0] + d[1];     
    def y = 1;               
    def z = d[y];            

    declare List d; allocate ArrayList instance → ArrayList reference; implicit cast ArrayList reference to defdef; store def to d

    load from ddef; implicit cast def to ArrayList referenceArrayList reference; call add on ArrayList reference with arguments(int 1)

    load from ddef; implicit cast def to ArrayList referenceArrayList reference; call add on ArrayList reference with arguments(int 2)

    load from ddef; implicit cast def to ArrayList referenceArrayList reference; call add on ArrayList reference with arguments(int 3)

    load from ddef; implicit cast def to ArrayList referenceArrayList reference; call set on ArrayList reference with arguments(int 0, int 2)

    load from ddef; implicit cast def to ArrayList referenceArrayList reference; call set on ArrayList reference with arguments(int 1, int 5)

    declare def x; load from ddef; implicit cast def to ArrayList referenceArrayList reference; call get on ArrayList reference with arguments(int 0) → def; implicit cast def to int 2int 2; load from ddef; implicit cast def to ArrayList referenceArrayList reference; call get on ArrayList reference with arguments(int 1) → def; implicit cast def to int 2int 2; add int 2 and int 5int 7; store int 7 to x

    declare int y; store int 1 int y

    declare int z; load from dArrayList reference; load from ydef; implicit cast def to int 1int 1; call get on ArrayList reference with arguments(int 1) → def; store def to z

Map Initialization

edit

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 = [:]; 

    declare Map empty; allocate HashMap instance → HashMap reference; implicit cast HashMap reference to Map referenceMap reference; store Map reference to empty

  • Map initialization with static values.

    Map map = [1:2, 3:4, 5:6]; 

    declare Map map; allocate HashMap instance → HashMap reference; call put on HashMap reference with arguments(int 1, int 2); call put on HashMap reference with arguments(int 3, int 4); call put on HashMap reference with arguments(int 5, int 6); implicit cast HashMap reference to Map referenceMap reference; store Map reference to map

  • Map initialization with non-static values.

    byte b = 0;                  
    int i = 1;                   
    long l = 2L;                 
    float f = 3.0F;              
    double d = 4.0;              
    String s = "5";              
    Map map = [b:i, l:f*d, d:s]; 

    declare byte b; store byte 0 to b

    declare int i; store int 1 to i

    declare long l; store long 2 to l

    declare float f; store float 3.0 to f

    declare double d; store double 4.0 to d

    declare String s; store String "5" to s

    declare Map map; allocate HashMap instance → HashMap reference; load from bbyte 0; load from iint 1; call put on HashMap reference with arguments(byte 0, int 1); load from llong 2; load from ffloat 3.0; load from ddouble 4.0; promote float 3.0 and double 4.0: result double; implicit cast float 3.0 to double 3.0double 3.0; multiply double 3.0 and double 4.0double 12.0; call put on HashMap reference with arguments(long 2, double 12.0); load from ddouble 4.0; load from sString "5"; call put on HashMap reference with arguments(double 4.0, String "5"); implicit cast HashMap reference to Map referenceMap reference; store Map reference to map

Map Access

edit

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();               
    map['value2'] = 2;                     
    map['value5'] = 5;                     
    int x = map['value2'] + map['value5']; 
    String y = 'value5';                   
    int z = x[z];                          

    declare Map map; allocate HashMap instance → HashMap reference; implicit cast HashMap reference to Map referenceMap reference; store Map reference to map

    load from mapMap reference; call put on Map reference with arguments(String 'value2', int 2)

    load from mapMap reference; call put on Map reference with arguments(String 'value5', int 5)

    declare int x; load from mapMap reference; call get on Map reference with arguments(String 'value2') → def; implicit cast def to int 2int 2; load from mapMap reference; call get on Map reference with arguments(String 'value5') → def; implicit cast def to int 5int 5; add int 2 and int 5int 7; store int 7 to x

    declare String y; store String 'value5' to y

    declare int z; load from mapMap reference; load from yString 'value5'; call get on Map reference with arguments(String 'value5') → def; implicit cast def to int 5int 5; store int 5 to z

  • Map access with the def type.

    def d = new HashMap();             
    d['value2'] = 2;                   
    d['value5'] = 5;                   
    int x = d['value2'] + d['value5']; 
    String y = 'value5';               
    def z = d[y];                      

    declare def d; allocate HashMap instance → HashMap reference; implicit cast HashMap reference to defdef; store def to d

    load from ddef; implicit cast def to HashMap referenceHashMap reference; call put on HashMap reference with arguments(String 'value2', int 2)

    load from ddef; implicit cast def to HashMap referenceHashMap reference; call put on HashMap reference with arguments(String 'value5', int 5)

    declare int x; load from ddef; implicit cast def to HashMap referenceHashMap reference; call get on HashMap reference with arguments(String 'value2') → def; implicit cast def to int 2int 2; load from ddef; call get on HashMap reference with arguments(String 'value5') → def; implicit cast def to int 5int 5; add int 2 and int 5int 7; store int 7 to x

    declare String y; store String 'value5' to y

    declare def z; load from ddef; load from yString 'value5'; call get on HashMap reference with arguments(String 'value5') → def; store def to z

New Instance

edit

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();   
def d = new ArrayList(); 
def e = new HashMap(m);  

declare Map m; allocate HashMap instance → HashMap reference; implicit cast HashMap reference to Map referenceMap reference; store Map reference to m;

declare def d; allocate ArrayList instance → ArrayList reference; implicit cast ArrayList reference to defdef; store def to d;

declare def e; load from mMap reference; allocate HashMap instance with arguments (Map reference) → HashMap reference; implicit cast HashMap reference to defdef; store def to e;

String Concatenation

edit

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";     
    String y = x + "cat"; 
    String z = 4 + 5 + x; 

    declare String x; store String "con" to x;

    declare String y; load from xString "con"; concat String "con" and String "cat"String "concat"; store String "concat" to y

    declare String z; add int 4 and int 5int 9; concat int 9 and String "9concat"; store String "9concat" to z; (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;             
    d = "con" + d + "cat"; 

    declare def; implicit cast int 2 to defdef; store def in d;

    concat String "con" and int 2String "con2"; concat String "con2" and String "cat"String "con2cat" implicit cast String "con2cat" to defdef; store def to d; (note the switch in type of d from int to String)

Elvis

edit

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();      
    List y = x ?: new ArrayList(); 
    y = null;                      
    List z = y ?: new ArrayList(); 

    declare List x; allocate ArrayList instance → ArrayList reference; implicit cast ArrayList reference to List referenceList reference; store List reference to x;

    declare List y; load xList reference; List reference equals nullfalse; evaluate 1st expression: List referenceList reference; store List reference to y

    store null to y;

    declare List z; load yList reference; List reference equals nulltrue; evaluate 2nd expression: allocate ArrayList instance → ArrayList reference; implicit cast ArrayList reference to List referenceList reference; store List reference to z;