Basic Semantics.

Slides:



Advertisements
Similar presentations
Chapter 3:: Names, Scopes, and Bindings
Advertisements

Semantic Analysis Chapter 6. Two Flavors  Static (done during compile time) –C –Ada  Dynamic (done during run time) –LISP –Smalltalk  Optimization.
Programming Languages and Paradigms
Names and Bindings.
Chapter 5 Names, Bindings, and Scopes
Various languages….  Could affect performance  Could affect reliability  Could affect language choice.
Chapter 5: Elementary Data Types Properties of types and objects –Data objects, variables and constants –Data types –Declarations –Type checking –Assignment.
Variables Names Bindings Type Scope. L-Value versus R-Value Not complicated Associated with assignment statements Left hand side represents an address.
Chapter 5 Basic Semantics
Programming Languages Third Edition
CS 330 Programming Languages 10 / 16 / 2008 Instructor: Michael Eckmann.
Names, Bindings, Type Checking, and Scopes
C++ Pointer and Functions
Chapter 5K. Louden, Programming Languages1 Chapter 5 Basic Semantics.
1 Names, Scopes and Bindings. 2 Names Kinds of names Kinds of names Variables, functions, classes, types, labels, blocks, operators, tasks, etc. Variables,
UNIVERSITY OF SOUTH CAROLINA Department of Computer Science and Engineering CSCE 330 Programming Language Structures Chapter 4: Names Fall 2009 Marco Valtorta.
The Concept of Variables
CS 330 Programming Languages 10 / 24 / 2006 Instructor: Michael Eckmann.
Chapter 9: Subprogram Control
CSC321: Programming Languages Names Chapter 4: Names 4.1 Syntactic Issues 4.2 Variables 4.3 Scope 4.4 Symbol Table 4.5 Resolving References 4.6 Dynamic.
1 Pointers, Dynamic Data, and Reference Types Review on Pointers Reference Variables Dynamic Memory Allocation –The new operator –The delete operator –Dynamic.
Copyright © 2006 The McGraw-Hill Companies, Inc. Programming Languages 2nd edition Tucker and Noonan Chapter 4 Names The first step toward wisdom is calling.
Names, Bindings, and Scopes
Review of C++ Programming Part II Sheng-Fang Huang.
Names, Bindings, and Scopes
Chapter 5 - Basic Semantics
1 Chapter 5: Names, Bindings and Scopes Lionel Williams Jr. and Victoria Yan CSci 210, Advanced Software Paradigms September 26, 2010.
Names and Binding In procedural programming, you write instructions the manipulate the “state” of the process where the “state” is the collection of variables.
CSC3315 (Spring 2009)1 CSC 3315 Programming Languages Hamid Harroud School of Science and Engineering, Akhawayn University
5-1 Chapter 5: Names, Bindings, Type Checking, and Scopes Variables The Concept of Binding Type Checking Strong Typing Type Compatibility Scope and Lifetime.
Semantics CSE 340 – Principles of Programming Languages Fall 2015 Adam Doupé Arizona State University
March 12, ICE 1341 – Programming Languages (Lecture #6) In-Young Ko Programming Languages (ICE 1341) Lecture #6 Programming Languages (ICE 1341)
Compiler Construction
1 Names, Scopes and Bindings Aaron Bloomfield CS 415 Fall
Names. 2 Variables  binding is an association between an entity (such as a variable) and a property (such as its value). A binding is static if the association.
Chapter 5 Names, Bindings, and Scopes. Copyright © 2012 Addison-Wesley. All rights reserved.1-2 Chapter 5 Topics Introduction Names Variables The Concept.
Basic Semantics Attributes, Bindings, and Semantic Functions
Defining and Converting Data Copyright Kip Irvine, 2003 Last Update: 11/4/2003.
Introduction A variable can be characterized by a collection of properties, or attributes, the most important of which is type, a fundamental concept in.
1 Compiler Construction (CS-636) Muhammad Bilal Bashir UIIT, Rawalpindi.
Basic Semantics Associating meaning with language entities.
1 Scope Scope describes the region where an identifier is known, and semantic rules for this.
ISBN Chapter 5 Names, Bindings, and Scopes.
Programming Languages and Paradigms Imperative Programming.
Run-Time Storage Organization Compiler Design Lecture (03/23/98) Computer Science Rensselaer Polytechnic.
Semantics CSE 340 – Principles of Programming Languages Fall 2015 Adam Doupé Arizona State University
Names, Bindings, and Scope Session 3 Course : T Programming Language Concept Year : February 2011.
Concepts of programming languages Chapter 5 Names, Bindings, and Scopes Lec. 12 Lecturer: Dr. Emad Nabil 1-1.
1 Structure of Compilers Lexical Analyzer (scanner) Modified Source Program Parser Tokens Semantic Analysis Syntactic Structure Optimizer Code Generator.
Names, Scope, and Bindings Programming Languages and Paradigms.
UNIVERSITY OF SOUTH CAROLINA Department of Computer Science and Engineering CSCE 330 Programming Language Structures Operational Semantics (Slides mainly.
1 Compiler Construction Run-time Environments,. 2 Run-Time Environments (Chapter 7) Continued: Access to No-local Names.
CHAPTER 4 VARIABLES & BINDING SUNG-DONG KIM DEPT. OF COMPUTER ENGINEERING, HANSUNG UNIVERSITY.
Semantic Analysis Chapter 6. Two Flavors  Static (done during compile time) –C –Ada  Dynamic (done during run time) –LISP –Smalltalk  Optimization.
Run-Time Environments Presented By: Seema Gupta 09MCA102.
Advanced Programming in C
Data Types In Text: Chapter 6.
Names and Attributes Names are a key programming language feature
Type Checking, and Scopes
CSE 3302 Programming Languages
Names, Bindings, and Scopes
Names.
Semantics CSE 340 – Principles of Programming Languages Spring 2016
CSE 3302 Programming Languages
CSE 3302 Programming Languages
Lecture 15 (Notes by P. N. Hilfinger and R. Bodik)
Semantic Analysis Chapter 6.
Names and Binding In Text: Chapter 5.
CSE 3302 Programming Languages
Lecture 6: Names (Revised based on the Tucker’s slides) 5/27/2019
Presentation transcript:

Basic Semantics

Content Names, attributes, and bindings Declarations, scope and the symbol table Overloading Allocation, lifetimes, and the environment Variables and constants Aliases, dangling references, and garbage

Names 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

Attributes 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 */

Binding 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 */

Binding 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

Symbol 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

Symbol Table For a compiler, the symbol table is a function that maps names to static attributes Symbol Table Names Static attributes

Introduction to Programming Languages Environment & Memory The dynamic attributes locations and values can be maintained by two functions environment (memory allocation) and memory (assignment) environment Names Locations memory Locations Values Basic Semantics

Declarations 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

An Example int x; /* global */ main() { int i, n; /* nonlocal */ while (i < n) { int m; /* local */ m = i++; f(m); }

Scope 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

An Example int x; void p(void) { int i; … } void q(void) int j; … i main() int k; … i j k main q p x

Visibility 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

An Example int i; void p(void) { int i; … } void q(void) int j; … main() int i; … i i scope hole i i j i scope hole scope visibility

Scope Resolution Operators Scope resolution operators can be used to access the bindings hidden by scope holes

An Example /* An example in C++ */ int x; class ex { int x; void f() { x = 1; /* local variable x */ ex::x = 2; /* x field of class ex */ ::x = 3; /* global variable x */ } void g() { x = 4; /* x field of class ex */ };

Scope Across Files In C, global variable declarations can actually be accessed across files File 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 */

The Symbol Table A symbol table is like a dictionary for names: 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

An Example int x; char y; void p(void) { double x; … { int y[10]; …} } void q(void) { int y; … } main() { char x; … } int global x

An Example int x; char y; void p(void) { double x; … { int y[10]; …} } void q(void) { int y; … } main() { char x; … } int global x char global y

An Example int x; char y; void p(void) { double x; … { int y[10]; …} } void q(void) { int y; … } main() { char x; … } int global x char global y void function p

An Example int x; char y; void p(void) { double x; … { int y[10]; …} } void q(void) { int y; … } main() { char x; … } double local to p int global x char global y void function p

An Example int x; char y; void p(void) { double x; … { int y[10]; …} } 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

An Example int x; char y; void p(void) { double x; … { int y[10]; …} } void q(void) { int y; … } main() { char x; … } int global x char global y void function p

An Example int x; char y; x void p(void) { double x; … { int y[10]; …} void q(void) { int y; … } main() { char x; … } int global x char global y void function p void function q

An Example int x; char y; x void p(void) { double x; … { int y[10]; …} void q(void) { int y; … } main() { char x; … } int global x int local to q char global y void function p void function q

An Example int x; char y; x void p(void) { double x; … { int y[10]; …} void q(void) { int y; … } main() { char x; … } int global x char global y void function p void function q

An Example int x; char y; x void p(void) { double x; … { int y[10]; …} void q(void) { int y; … } main() { char x; … } int global x char global y void function p void function q void function main

An Example int x; char y; x void p(void) { double x; … { int y[10]; …} 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

An Example int x; char y; x void p(void) { double x; … { int y[10]; …} void q(void) { int y; … } main() { char x; … } int global x char global y void function p void function q void function main

Symbol Tables for Structures 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

Nested 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; 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; B: declare x: character := ‘b’; q; put(ex.x); new_line; end B; end ex;

Nested Procedures ex procedure x integer x float y character block A p array of integer q procedure y integer B block x character

Dynamic 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

An Example: Static Scope int x = 1; char y = ‘a’; void p(void) { double x = 2.5; printf(“%c\n”, y); { int y[10]; …} } void q(void) { int y = 42; printf(“%d\n”, x); p(); } main() { char x = ‘b’; q(); return 0; } a 1

An Example: Dynamic Scope int = 1 global int x = 1; char y = ‘a’; void p(void) { double x = 2.5; printf(“%c\n”, y); { int y[10]; …} } 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

An Example int x = 1; x char y = ‘a’; void p(void) { double x = 2.5; char = ‘b’ in main int = 1 global int x = 1; char y = ‘a’; void p(void) { double x = 2.5; printf(“%c\n”, y); { int y[10]; …} } 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

An Example int x = 1; x char y = ‘a’; void p(void) { double x = 2.5; char = ‘b’ in main int = 1 global int x = 1; char y = ‘a’; void p(void) { double x = 2.5; printf(“%c\n”, y); { int y[10]; …} } void q(void) { int y = 42; printf(“%d\n”, x); p(); } main() { char x = ‘b’; q(); return 0; } x int = 42 in q char = ‘a’ global y void function p void function q 98 void function main

An Example * int x = 1; x char y = ‘a’; void p(void) { double x = 2.5; in p char = ‘b’ in main int = 1 global int x = 1; char y = ‘a’; void p(void) { double x = 2.5; printf(“%c\n”, y); { int y[10]; …} } void q(void) { int y = 42; printf(“%d\n”, x); p(); } main() { char x = ‘b’; q(); return 0; } x int = 42 in q char = ‘a’ global y * void function p void function q void function main

Issue 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

Overloading 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

Overload 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);

Overloading & 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

Overloading & Automatic Conversion Since there are no automatic conversions in Ada, the return type of a function can also be used to resolve overloading function max(x:integer; y:integer) return int function max(x:integer; y:integer) return float a: integer; b: float; a := max(2, 3); -- call to max #1 b := max(2, 3); -- call to max #2

Operator 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

An Example typedef struct { int i; double d; } IntDouble; bool operator < (IntDouble x, IntDouble y) { return x.i < y.i && x.d < y.d; } 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 = x + y; else y = x + y; cout << x.i << " " << x.d << endl; return 0;

Name 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; }

Environment 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

Location 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

An 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; }

An Example x y x y a x y x y b x y b x y b x y enter A enter B exit B C enter D exit D exit C

Manually Location Allocation Many languages also provide mechanisms to manually allocate (or deallocate) memory for variables C: malloc, free library functions C++: new, delete built-in operators Java: new built-in operators

Structure of an Environment static stack heap

Static Local Variables In C, the allocation of a local variable can be changed from stack-based to static

An 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 < 10; i++) if (p() % 3) printf("%d\n",p()); return 0;

Variables 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 Name Value Location Other Attributes

Assignments 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 y x

R-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

R-Value & L-Value ML, Algol68, and BLISS are languages that make r-values and l-values explicit. In ML, val x = ref 0; val y = ref 1; x := !y; x := !x + 1; z : int -- not assignable (like a constant) x : int ref -- assignable reference cell

Address-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;

Semantics 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

Pointer Semantics Pointer semantics are usually implemented using implicit pointers and implicit dereferencing Java y y x = y x x

An Example class ArrTest { public static void main(String[] args) { int[] x = {1, 2, 3}; int[] y = x; x[0] = 42; System.out.println(y[0]); } /* y[0] = 42 */

Constants 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

Symbolic 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 Name Value Other Attributes const int a = 2; int *x; x = &a; /* Illegal C code */

Initialization of Constants /* compile-time constant */ const int a = 2; /* manifest constant */ const int b = 27 + 2 * 2; const int b = 27 + a * a; /* C illegal, C++ ok */ /* static (or load-time) constant */ const int c = (int) time(0); /* C illegal, C++ ok */ /* dynamic constant */ int f(int x) { const int d = x + 1; return b + c; }

Function 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); }

Function 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; } A little inconsistant

Functions 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(x:int) => x * x (* literal *) (fn(x:int) => x * x) 2; val square = fn(x:int) => x * x; (* constant *) fun square (x:int) = x * x; (* constant *)

Aliases 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

An Example: Call by Reference void incr(int &i) { i++;} void f( ) { int x = 1; incr(x); printf(“%d\n”, x); } /* x = 2 */

An Example: Call by Reference 1 x x 1 i x 2 x 2 i

An Example: Pointer Assignment int *x, *y; x = (int *) malloc(sizeof(int)); *x = 1; y = x; *y = 2; printf(“%d\n”, *x); /* x = 2 */

An Example: Pointer Assignment 1 y y y x 1 x 2 y y

An Example: Pointer Semantics class ArrTest { public static void main(String[] args) { int[] x = {1, 2, 3}; int[] y = x; x[0] = 42; System.out.println(y[0]); } /* y[0] = 42 */

Dangling 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, *y; x = (int *) malloc(sizeof(int)); *x = 2; y = x; free(x); printf(“%d\n”, *y);

Garbage Garbage is locations that have been allocated but that have become inaccessible to the program int *x; x = (int *) malloc(sizeof(int)); x = 0; void p(void) { int *x; x = (int *) malloc(sizeof(int)); *x = 2; }

Garbage 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