Title: Basic Semantics
1Basic Semantics
2Names
- A fundamental abstraction mechanism in a
programming language is the use of names or
identifiers to denote language entities or
constructs - In most languages, constants, variables, and
procedures can have names assigned by the
programmer
3Attributes
- The meaning of a name is determined by the
attributes associated with the name const int n
5 / n is a constant / int x / x is
a variable / double f(int n) / f is a
function /
4Binding
- The process of associating an attribute to a name
is called binding const int n 2 / static
binding / int x / static binding / x
2 / dynamic binding / int y /
static binding / y new int / dynamic
binding /
5Binding Time
- Language definition time int, char, float
- Language implementation time sizeof(int)
- Translation time types of variables
- Link time code body of external functions
- Load time locations of global variables
- Execution time values of variables, locations of
local variables
6Symbol Table
- Bindings can be maintained by a data structure
called the symbol table - For an interpreter, the symbol table is a
function that maps names to attributes Symbol
Table Names Attributes
7Symbol Table
- For a compiler, the symbol table is a function
that maps names to static attributes Symbol
Table Names Static attributes
8Environment Memory
- The dynamic attributes locations and values can
be maintained by two functions environment
(memory allocation) and memory(assignment) En
vironment Names Locations
Memory Locations Values
9Declarations
- Declarations are a principal method for
establishing bindings - Declarations are commonly associated with a
block. These declarations are called local
declarations of that block. - Declarations associated with an enclosing block
are called nonlocal declarations - Declarations can also be external to any block.
These declarations are called global declarations
10An Example
int x / global / main() int i,
n / nonlocal / i 1 n 10 while
(i i f(l)
11Scope
- The scope of a binding is the region of the
program over which the binding is maintained - We can also refer to the scope of a declaration
if all the bindings established by the
declaration have identical scopes - In a block-structured language, the scope of a
binding is limited to the block in which its
associated declaration appears. Such a scope rule
is called static (or lexical) scope
12An Example
13Visibility
- The local binding of a name will take precedence
over the global and nonlocal binding of the name.
This causes a scope hole for the global and
nonlocal binding of the name - The visibility of a binding includes only those
regions of a program where the binding applies
14An Example
int i void p(void) int i void
q(void) int j main() int i
i
i
scope hole
i
i
j
scope hole
i
scope
visibility
15Scope Resolution Operators
- Scope resolution operators can be used to access
the bindings hidden by scope holes
16An Example
/ An example in C / int x class ex
int x void f() int x x
1 / local variable x / exx 2 /
x field of class ex / x 3 /
global variable x / void g()
x 4 / x field of class ex /
17Scope Across Files
- In C, global variable declarations can actually
be accessed across filesFile 1 extern int
x / use x in other files / File 2 int x
/ x can be used by other files / File 2
static int x / x can only be used in this
file /
18The Symbol Table
- A symbol table is like a variable dictionary It
must support insertion, lookup, and deletion of
names with associated attributes - The maintenance of scope information in a
statically scoped language with block structure
requires that declarations be processed in a
fashion like stack
19An Example
int x char y void p(void) double x
int y10 void q(void) int y
main() char x
double local to p
int global
x
char global
y
void function
p
20An Example
int x char y void p(void) double x
int y10 void q(void) int y
main() char x
double local to p1
int global
x
int array local to p2
char global
y
void function
p
21An Example
int x char y void p(void) double x
int y10 void q(void) int y
main() char x
int global
x
char global
y
void function
p
22An Example
int x char y void p(void) double x
int y10 void q(void) int y
main() char x
int global
x
int local to q
char global
y
void function
p
void function
q
23An Example
int x char y void p(void) double x
int y10 void q(void) int y
main() char x
int global
x
char global
y
void function
p
void function
q
24An Example
int x char y void p(void) double x
int y10 void q(void) int y
main() char x
char local to main
int global
x
char global
y
void function
p
void function
q
void function
main
25Dynamic Scope
- Using dynamic scope, the binding of a nonlocal
name is determined according to the calling
ancestors during the execution instead of the
static program text
26An Example
int x 1 char y a void p(void) double
x 2.5 printf(c\n, y) int y10
void q(void) int y 42
printf(d\n, x) p() main() char x
b q() return 0
1 a
27An Example
char b local to main
int 1 global
int x 1 char y a void p(void) double
x 2.5 printf(c\n, y) int y10
void q(void) int y 42
printf(d\n, x) p() main() char x
b q() return 0
x
char a global
y
void function
p
void function
q
void function
main
28An Example
char b local to main
int 1 global
int x 1 char y a void p(void) double
x 2.5 printf(c\n, y) int y10
void q(void) int y 42
printf(d\n, x) p() main() char x
b q() return 0
x
int 42 local to q
char a global
y
void function
p
void function
q
98
void function
main
29An Example
char b local to main
int 1 global
double 2.5 local to p
int x 1 char y a void p(void) double
x 2.5 printf(c\n, y) int y10
void q(void) int y 42
printf(d\n, x) p() main() char x
b q() return 0
x
int 42 local to q
char a global
y
void function
p
void function
q
void function
main
30Issue of Dynamic Scope
- When a nonlocal name is used in an expression or
statement, the declaration that applies to that
name cannot be determined by simply reading the
program - Static typing and dynamic scoping are inherently
incompatible - Languages that use dynamic scope are Lisp, APL,
Snobol, Perl
31Symbol Tables for Structures
struct int a char b double c x
1,'a',2.5 void p(void) struct double
a int b char c y 1.2,2,'b'
printf("d, c, g\n",x.a,x.b,x.c) printf("f,
d, c\n",y.a,y.b,y.c) main() p() return
0
struct global
a
int
x
char
b
c
double
void function
p
a
double
int
b
struct local to p
y
c
char
32Nested Procedures
procedure ex is x integer 1 y character
a procedure p is x float 2.5
begin put(y) new_line A declare
y array (1..10) of integer begin y(1)
2 put(y(1)) new_line put(ex.y)
new_line end A end p
procedure q is y integer 42 begin
put(x) new_line p end q begin B
declare x character b begin q
put(ex.x) new_line end B end ex
33Nested Procedures
ex
procedure
x
integer
x
float
y
block
character
A
procedure
p
y
array of integer
procedure
y
q
integer
procedure
x
B
character
34Overloading
- An operator or function name is overloaded if it
is used to refer to two or more different things
in the same scope 2 3 integer addition 2.1
3.2 floating-point addition 2 3.2 error or
floating-point addition by automatically
converting 2 to 2.0
35Overload Resolution
- Overloading of operators or function names can be
resolved by checking the number of parameters (or
operands) and the data types of the parameters
(or operands)int max(int x, int y) max(2,
3) double max(double x, double y) max(2.1,
3.2)int max(int x, int y, int z) max(1, 3,
2)
36Overloading Automatic Conversion
- Automatic conversions complicate the process of
overload resolution max(2.1, 3) - C error, both conversions are allowed
- Ada error, no conversion is allowed
- Java only int to double is allowed
37Overloading Automatic Conversion
- Since there are no automatic conversions in Ada,
the return type of a function can also be used to
resolve overloadingfunction max(xinteger
yinteger) return intfunction max(xinteger
yinteger) return floata integerb floata
max(2, 3) -- call to max 1b max(2,
3) -- call to max 2
38Operator Overloading
- Ada and C also allow built-in operators to be
extended by overloading - We must accept the syntactic properties of the
operator, i.e., we cannot change their
associativity or precedence
39An Example
typedef struct int i double d
IntDouble bool operator IntDouble y) return x.i IntDouble operator (IntDouble x, IntDouble
y) IntDouble z z.i x.i y.i z.d x.d
y.d return z int main() IntDouble x 1,
2.1, y 5, 3.4 if (x y x y cout return 0
40Name Overloading
- A name can be used to refer to completely
different things class A - A A(A A)
- A for()
- if (A.A(A) A) break
A - return A
-
-
41Environment
- Depending on the language, the environment may be
constructed statically (at load time),
dynamically (at execution time), or a mixture of
the two - FORTRAN uses a complete static environment
- LISP uses a complete dynamic environment
- C, C, Ada, Java use both
42Location Allocation
- Typically, global variables are allocated
statically - Local variables are usually allocated
automatically and dynamically in stack-based
fashion - The lifetime or extent of an allocated location
is the duration of its allocation in the
environment
43An Example
main() A int x char y / ... /
B double x int a / ... / / end B /
C char y int b / ... / D
int x double y / ... / / end D / /
... / / end C / / ... /
/ end A / return 0
44An Example
x y
x y x a
x y y b
x y
x y y b x y
x y y b
x y
45Location Allocation
- Many languages also provide mechanisms to
manually allocate (or deallocate) memory for
variablesC malloc, free library
functionsC new, delete built-in
operatorsJava new built-in operators
46Structure of an Environment
static stack heap
47Static Local Variables
- In C, the allocation of a local variable can be
changed from stack-based to static
48An Example
int p(void) static int p_count 0
/ initialized only once / p_count 1
return p_count main() int i for (i
0 i printf("d\n",p()) return 0
49Variables
- A variable is an object whose stored value can
change during execution - A variable is specified by its attributes, which
include its name, its location, its value, and
others
50Assignments
- The semantics of the assignment x e are that e
is evaluated to a value, which is then copied
into the location of x x y
51R-Value L-Value
- The variable y on the right-hand side of x y
stands for the value of y, while the variable x
on the left-hand side stands for the location of
x - We sometimes call the value stored in the
location of a variable its r-value, while the
location of a variable its l-value
52R-Value L-Value
- ML, Algol68, and BLISS are languages that make
r-values and l-values explicit. In ML, x
!y x !x 1
53Address-of Dereferencing
- In C, the address-of operator explicitly
returns the location of a variable, while the
dereferencing operator explicitly takes the
value of a variable and returns it as a
location int x, y, xptr xptr x xptr
y
54Semantics of Assignments
- The usual semantics of an assignment, which
copies the value of a location to another
location, is called storage semantics - In some languages, like Java and LISP, an
assignment copies the location to another
location. This semantics is called pointer
semantics
55Pointer Semantics
- Pointer semantics are usually implemented using
implicit pointers and implicit dereferencing
Java
y
y
x y
x
x
56Constants
- A constant is a language entity that has a fixed
value for the duration of its existence - A constant can be a literal like 123 or a. Or
it can be a name for a value, called symbolic
constants. Once its value is computed, it cannot
change
57Symbolic Constants
- A symbolic constant is like a variable, except
that it has no location attribute, but a value
only. The location of a symbolic constant cannot
be explicitly referred to
const int a 2 int x x a / Illegal C
code /
58Initialization of Constants
const int a 2 / manifest constant / const
int b 27 2 2 / compile-time constant
/ const int c (int) time(0) / static
constant, illegal / int f(int x) const int
d x 1 / dynamic constant / return b
c
59Function Constants
- Function definitions are definitions of constants
whose values are functions
int gcd(int u, int v) if (v 0) return
u else return gcd(v, u v)
60Function Variables
- C has function variables, which must be defined
as pointers. However, dereferencing is not
required to access the value of function
variables int (fun_var) (int, int) fun_var
gcd main() printf(d\n, fun_var(15,
10)) return 0
61Functions in Functional Languages
- Functional languages do a much better job of
making clear the distinction between function
constants, function variables, and function
literals. In ML, fn(xint) x x (
literal ) val square fn(xint) x x
( constant ) fun square (xint) x x
(fn(xint) x x) 2
62Aliases
- An alias occurs when the same location is bound
to two different names at the same time - An alias can occurs at call-by-reference
parameter passing - An alias can occurs at pointer assignment
- An alias can occurs at assignment with pointer
semantics - An alias can occurs in the EQUIVALENCE
declaration of FORTRAN
63An Example
int x, y x (int ) malloc(sizeof(int)) x
1 y x y 2 printf(d\n, x)
64An Example
x
x
x
1
y
y
y
x
x
1
2
y
y
65An Example
class ArrTest public static void
main(String args) int x 1, 2,
3 int y x x0 42
System.out.println(y0)
66Dangling References
- A dangling reference is a pointer that points to
a location that has been deallocated.
int dangle(void) int x return x
int x, yx (int ) malloc(sizeof(int))x
2y xfree(x)printf(d\n, y)
67Garbage
- Garbage is locations that have been allocated but
that have become inaccessible to the program
int xx (int ) malloc(sizeof(int))x 0
void p(void) int x x (int )
malloc(sizeof(int)) x 2
68Garbage Collection
- It is useful to remove the need to deallocate
memory explicitly from the programmer, while at
the same time automatically reclaiming garbage
for further use. This mechanism is called garbage
collection - Most functional. logic, and object-oriented
languages provide garbage collection