This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
• Expressions are fundamental means of specifying computations in programming languages
• Understanding how expressions are evaluated requires knowing the order in which operator and operand are evaluated
• Essence of imperative languages is the dominant role of assignment statements, including expressions
3Arithmetic Expressions
• Evaluation of numeric expressions – Motivation for the development of PLs
• Remember trajectory tables?
• Arithmetic expressions consist of– Operators– Operands– Parentheses/delimiters– Function calls
4Design Issues for Arithmetic Expressions
1. What are the operator precedence rules?2. What are the operator associativity rules?3. What is the order of operand evaluation?4. Are there restrictions on operand evaluation side
effects?5. Is user-defined operator overloading supported?6. What mode mixing in expressions is allowed?
5Arity of Arithmetic Expressions
• Arity– Number of operands/arguments of a function
• A unary operator has one operand
• A binary operator has two operands– Most common operators
• A ternary operator has three operands
• Some languages support N-ary operators– In Lisp, a benefit of prefix representation(* pi r r) vs. pi*r*r or pi*r^2
6Operator Precedence Rules
• Precedence define the order in which adjacent operators are evaluated– Adjacent - separated by at most one operand
• Different PLs have different precedence levels
• Typical precedence levels – highest to lowest1. Parentheses2. Unary operators3.** (exponentiation, if the language supports it)4.*, /, % (modulo)5.+, -
7Operator Associativity Rules
• Define the order in which adjacent operators with the same precedence level are evaluated
• Typical associativity rules– Left to right, except ** which is right to left– Unary operators may associate right to left (e.g., FORTRAN)
• APL is different– All operators have equal precedence and– All operators associate right to left!
• Parentheses override precedence and associativity rule
8Expression Evaluation Process
• Order of evaluation is crucial
1. Variables– fetch value from memory
2. Constants– either implicit in instruction – or fetch from memory
3. Parenthesized expressions– evaluate all operands and operators first
4. Function references– the most interesting
9Functions/Procedures
Result/Return value
Input/Output Side Effects
Function/Procedure
Arguments/Parameters
• Parameters – pass by value (in) or by reference (in/out)• Return value• Input/Output• Side Effects
10Side Effects
• Side effect– a function or procedure changes a two-way parameter
or a non-local variable
• A major problem with side effects:– When a function referenced in an expression alters another
operand of the expression; e.g., for a parameter change:a = 10;b = a + fun(&a); /*Assume fun changes its parameter*/
• Results of the expression depend on the order of evaluation of statements!!– why is this bad?
11Solution 1: Prohibit Side Effects!
1. Language definition prohibits side effects– No two-way parameters– No non-local references
• Advantage– It works!– E.g. functional languages
• Disadvantages:– Need flexibility of two-way parameters and non-local variables
• What about C? What about Java?– Copying of parameters to avoid side effects
12Solution 2: Fix Evaluation Order
2. Operand evaluation order is fixed in language definition
• Advantage– We always know how expression will be evaluated
• Disadvantage– This limits some compiler optimizations
13Conditional Expressions
• Ternary operator <cond> ? <expr1> : <expr2> – Same as if (<cond> ) <expr1> else <expr2>– C, C++, and Java <condition> average
(count == 0) ? 0 : sum / count– Lisp:
(if <test> <do-if-true> <do-ifnot>)
• Short-circuit evaluation means1. Evaluate test first and then2. Evaluate only the branch taken
• e.g. avoid division by zero above
14Overloading Operators
• Operator overloading– use of an operator for more than one purpose
• Some are common (e.g., + for int and float)
• Some are potential trouble• e.g., * in C and C++, / for int and float in Java
– Loss of compiler error detection• Missing operand should be a detectable error
– Some loss of readability– Can be avoided by introduction of new symbols
e.g., Pascal’s div
15User-defined Overloaded Operators
• C++ and Ada allow user-defined overloaded operators
• Problems– Users can define nonsense operations– Readability may suffer, even when the operators make sense
16Type Conversions
• Narrowing conversion – converts to a “smaller” type (type has fewer values)
• e.g., float to int • 3.99 to 4
• Widening conversion – converts to a type that includes all values of the
original type– or at least an approximation of each
• e.g., int to float• 4 to 4.0f
17Type Conversions
• Mixed-mode expression – Operands of different types
• Coercion – An implicit type conversion
• Disadvantage– Decreases the type error detection ability of the compiler
• In most languages, widening conversions of numeric types in expressions can be coerced
• In Ada, there are virtually no coercions in expressions
18Explicit Type Conversions
• In C, C++, Ada, Java called casts
• E.g., Ada:FLOAT (INDEX) --INDEX is INTEGER type– converts to floating point