cse 3341 principles of programming languages core
play

CSE 3341: Principles of Programming Languages Core Concepts I - PowerPoint PPT Presentation

CSE 3341: Principles of Programming Languages Core Concepts I Jeremy Morris 1 Imperative Language Basics The model of most imperative languages is straightforward: Programs are a sequence of expressions or statements Expressions


  1. CSE 3341: Principles of Programming Languages Core Concepts I Jeremy Morris 1

  2. Imperative Language Basics  The model of most imperative languages is straightforward:  Programs are a sequence of expressions or statements  Expressions read values from memory and produce a new value Some expressions may have side effects that change values in  memory  Statements read values from memory and do not produce new values All statements operate by side effect  Assignment statements – most basic example   Core idea: Expressions are evaluated, Statements are executed 2

  3. Imperative Language Basics  Early languages sought to break away from being machine dependent  Assembly languages are machine dependent  These language designers sought a higher level of abstraction  Separation of function from the details of machine implementation Or separation of function from implementation details period  (Sound familiar – it should. Think client vs. implementer)   Key to this idea are names Strings of symbols used to refer to "things" in a programming  language Variables, procedures, constants, etc.  3

  4. Binding and Binding Time  Binding is an association between two things  Typically we are using it in reference to binding a name to a target (or object in the textbook's terminology)  Binding time is when a binding occurs  A few important ones: Compile time  Compiler chooses how to bind high-level constructs to machine code  Link time  When code in libraries are joined together by a linker  Load time  When the OS loads a program into memory  Run time  The entire span of execution of a program from beginning to end   Static vs. Dynamic Static before run time, dynamic during runtime  4

  5. Object lifetime  Lifetime of an object  The period of time between when an object is created and when it is destroyed  Lifetime of a binding  The period of time between when a binding between a name and an object is created and when it is destroyed  Object lifetimes generally fall into one of three types based on how they are allocated  Static objects  Stack objects  Heap objects 5

  6. Static Allocation An absolute memory location retained through the program's  execution Typically global variables  Also (in some languages) variables that are local to a subroutine but  retain value from one invocation to the next Numeric and string-valued constant literals  The lifetime of a statically allocated variable is the entire program  Local variables are not typically statically allocated in modern  languages If a language doesn't have recursion, local variables can be statically  allocated Fortran as originally designed, for example  Recursion means we need to do something else  Stack allocation can help us solve this problem  6

  7. Static local variable in C void adder() { static int x = 0; x++; printf("%d\n", x); } int main(int argc, char *argv[]) { adder(); // prints 1 adder(); // prints 2 adder(); // prints 3 return 0; } 7 Example courtesy Wikipedia: https://en.wikipedia.org/wiki/Static_variable

  8. Stack Allocation Image courtesy Programming Language Pragmatics p. 118 8

  9. Heap Allocation  The heap is free memory allocated to the program by the OS  The programmer can allocate it however they want  Uses keywords like new (Java/C++) or malloc (C) to allocate memory from the heap for the program  Uses keywords like delete (C++) or free (C) to free it up  Data in the heap is accessed via references (or pointers)  Addresses in the heap to where data is stored  new and malloc both return a reference (pointer) to the memory they allocate  The lifetime of a heap allocated object is controlled by the programmer May be as long or as short as the programmer needs  9

  10. C program running in memory 10 Example courtesy Wikipedia: https://en.wikipedia.org/wiki/Data_segment

  11. Scope  The region in the code where a binding is active is its scope  Scope can be determined statically or dynamically Almost all modern languages have static scoping  Dynamic scoping comes with a run-time cost   Static scoping is also known as lexical scoping  Because we can determine it from the code at compile time Just by reading the source, we can understand the scope of every  variable  Dynamic scoping can only be determined at run-time 11

  12. Static/Lexical Scope  Probably what you think of when you think of scope  Java, C, C++, Python, Pascal …  Most modern languages use lexical scope  Typically the current binding between a name and a target is based on the "block" of code that the name appears in  Scope can often be nested – variables in outer blocks can be accessed from within inner blocks (but not vice-versa) 12

  13. Static/Lexical Scope – Java Example public class Sample { private static int avg = 33; private static int average( int[] list) { int x = avg; int avg = 0; for ( int i=0; i<list.length; i++) { int y = list[i]; avg += y; } if (list.length > 0) { avg /= list.length; } return avg; } public static void main(String[] args) { int[] list = { 2, 4, 6, 8, 10 }; int avg = average(list); System.out.println("The average is: " + avg); } } 13

  14. Static/Lexical Scope – C++ Example int avg = 33; double average( int list[], int size) { double x = avg; double avg = 0; for ( int i=0; i<size; i++) { int x = list[i]; avg += x; } if (size > 0) { avg /= size; } return avg; } int main(String[] args) { int list[5] = { 2, 4, 6, 8, 10 }; double avg = average(list); cout << "The average is: " << avg << endl; return 0; } 14

  15. Static/Lexical Scope – Python Example avg = 33 def average(list): avg = 0 for x in list: avg += x if ( len(list) > 0 ): avg /= len(list) return avg def foo(): local = 10 def bar(): local = 5 print ("Local2: "+str(local)) bar() print ("Local1: "+str(local)) print ("The average is: "+str(avg)) list = [2,4,6,8,10] avg = average(list) print ("The average is: "+str(avg)) 15

  16. Static/Lexical Scope – C/C++  In Java, you can refer to methods before you declare them  Scope is the entire block they are declared in  In C/C++, you cannot  Scope is only after they've been declared  This is a problem for recursive types and subroutines How can you refer to something if it isn't in scope?   C/C++ solve this problem by separating declaration from definition  Only declaration has to exist before you can use it  Definition can come after you've used it 16

  17. Static/Lexical Scope – C/C++ bool isEven( int x); bool isOdd( int y); bool isEven(int x) { if (x == 0) { return true; } else { return isOdd(x-1);} } bool isOdd( int x) { if (x == 0) { return false; } else { return isEven(x-1);} } 17

  18. Dynamic scope  Bindings between names and targets can only be determined at run-time  Depending on the flow of control of the program, bindings may be different  You can't tell from reading the code exactly what the scope of a variable is It will depend on what was previously executed before the code  reached that point  If you are used to static scoping, this idea may seem very odd 18

  19. Dynamic scope example int n void first(): n = 1 void second(): int n first() main(): n = 2 int x = readInteger() if (x > 0) then second() else first() println (n) 19 Example courtesy Michael Scott – Programming Language Pragmatics

  20. Scope implementation  Scope rules in a compiler are implemented using the symbol table  If everything is global, it's just a mapping of symbols to internal keys Think about the recursive descent algorithm discussed in class   Scope rules require some extra complexity Augment the symbol table with "enter scope" and "leave scope"  operations to keep track of visibility Nothing is ever deleted from a symbol table – even when it falls out  of scope It's just marked "out of scope"  Retained through entire compilation   Scope rules in an interpreter are treated in a similar fashion Interpreter also has to keep track of the targets tied to each binding  20

  21. Expression Evaluation  An expression is a line of code that is evaluated and produces a result  Expressions can be combinations of operands and operators An operator in a language is a built-in function that uses special  syntax An operand is one of the arguments to the operator function  3 + 2, x + y, x++, --j, etc.   Expressions can also be function calls Typically the name in parentheses with arguments in parentheses  myFunction(x,y)   In some languages, operands are just syntactic sugar for function calls Ada – "+"(a,b)  C++ - a.operator+(b)  Scala – a.+(b)  21

  22. Expression Values & Assignment  Variables are a binding between a memory location and a value  Semantics of how we read the variable differ  Sometimes the variable designates a value x * 3  multiply the value stored in x by 3   But sometimes it designates a memory location x = 3  store the value three in the memory location denoted by x   Value model of variables  "l-value" denotes a memory location  "r-value" denotes a value  But … pointers/references can make this tricky 22

Recommend


More recommend