Figure 2.29. Concrete Syntax for Expressions
Figure 2.29, “Concrete Syntax for Expressions” presents the concrete syntax of expressions. BIR expressions are strictly evaluated for their values. In other words, BIR expressions are pure expressions (i.e., side-effect free). We use paragraphs with "Type" as headers to describe the type of the expressions. Table ?? presents the precedence of BIR compound expression operators. Operators that are in the same line have the same precedence. Operators listed higher than other operators have higher precedence than the other operators. Operators with higher precedence are evaluated before operators with lower precedence. Unary expressions and the conditional expression are right-associative; all other expressions are left-associative. We now describe each expression construct in details in the following subsections.
Non-atomic high-level expressions are translated to their 3-address code low-level equivalent.
Abstract Syntax Tree.
The top level Java AST class for expressions is the Exp class.
A literal expression is an expression whose valuation is the value represented by the literal.
Type. The type of a literal expression is the same as the type of the literal.
Examples.
Abstract Syntax Tree. The Java AST class for literal expression is the LiteralExp class.
A variable expression is an expression whose valuation is the value being held (or bound) by the specified variable at the state (or environment) where the expression is evaluated. Depending on where a variable expression is used, the variable can refer to a global variable, a local variable, a let-local variable (see let expression), or a functional expression.
Type. The type of a variable expression is the same as the type of the variable.
Examples.
Abstract Syntax Tree. The Java AST class for variable expression is the IdExp class.
A unary expression is an expression whose valuation is computed by applying its (unary) operator to the valuation of its operand. There are three kinds of unary operators: (1) the logical complement unary operator "!", (2) the plus unary operator "+", and (3) the minus unary operator "!". The semantics of the operators are defined similar to other programming languages such as Java.
Type. The type of a unary expression is the same as the type of its operand.
Examples.
Abstract Syntax Tree. The Java AST class for unary expression is the UnaryExp class. The unary operators are defined in the UnaryOp class.
A binary expression is an expression whose valuation is computed by applying its (binary) operator to the valuations of both of its operands. Binary operators in BIR are:
the addition binary operator ("+"),
the substraction binary operator ("-"),
the multiplication binary operator ("*"),
the division binary operator ("/"),
the modulus (remainder) binary operator ("%"),
the equality test binary operator ("=="),
the inequality test binary operator ("!="),
the less than test binary operator ("<"),
the less than or equal test binary operator ("<="),
the greater than test binary operator (">"),
the greater than or equal to test binary operator (">="),
the shift left binary operator ("shl"),
the shift right binary operator ("shr"),
the unsigned shift right binary operator ("ushr"),
the conditional-and binary operator ("&&"),
the conditional-or binary operator ("||"),
the conditional-implication binary operator ("=>"),
the bit-wise-and binary operator ("&"),
the bit-wise-or binary operator ("|"), and
the bit-wise-xor binary operator ("^").
For binary conditional operators, the binary expression's second operand may not be evaluated. The semantics of the operators are defined similar to other programming languages such as Java ("shl", "shr", and "ushr" are "<<", ">>", and ">>>" in Java, respectively).
Type. The types of a binary expression's operands must be equal if they are primitive types. The type of a binary expression depends on its operator's type. The type of arithmetic operators ("+", "-", "*", "/", "%"), shift operators ("<<", ">>", and ">>>"), and bit-wise operators ("&", "|", and "^") is the same as the type of the binary expression's operands. All other operators are of type boolean.
Examples.
Abstract Syntax Tree. The Java AST class for binary expression is the BinaryExp class. The binary operators are defined in the BinaryOp class.
A conditional expression is an expression whose valuation depends on the valuation of its first operand. If the valuation of the first operand is true, then, the valuation of the conditional expression is the valuation of its second operand (its third operand will not be evaluated). Otherwise, the valuation of the conditional expression is the valuation of its third operand (its second operand will not be evaluated).
Type. The first operand of a conditional expression must be of type boolean. The second and third operands must be of equal types. The type of a conditional expression is the same as its second and third operands.
Examples.
Abstract Syntax Tree. The Java AST class for conditional expression is the ConditionalExp class.
Parenthesis expression is used to override the precedence rules for lower precendence compound expressions. The valuation of a parenthesis expression is the valuation of the expression inside the parenthesis.
Type. The type of a parenthesis expression is the same as the type of the expression inside the parenthesis.
Examples.
Abstract Syntax Tree. The Java AST class for parenthesis expression is the ParenExp class.
Atomic expression is used to force the evaluation of the contained expression to be indivisible. This expression can only be used in high-level BIR as expression in low-level is atomic by default.
Type. The type of an atomic expression is the same as the type of the contained expression.
Examples.
Abstract Syntax Tree. The Java AST class for parenthesis expression is the AtomicExp class.
There are three kind of creation expressions: (1) record creation expressions, (2) array creation expressions, and (3) the lock creation expression. The valuation of a creation expression is a fresh instance of the specified type.
Note that creation expressions are pure expressions because they do not change the current state until the new instances are assigned to some program variables.
Type. The type of a creation expression is the type of the record, the array, or the lock being created.
Examples.
Abstract Syntax Tree. The Java AST classes for record creation, array creation, and lock creation are the NewRecordExp class, the NewArrayExp class, and the NewLockExp class, respectively.
Field access expression is used to access a field value of a record value or an array value (i.e., fields from the top record, if any). If the record/array value is null, then a null pointer exception is raised.
Examples.
Abstract Syntax Tree. The Java AST class for field access expression is the FieldAccessExp class.
Array access expression is used to access an element value of an array value. If the array value is null, then a null pointer exception is raised.
Examples.
Abstract Syntax Tree. The Java AST class for array access expression is the ArrayAccessExp class.
Cast expression is used to coerce a value to one of its compatible type value.
Examples.
Abstract Syntax Tree. The Java AST class for cast expression is the CastExp class.
Kind-of expression is used to test a value's exact type.
Examples.
Abstract Syntax Tree. The Java AST class for kind-of expression is the KindofExp class.
Kind-of expression is used to test a value's type with respect to record extension (i.e., inheritance).
Examples.
Abstract Syntax Tree. The Java AST class for instance-of expression is the InstanceofExp class.
Lock test expressions are used to query the state of a lock: (1) lockAvailable is used to test whether a thread's attempt to acquire a lock would succeed (that is, either the thread already owns the lock or the lock is unowned), (2) hasLock is used to test whether the current executing thread holds a lock, and (3) wasNotified is used to test whether there was a notification for a lock.
Examples.
Abstract Syntax Tree. The Java AST class for lock test expression is the LockTestExp class. The lock test operators are defined in the LockTestOp class.
Thread test expression is used to determine the status of a thread, i.e., whether the thread is terminated. It takes a tid value as its argument (i.e., from the start thread action).
Example.
Abstract Syntax Tree. The Java AST class for thread test expression is the ThreadTestExp class.
Let binding expression is used to bind a value to a name similar to a construct in a functional programming language. Note that the expression does not change the state. Also note that the name may hide local variables or global variables.
Example.
Abstract Syntax Tree. The Java AST class for let expression is the LetExp class.
Application expression is used to apply functional expression in both low-level and high-level BIR. In high-level BIR, it also used to represent function call.
Example.
Abstract Syntax Tree. The Java AST class for apply expression is the ApplyExp class.
Extension call expression is used to call an expression extension. For a parametric expression extension, Bogor tries to infer the arguments to the declared parametric type variables. It is limited, however, as it cannot infer the argument of a type variable that is only used as the return type of the expression extension.
Example.
Abstract Syntax Tree. The Java AST class for extension call expression is the ExtExp class.