400 likes | 550 Views
Structure of Programming Language. Subroutines. Procedures and Functions. There are two categories of subprograms Function : subroutine that returns a value Procedure : subroutine that does not return a value. Basic Definitions.
E N D
Structure of Programming Language Subroutines
Procedures and Functions There are two categories of subprograms • Function: subroutine that returns a value • Procedure: subroutine that does not return a value
Basic Definitions • A subprogram call is an explicit request that the subprogram be executed • A subprogram header is the first part of the definition, including the name, the kind of subprogram, and the formal parameters • The parameter profile of a subprogram is the number, order, and types of its parameters
Basic Definitions (continued) • Function declarations in C and C++ are often called prototypes • A subprogram declaration provides the protocol, but not the body, of the subprogram • A formal parameter is the variable listed in the subprogram header and used in the subprogram • An actual parameter represents a value or address used in the subprogram call statement
Stack Layout • Storage consumed by parameters and local variables can be allocated on a stack • Activation record contains arguments and/or return values, bookkeeping info, local variables, and/or temporaries • On return, stack frame is popped from stack
Stack Layout (cont’d) Static chain - Each stack frame contains a reference to the lexically surrounding subroutine
Calling Sequences • Tasks on the way in (prologue) • Passing parameters, saving return address, changing program counter, changing stack pointer, saving registers, changing frame pointer • Tasks on the way out (epilogue) • Passing return parameters, executing finalization code, deal locating stack frame, restoring saved registers and pc
Parameter Passing Methods • Ways in which parameters are transmitted to and/or from called subprograms • Pass-by-value • Pass-by-result • Pass-by-value-result • Pass-by-reference • Pass-by-name
Call by Value • Provides with a copy of variable’s value • Actual parameter is assigned to the corresponding formal parameter when subroutine is called, and the two are independent from then on • Like creating a local or temporary variable • When copies are used, additional storage is required
Pass-by-Result (Out Mode) • When a parameter is passed by result, no value is transmitted to the subprogram; the corresponding formal parameter acts as a local variable; its value is transmitted to caller’s actual parameter when control is returned to the caller • Require extra storage location and copy operation • Potential problem: sub(p1, p1); whichever formal parameter is copied back will represent the current value of p1
Pass-by-Value-Result (inout Mode) • A combination of pass-by-value and pass-by-result • Sometimes called pass-by-copy • Formal parameters have local storage
Pass-by-Reference (Inout Mode) • Pass an access path. Provide P with the address of X • Also called pass-by-sharing • Passing process is efficient (no copying and no duplicated storage) • Disadvantages • Slower accesses (compared to pass-by-value) to formal parameters
Call by name • Pretty much only in Algol. • By textual substitution • Re-evaluates the actual parameter on every use • For actual parameters that are simple variables, it’s the same as call by reference • For actual parameters that are expressions, the expression is re-evaluated on each access • No other language ever used call by name…
Call by name Invocation: P(A, B+2, 27+3) Definition: procedure P(X,Y,Z) {int I; I=7; X = I + (7/Y)*Z;} Meaning: P(X,Y,Z) {int I; I=7; A=I+(7/(B+2))*(27+3);}
Examples of Call by Name 1. P(x) {x = x + x;} Seems simple enough … Y = 2; P(Y); write(Y) means Y = Y+Y write(Y) prints 4 2. int A[10]; for(I=0; I<10; I++) {A[I]=I;}; I=1; P(A[I]) A[1] = A[1] + A[1] A[1] set to 2
Examples of Call by Name But: F {I = I + 1; return I;} What is: P(A[F])? P(A[F]) A[F] = A[F]+A[F] A[I++] = A[I++]+A[I++] A[2] = A[3]+A[4]
Examples of Call by Name Write a program to exchange values of X and Y: (swap(X,Y)) Usual way: swap(x,y) {t=x; x=y; y=t;} Cannot do it with call by name. Cannot handle both of following: swap(I, A[I]) swap(A[I],I) One of these must fail.
Example of parameter passing Main { A = 2; B = 5; C = 8; D = 9; P(A, B, C, D); write(A, B, C, D); P(U, V, W, X) { V = U+A; W = A+B; A = A+1; X = A+2; write(U, V, W, X) }
Example Program { local i,j local a[1..12] proc P( X , Y ) { local j j = 2 i = i + 1 print X X = X + 2 print Y j--; print Y } a[1]=1; a[2]=2; … ; a[12]=12; i = 1 j = 3 P( i , a[i*j] ) print i print a[9] }
i = 1 j = 3 P( i , a[i*j] ) X , Y j = 2 i = i + 1 print X X = X + 2 print Y j--; print Y print i print a[9] thunk: 0-ary function encapsulating argument text int& X(){return &i} int& Y(){return &a[i*j]} j = 2 // j’==2 j==3 i=i+1 // i == 2 print *X() 2 X()=*X()+2 //i==4 print *Y() //a[i*j]==a[4*3]12 j--; print *Y() 8 ! print i 4 print a[9] 9 Call by name—implemented by thunk
i = 1 j = 3 P( i , a[i*j] ) X , Y j = 2 i = i + 1 print X X = X + 2 print Y j--; print Y print i print a[9] lval(X)==lval(i) lval(Y)==lval(a[1*3]) j = 2 //j’==2 j==3 i=i+1 //i== 2 print i 2 i = i+2 //i==4 print a[1*3] 3 j--; print a[1*3] 3 print i 4 print a[9] 9 Call by reference aliased
i = 1 j = 3 P( i , a[i*j] ) X , Y j = 2 i = i + 1 print X X = X + 2 print Y j--; print Y print i print a[9] X = i //X==1 Y =a[i*j])//Y==a[1*3] j = 2 //j’==2 j==3 i=i+1 //i == 2 print X 1 X = X+2 //i==2 X==3 print Y 3 j--; print Y 3 print i 2 print a[9] 9 Call by value (copy-in)
i = 1 j = 3 P( i , a[i*j] ) X , Y j = 2 i = i + 1 print X X = X + 2 print Y j--; print Y print i print a[9] X =i Y =a[i*j])//Y==a[1*3] j = 2 // j’==2 j==3 i=i+1 // i == 2 print X 1 X = X+2 //i==2 X==3 print Y 3 j--; print Y 3 Use names of actuals for copy-out i = X //i==3 a[i*j] = Y //a[3*3]==3 print i 3 print a[9] 3 Call by value–result (Algol W)
Modes in Programming Languages • Call as constant Algol 68, C/C++ const • Call by reference Pascal var, Fortran, Cobol, PL/I, Ada arrays, C arrays • Call by value Algol 60, Algol 68 (has ref x), Simula, C, C++ (has &x), Pascal, PL/I, APL, LISP, Snobol4, Ada (scalar in variables) • Call by copy Ada (scalar out or in-out) • Call by value-result Algol W • Call by text LISP Macros • Call by name Algol 60, Simula • Call by need, R-value Haskell, Scheme (delay x) &(force x) • Call by need, L-value imperative + lazy eval?
Language dependent • ALGOL - name, value • Fortran • Always used the inout semantics model • Before Fortran 77: pass-by-reference • Fortran 77 and later: scalar variables are often passed by value-result
Parameter Passing Methods • C • Pass-by-value • Pass-by-reference is achieved by using pointers as parameters • C++ • A special pointer type called reference type for pass-by-reference • Java • All parameters are passed by value • Object parameters are passed by reference
Parameter Passing Methods of • Ada • Three semantics modes of parameter transmission: in, out, in out; in is the default mode • Formal parameters declared out can be assigned but not referenced; those declared in can be referenced but not assigned; in out parameters can be referenced and assigned • C# • Default method: pass-by-value • Pass-by-reference is specified by preceding both a formal parameter and its actual parameter with ref • PHP: very similar to C# • Perl: all actual parameters are implicitly placed in a predefined array named @_
Language Specific Variations • Pascal: Call by Value is the default, the keyword VAR denotes Call by Reference • Smalltalk, Lisp: Actual Parameter is already a reference to the object
Type Checking Parameters • FORTRAN 77 and original C: none • Pascal, FORTRAN 90, Java, and Ada: it is always required • ANSI C and C++: choice is made by the user • Prototypes • Relatively new languages Perl, JavaScript, and PHP do not require type checking
Multidimensional Arrays as Parameters • If a multidimensional array is passed to a subprogram and the subprogram is separately compiled, the compiler needs to know the declared size of that array to build the storage mapping function
Multidimensional Arrays as Parameters: C and C++ • Programmer is required to include the declared sizes of all but the first subscript in the actual parameter • Solution: pass a pointer to the array and the sizes of the dimensions as other parameters; the user must include the storage mapping function in terms of the size parameters
Multidimensional Arrays as Parameters: Pascal and Ada • Pascal • Not a problem; declared size is part of the array’s type • Ada • Constrained arrays - like Pascal • Unconstrained arrays - declared size is part of the object declaration
Multidimensional Arrays as Parameters: Java and C# • Similar to Ada • Arrays are objects; they are all single-dimensioned, but the elements can be arrays • Each array inherits a named constant (length in Java, Length in C#) that is set to the length of the array when the array object is created
Function Returns • Some languages restrict Return types • Algol 60, Fortran: scalars only • Pascal, Modula: scalars or pointers only • Most imperative languages are flexible • Return statements specify a value and also cause the immediate termination of the subroutine
Parameters that are Subprogram Names • It is sometimes convenient to pass subprogram names as parameters • Are parameter types checked?
Parameters that are Subprogram Names: Parameter Type Checking • C and C++: functions cannot be passed as parameters but pointers to functions can be passed; parameters can be type checked • FORTRAN 95 type checks • Later versions of Pascal and Ada does not allow subprogram parameters; a similar alternative is provided via Ada’s generic facility
Overloaded Subprograms • Ada, Java, C++, and C# allow users to write multiple versions of subprograms with the same name • Every version of an overloaded subprogram has a unique protocol • C++, Java, C#, and Ada include predefined overloaded subprograms • In Ada, the return type of an overloaded function can be used to disambiguate calls (thus two overloaded functions can have the same parameters)
Lifetime • The lifetime of a variable is that period during program execution when the storage for the declared variable exists in some activation record (i.e., from the time the activation record for the declaring procedure is created until that activation record is destroyed). • The scope of a variable is the portion of the source program where the data item can be accessed (i.e., the name of the item is a legal reference at that point in the program).
Lifetimes of variables • Lifetime of variable X is the period when the activation record for P exists. • Note that we can change the scope, but the not lifetime of a variable by nesting procedures: