Subprograms The basic abstraction mechanism. Functions correspond to the mathematical notion of computation input output procedures affect the environment,

Slides:



Advertisements
Similar presentations
1) Scope a] Ada scope rules b] C scope rules 2) Parameter passing a] Ada parameter modes b) Parameter passing mechanisms COMP205 IMPERATIVE LANGUAGES 13.
Advertisements

Programming Languages and Paradigms
CSI 3120, Implementing subprograms, page 1 Implementing subprograms The environment in block-structured languages The structure of the activation stack.
Chapter 9 Subprograms Specification: name, signature, actions Signature: number and types of input arguments, number and types of output results –Book.
Subprogram Control - Data sharing Mechanisms to exchange data Arguments - data objects sent to a subprogram to be processed. Obtained through  parameters.
CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha
Subprograms The basic abstraction mechanism. Functions correspond to the mathematical notion of computation input output procedures affect the environment,
(1) ICS 313: Programming Language Theory Chapter 10: Implementing Subprograms.
Chapter 10 Implementing Subprograms. Copyright © 2012 Addison- Wesley. All rights reserved. 1-2 Chapter 10 Topics The General Semantics of Calls and Returns.
CS 326 Programming Languages, Concepts and Implementation Instructor: Mircea Nicolescu Lecture 18.
Chapter 9 Subprogram Control Consider program as a tree- –Each parent calls (transfers control to) child –Parent resumes when child completes –Copy rule.
1 Storage Registers vs. memory Access to registers is much faster than access to memory Goal: store as much data as possible in registers Limitations/considerations:
1 Chapter 7: Runtime Environments. int * larger (int a, int b) { if (a > b) return &a; //wrong else return &b; //wrong } int * larger (int *a, int *b)
ISBN Chapter 10 Implementing Subprograms.
ISBN Chapter 10 Implementing Subprograms.
Runtime Environments Source language issues Storage organization
1 Pertemuan 20 Run-Time Environment Matakuliah: T0174 / Teknik Kompilasi Tahun: 2005 Versi: 1/6.
Run time vs. Compile time
Semantics of Calls and Returns
The environment of the computation Declarations introduce names that denote entities. At execution-time, entities are bound to values or to locations:
Chapter 9: Subprogram Control
1 CSCI 360 Survey Of Programming Languages 9 – Implementing Subprograms Spring, 2008 Doug L Hoffman, PhD.
1 Run time vs. Compile time The compiler must generate code to handle issues that arise at run time Representation of various data types Procedure linkage.
1 Programming Languages Lecture 5 Scheme, Subroutines and Control Abstractions.
Chapter 8 :: Subroutines and Control Abstraction
Chapter 7: Runtime Environment –Run time memory organization. We need to use memory to store: –code –static data (global variables) –dynamic data objects.
ISBN Chapter 10 Implementing Subprograms.
Runtime Environments What is in the memory? Runtime Environment2 Outline Memory organization during program execution Static runtime environments.
5-1 Chapter 5: Names, Bindings, Type Checking, and Scopes Variables The Concept of Binding Type Checking Strong Typing Type Compatibility Scope and Lifetime.
CS 2104 Prog. Lang. Concepts Subprograms
COMPILERS Semantic Analysis hussein suleman uct csc3005h 2006.
Programming Languages and Design Lecture 7 Subroutines and Control Abstraction Instructor: Li Ma Department of Computer Science Texas Southern University,
Runtime Environments Compiler Construction Chapter 7.
Subprograms Support process abstraction and modularity –characteristics of subprograms are that they have a single entry point the calling entity is suspended.
Compiler Construction
Chapter 10 Implementing Subprograms. Copyright © 2012 Addison-Wesley. All rights reserved.1-2 Chapter 10 Topics The General Semantics of Calls and Returns.
Chapter 9 Functions It is better to have 100 functions operate on one data structure than 10 functions on 10 data structures. A. Perlis.
Copyright © 2005 Elsevier Chapter 8 :: Subroutines and Control Abstraction Programming Language Pragmatics Michael L. Scott.
Basic Semantics Associating meaning with language entities.
CSC3315 (Spring 2008)1 CSC 3315 Subprograms Hamid Harroud School of Science and Engineering, Akhawayn University
Programming Languages and Paradigms Imperative Programming.
1 Languages and Compilers (SProg og Oversættere) Bent Thomsen Department of Computer Science Aalborg University With acknowledgement to Angela Guercio.
ISBN Chapter 10 Implementing Subprograms.
Implementing Subprograms What actions must take place when subprograms are called and when they terminate? –calling a subprogram has several associated.
RUN-Time Organization Compiler phase— Before writing a code generator, we must decide how to marshal the resources of the target machine (instructions,
CSC 8505 Compiler Construction Runtime Environments.
1 Structure of Compilers Lexical Analyzer (scanner) Modified Source Program Parser Tokens Semantic Analysis Syntactic Structure Optimizer Code Generator.
RUNTIME ENVIRONMENT AND VARIABLE BINDINGS How to manage local variables.
Chapter 10 Implementing Subprograms. Copyright © 2012 Addison-Wesley. All rights reserved.1-2 Chapter 10 Topics The General Semantics of Calls and Returns.
10-1 Chapter 10: Implementing Subprograms The General Semantics of Calls and Returns Implementing “Simple” Subprograms Implementing Subprograms with Stack-Dynamic.
ISBN Chapter 10 Implementing Subprograms.
Implementing Subprograms
Subprograms - implementation. Calling a subprogram  transferring control to a subprogram: save conditions in calling program pass parameters allocate.
Names, Scope, and Bindings Programming Languages and Paradigms.
Procedure Definitions and Semantics Procedures support control abstraction in programming languages. In most programming languages, a procedure is defined.
1 CSC 533: Programming Languages Spring 2014 Subprogram implementation  subprograms (procedures/functions/subroutines)  subprogram linkage  parameter.
1 Compiler Construction Run-time Environments,. 2 Run-Time Environments (Chapter 7) Continued: Access to No-local Names.
ISBN Chapter 10 Implementing Subprograms.
Implementing Subprograms Chapter 10
Implementing Subprograms
Subprograms The basic abstraction mechanism.
Chapter 10: Implementing Subprograms Sangho Ha
CSC 533: Programming Languages Spring 2015
Implementing Subprograms
PZ09A - Activation records
Activation records Programming Language Design and Implementation (4th Edition) by T. Pratt and M. Zelkowitz Prentice Hall, 2001 Section
Runtime Environments What is in the memory?.
CSC 533: Programming Languages Spring 2018
CSC 533: Programming Languages Spring 2019
Activation records Programming Language Design and Implementation (4th Edition) by T. Pratt and M. Zelkowitz Prentice Hall, 2001 Section
Presentation transcript:

Subprograms The basic abstraction mechanism. Functions correspond to the mathematical notion of computation input output procedures affect the environment, and are called in order to create side effects. pure functional model possible (but awkward) hybrid model most common: functions can have (limited) side effects.

The environment of the computation Declarations introduce names that denote entities. At execution-time, entities are bound to values or to locations: name value (functional) name location value (imperative) Value binding takes place during function invocation Names are bound to locations on scope entry. Locations are bound to values by assignment.

Example from Everyday Life 221b Baker Street is the name of a location. The location can have an inhabitant (value) at a given time. This can change over time (assignment) locations: name location value (imperative)

Parameter passing The rules that describe the binding of arguments to formal parameters, i.e. the meaning of a reference to a formal in the execution of the subprogram. By-value: formal is bound to value of actual by-reference: formal is bound to location of actual by name: formal is bound to expression for actual

Functional Programming All parameter-passing by value no assignment. local declarations of constants only. consequence: functions have no side-effects. referential transparency: two occurrences of the same expression have the same meaning. awkward if need to describe computations with history, e.g. a random number generator, a database.

Parameter passing in Ada Separate the semantic intent from implementation. Parameter modes: –in : read-only in subprogram –out : write in subprogram –in out : read-write in subprogram independent of whether binding by value, by reference, or by copy-return. Functions can have only in parameters history: can assign to global variables.

Syntactic sugar Default values for in-parameters are possible in Ada function Incr (base: integer; delt : integer :=1) return integer; incr (a(j)) equivalent to (incr (a(j), 1); Also available in C++ int f (int first, int second =0, char* handle = 0); Named associations (Ada): incr (delt => 17, base => a(I));

Parameter passing in C C: parameter passing by value, no semantic checks. Assignment to formal is assignment to local copy If argument is pointer, effect is similar to passing designated object by reference void incr (int* x) { (*x) ++; } incr (&counter); /* pointer to counter*/ why would void incr2(int x) {x++;} not be useful? no need to distinguish between functions and procedures: void indicates no return value.

Parameter-passing in C++ Default is by-value (same semantics as C) Explicit reference parameters: void incr (int& y) { y++}; incr (counter); // compiler knows profile of incr, builds reference semantic intent indicated by qualifier: void f (const double& val); // in-parameter by reference: call cannot modify it

Reference in C++ A reference is a constant pointer, allowing two names for the same object (morning star and evening star). Ex: int I = 17; int &r = I; r++; // has side effect on I too. r = 33; // I also gets this value

Parameter-passing in Java By value only. Semantics of assignment differs for primitive types and for classes: –primitive types have value semantics –objects have reference semantics Consequence: methods can modify objects. On primitive types: assignment allowed, affects local copy. On objects: can’t specify read-only. Have to copy.

Block structure procedure outer (x : integer) is y : boolean; procedure inner (z : integer) is x : float := 3.0; -- hides outer.x function innermost (v : integer) return float is begin return x * float (v * outer.x); -- use inner.x and outer.x end innermost; begin x := innermost (z); -- assign to inner.x end inner; begin inner (x); -- outer.x, the other one is out of scope end;

Parameter passing anomalies var global : integer := 10; another : integer := 2; procedure confuse ( var first, second : integer); begin first := first + global; second := first * global; end; begin confuse (global, another); first and global will be aliased to same location in call by reference; end passing by value with copy-return is less error-prone

Comparison: by value, by reference, by copy-return by value – changes to formal never change the actual (copy-on-entry) by reference – changes to formal immediately change the actual because formal and actual are “aliased” (I.e. point to the same location) By copy-return – like by value except formal is copied to actual upon return.

Call to confuse(global, another) when using by reference var global : integer := 10; another : integer := 2; procedure confuse ( var first, second : integer); begin first := first + global; -- first gets 20 and so does global second := first * global; -- second gets 20*20 and so does another end; begin confuse (global, another); first and global will be aliased to same location in call by reference; end

Call to confuse(global, another) when using copy-return var global : integer := 10; another : integer := 2; procedure confuse ( var first, second : integer); begin first := first + global; -- first gets 20 but global doesn’t change second := first * global; -- second gets 20*10 but another doesn’t change -- only upon exit does first get copied into global (20) -- and second into another (200) end; begin confuse (global, another); end

Case Study: Ada Elementary types in Ada that are in-out have copy-return semantics. Tagged types are by reference in Ada.

Storage outside of the block With block structure, the lifetime of an entity coincides with the invocation of the enclosing construct. If the same entity is to be used for several invocations, it must be global to the construct Simplest: declare in the outermost context. Three storage classes: – static –stack-based (automatic) –heap-allocated

Bounded Nesting C: no nested functions. Blocks are merged with activation record of enclosing function. Static storage available. Ada: arbitrary nesting of packages and subprograms. Packages provide static storage. early C++, Java: 3 levels: static objects, class members, entities local to a member. current C++, Java: nested classes provide arbitrary nesting

Run-time organization Each subprogram invocation creates an activation record. Recursion imposes stack allocation (all languages today) Activation record hold actuals, linkage information, saved registers, local entities. caller: place actuals on stack, return address, linkage information, then transfer control to callee. Prologue: save registers, allocate space for locals Epilogue: place return value in register or stack position, update actuals, restore registers, then transfer control to caller. Binding of locations: actuals and locals are at fixed offsets from frame pointers complications: variable no. of actuals, dynamic objects.

Activation record layout actual Return addr Save area Frame pointer Stack pointer local Handled by callee Handled by caller

Functions with variable number of parameters printf (“this is %d a format %d string”, x, y); within body of printf, need to locate as many actuals as place- holders in the format string. Solution: place parameters on stack in reverse order. Actuals at positive offset from FP, locals at negative offset from FP. actual n actual n-1 … actual 1 (format string) return address

Objects of dynamic size declare x : string (1..N); -- N global, non-constant y : string (1..N); begin... where is the start of y in the activation record? Solution 1: use indirection: activation record hold pointers. Simpler implementation, costly dynamic allocation., deallocation. solution 2: local indirection: activation record holds offset into stack. Faster allocation/deallocation, complex implementation.

Run-time access to globals procedure outer is -- recursive global : integer; procedure inner is -- recursive local : integer; begin... if global = local then -- how do we locate global? Need run-time structure to locate activation record of statically enclosing scopes. Environment includes current activation record AND activation records of parent scopes.

Global linkage Static chain: pointer to activation record of statically enclosing scope display: array of pointers to activation records does not work for function values –functional languages allocate activation records on heap may not work for pointers to functions –simpler if there is no nesting (C, C++, Java) –can check static legality in many cases (Ada)

Static Links Activation record hold pointer to activation record of enclosing scope. Setup as part of call prologue. outer inner To enclosing scope To retrieve entity 3 frames out: 3 dereference operations

Display Global array of pointers to current activation records outer inner display outermost... To retrieve entity 3 frames out: one indexing operation

Subprogram parameters type proc is access procedure (X : Integer); procedure Perform (Helper : proc) is begin … proc (42); end; procedure Action (X : Integer) is … procedure Proxy is begin Perform (Action’Access); end; Proxy can see (and call) Action, therefore environment of Action ( e.g static link) Is known to Proxy. Proxy transmits to Perform both a pointer to the code for Action, and the proper static link for it. -- ‘Access creates pair (ptr to Action, environment of Action) simplest implementation if Env is pointer (static link) but can also be display: more efficient to retrieve non-local entities, less efficient for subprogram parameters, because array of variable size.

Subprogram parameters in C/C++ void (*pf) (string); // pf is a pointer to a void function that takes a string // argument typedef void (*PROC)(int); // type abbreviation clarifies syntax void use_it (PROC); PROC ptr = &do_it; use_it (ptr); use_it (&do_it);

Dispatching in Java No notion of pointer, so no immediate translation Dynamic dispatching on a virtual method is indirect call, so can be obtained using interfaces, classes, and extensions Still in progress.

The limits of stack allocation type ptr is access function (x : integer) return integer; function make_incr (x : integer) return ptr is function new_incr (base : integer) return integer is begin return base + x; -- reference to formal of make_incr end; begin return new_incr’access; -- will it work? end; add_five: ptr := make_incr (5); total : integer := add_five (10); -- where does add_five find x ?

Functions as first-class values forces heap allocation of activation record The environment of definition of the function must be preserved until the point of call: activation record cannot be reclaimed if it creates functions. Functional languages require more complex run-time management. Higher-order functions: functions that return (build) functions, are powerful but complex mechanisms. Imperative languages restrict their use. A function that returns a pointer to a function is a higher-order function.

Canonical Use of Higher Order Functions: map Suppose you have defined a function double(x) return 2*x Now you have a list of elements and you’d like to execute double on every element of the list. This would take the list (2 4 3) and return (4 8 6). In some languages you can say something like map (double, list). You could do this in other ways, but map is very generally useful.

Higher-order functions and Scoping Both arguments and result can be (pointers to) subprograms: type Func is access function (x : integer) return integer; function compose (first, second : Func) return Func is begin function result (x : integer) return integer is begin return (second (first (x)); -- implicit dereference on call end; -- in C++ as well. begin return result ’access; -- but first and second won’t exist at the point end; -- of call, so illegal in Ada.

Restricting higher-order functions C: no nested definitions, so environment is always global. C++: ditto, except for nested classes. Ada: static checks to reject possible dangling references Modula: pointers to function illegal if function not declared at top-level. LISP: special syntax to indicate capture of environment ML, Haskell: no restriction: compose is a primitive

Returning composite values Intermediate problem: functions that return values of non-static sizes: function conc3 (x, y, z : string) return string is begin return x & “:” & y & “:” & z; end; example : string := conc3 (this, that, theother); best not to use heap, but still need indirection. Simplest : forbid it (Pascal, C) or use heap automatically (Java)